summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-12-18 14:54:57 +0000
committerJelmer Vernooij <jelmer@samba.org>2008-12-18 14:54:57 +0000
commitd14c8604653d39dd25736279d34930ee7a3ae103 (patch)
tree626f700b9b42b798ed7459a5cba5cd27aca9753e /source4
parent0c0b9c738f0fc1bf8aa64533a5e4e0635b84f58f (diff)
parentfc31f2c5269fd405be96b9a036baf35a60141ccf (diff)
downloadsamba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.gz
samba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.bz2
samba-d14c8604653d39dd25736279d34930ee7a3ae103.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba into pyregistry
Diffstat (limited to 'source4')
-rw-r--r--source4/Makefile1
-rw-r--r--source4/auth/gensec/gensec.h1
-rw-r--r--source4/auth/kerberos/krb5_init_context.c3
-rw-r--r--source4/auth/session.h3
-rw-r--r--source4/cluster/ctdb/common/ctdb_ltdb.c1
-rw-r--r--source4/cluster/ctdb/common/ctdb_message.c1
-rw-r--r--source4/cluster/ctdb/common/ctdb_util.c1
-rw-r--r--source4/cluster/ctdb/config.mk2
-rw-r--r--source4/cluster/ctdb/ctdb_cluster.c1
-rw-r--r--source4/configure.ac4
-rw-r--r--source4/dsdb/samdb/ldb_modules/anr.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk48
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn.c666
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_in.c394
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_out.c655
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_store.c431
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/linked_attributes.c517
-rw-r--r--source4/dsdb/samdb/ldb_modules/local_password.c9
-rw-r--r--source4/dsdb/samdb/ldb_modules/normalise.c194
-rw-r--r--source4/dsdb/samdb/ldb_modules/partition.c10
-rw-r--r--source4/dsdb/samdb/ldb_modules/proxy.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/ranged_results.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c5
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c21
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/show_deleted.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/simple_ldap_map.c51
-rw-r--r--source4/dsdb/samdb/samdb.h27
-rw-r--r--source4/headermap.txt77
-rw-r--r--source4/ldap_server/ldap_backend.c17
-rw-r--r--source4/lib/events/Makefile.in81
-rwxr-xr-xsource4/lib/events/autogen.sh16
-rw-r--r--source4/lib/events/build_macros.m414
-rw-r--r--source4/lib/events/config.mk57
-rw-r--r--source4/lib/events/configure.ac40
-rw-r--r--source4/lib/events/events.c310
-rw-r--r--source4/lib/events/events.h99
-rw-r--r--source4/lib/events/events.i54
-rw-r--r--source4/lib/events/events.mk59
-rw-r--r--source4/lib/events/events.pc.in11
-rw-r--r--source4/lib/events/events.py94
-rw-r--r--source4/lib/events/events_aio.c567
-rw-r--r--source4/lib/events/events_debug.c83
-rw-r--r--source4/lib/events/events_dummy.c4
-rw-r--r--source4/lib/events/events_epoll.c482
-rw-r--r--source4/lib/events/events_internal.h159
-rw-r--r--source4/lib/events/events_liboop.c288
-rw-r--r--source4/lib/events/events_s4.c108
-rw-r--r--source4/lib/events/events_select.c302
-rw-r--r--source4/lib/events/events_signal.c291
-rw-r--r--source4/lib/events/events_standard.c607
-rw-r--r--source4/lib/events/events_timed.c230
-rw-r--r--source4/lib/events/events_util.c86
-rw-r--r--source4/lib/events/events_util.h117
-rw-r--r--source4/lib/events/events_wrap.c3348
-rw-r--r--source4/lib/events/libevents.m449
-rw-r--r--source4/lib/events/libtalloc.m47
-rw-r--r--source4/lib/events/pkg.m4156
-rw-r--r--source4/lib/events/rules.mk21
-rw-r--r--source4/lib/events/tests.py31
-rw-r--r--source4/lib/events/testsuite.c145
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.c189
-rw-r--r--source4/lib/ldb/common/ldb_attributes.c47
-rw-r--r--source4/lib/ldb/common/ldb_controls.c20
-rw-r--r--source4/lib/ldb/common/ldb_dn.c453
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c6
-rw-r--r--source4/lib/ldb/common/ldb_modules.c6
-rw-r--r--source4/lib/ldb/include/ldb.h91
-rw-r--r--source4/lib/ldb/include/ldb_private.h6
-rw-r--r--source4/lib/ldb/ldb.i2
-rw-r--r--source4/lib/ldb/ldb_ildap/ldb_ildap.c14
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c2
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_outbound.c2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c346
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_search.c2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c10
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h5
-rw-r--r--source4/lib/ldb/modules/asq.c2
-rw-r--r--source4/lib/ldb/modules/operational.c2
-rw-r--r--source4/lib/ldb/modules/paged_results.c2
-rw-r--r--source4/lib/ldb/modules/paged_searches.c2
-rw-r--r--source4/lib/ldb/modules/sort.c2
-rwxr-xr-xsource4/lib/ldb/tests/python/ldap.py87
-rw-r--r--source4/lib/ldb/tools/ldbadd.c4
-rw-r--r--source4/lib/ldb/tools/ldbedit.c4
-rw-r--r--source4/lib/ldb/tools/ldbmodify.c8
-rw-r--r--source4/lib/socket/connect.c63
-rw-r--r--source4/lib/socket/connect_multi.c7
-rw-r--r--source4/lib/socket/socket.h5
-rw-r--r--source4/lib/socket/testsuite.c2
-rw-r--r--source4/lib/stream/packet.h4
-rw-r--r--source4/libcli/composite/composite.h2
-rw-r--r--source4/libcli/config.mk4
-rw-r--r--source4/libcli/ldap/ldap.c26
-rw-r--r--source4/libcli/ldap/ldap_client.c2
-rw-r--r--source4/libcli/ldap/ldap_controls.c115
-rw-r--r--source4/libcli/ldap/ldap_ndr.c1
-rw-r--r--source4/libcli/resolve/bcast.c32
-rw-r--r--source4/libcli/resolve/dns_ex.c532
-rw-r--r--source4/libcli/resolve/host.c209
-rw-r--r--source4/libcli/resolve/nbtlist.c53
-rw-r--r--source4/libcli/resolve/resolve.c45
-rw-r--r--source4/libcli/resolve/resolve.h22
-rw-r--r--source4/libcli/resolve/testsuite.c4
-rw-r--r--source4/libcli/resolve/wins.c33
-rw-r--r--source4/libcli/wrepl/winsrepl.c9
-rw-r--r--source4/librpc/config.mk16
-rw-r--r--source4/librpc/rpc/dcerpc_secondary.c13
-rw-r--r--source4/librpc/rpc/dcerpc_sock.c13
-rw-r--r--source4/main.mk1
-rw-r--r--source4/ntvfs/ntvfs_generic.c2
-rw-r--r--source4/ntvfs/posix/config.mk2
-rw-r--r--source4/ntvfs/sysdep/config.mk2
-rw-r--r--source4/ntvfs/sysdep/sys_lease.c1
-rw-r--r--source4/ntvfs/sysdep/sys_lease.h1
-rw-r--r--source4/rpc_server/config.mk2
-rw-r--r--source4/scripting/python/samba/provision.py27
-rw-r--r--source4/selftest/knownfail1
-rw-r--r--source4/setup/provision_basedn_modify.ldif3
-rw-r--r--source4/setup/schema_samba4.ldif2
-rw-r--r--source4/setup/slapd.conf2
-rw-r--r--source4/smb_server/smb_server.h3
-rw-r--r--source4/smbd/config.mk2
-rw-r--r--source4/smbd/process_model.mk3
-rw-r--r--source4/smbd/service_named_pipe.c1
-rw-r--r--source4/torture/basic/locking.c16
-rw-r--r--source4/torture/config.mk16
-rw-r--r--source4/torture/ldb/ldb.c735
-rw-r--r--source4/torture/local/config.mk2
-rw-r--r--source4/torture/nbt/winsreplication.c12
-rw-r--r--source4/torture/raw/chkpath.c2
-rw-r--r--source4/torture/raw/oplock.c4
-rw-r--r--source4/torture/rpc/netlogon.c21
-rw-r--r--source4/torture/torture.c1
-rw-r--r--source4/wrepl_server/wrepl_out_helpers.c1
136 files changed, 4763 insertions, 9698 deletions
diff --git a/source4/Makefile b/source4/Makefile
index 8899cde2d2..2d49efb93b 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -67,6 +67,7 @@ libtlssrcdir := lib/tls
libregistrysrcdir := lib/registry
smbreadlinesrcdir := lib/smbreadline
libmessagingsrcdir := lib/messaging
+libteventsrcdir := ../lib/tevent
libeventssrcdir := lib/events
libcmdlinesrcdir := lib/cmdline
poptsrcdir := ../lib/popt
diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h
index cb7f3aec99..235d2008fb 100644
--- a/source4/auth/gensec/gensec.h
+++ b/source4/auth/gensec/gensec.h
@@ -65,6 +65,7 @@ enum gensec_role
struct auth_session_info;
struct cli_credentials;
struct gensec_settings;
+struct event_context;
struct gensec_update_request {
struct gensec_security *gensec_security;
diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c
index 06db904130..ac12a498c6 100644
--- a/source4/auth/kerberos/krb5_init_context.c
+++ b/source4/auth/kerberos/krb5_init_context.c
@@ -272,8 +272,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
continue;
}
- status = socket_connect_ev(smb_krb5->sock, NULL, remote_addr, 0,
- NULL, ev);
+ status = socket_connect_ev(smb_krb5->sock, NULL, remote_addr, 0, ev);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(smb_krb5);
continue;
diff --git a/source4/auth/session.h b/source4/auth/session.h
index e0805e1584..fd298b4401 100644
--- a/source4/auth/session.h
+++ b/source4/auth/session.h
@@ -29,7 +29,8 @@ struct auth_session_info {
};
#include "librpc/gen_ndr/netlogon.h"
-#include "lib/events/events.h"
+
+struct event_context;
/* Create a security token for a session SYSTEM (the most
* trusted/prvilaged account), including the local machine account as
diff --git a/source4/cluster/ctdb/common/ctdb_ltdb.c b/source4/cluster/ctdb/common/ctdb_ltdb.c
index e9ee55f6a7..1673368860 100644
--- a/source4/cluster/ctdb/common/ctdb_ltdb.c
+++ b/source4/cluster/ctdb/common/ctdb_ltdb.c
@@ -18,7 +18,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "../tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
diff --git a/source4/cluster/ctdb/common/ctdb_message.c b/source4/cluster/ctdb/common/ctdb_message.c
index 323e90c9e0..54f8e2ac1a 100644
--- a/source4/cluster/ctdb/common/ctdb_message.c
+++ b/source4/cluster/ctdb/common/ctdb_message.c
@@ -21,7 +21,6 @@
protocol design and packet details
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "../tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
diff --git a/source4/cluster/ctdb/common/ctdb_util.c b/source4/cluster/ctdb/common/ctdb_util.c
index 67eb32221a..f6389c449f 100644
--- a/source4/cluster/ctdb/common/ctdb_util.c
+++ b/source4/cluster/ctdb/common/ctdb_util.c
@@ -18,7 +18,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "../tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
diff --git a/source4/cluster/ctdb/config.mk b/source4/cluster/ctdb/config.mk
index 28b18c17ce..d164d710df 100644
--- a/source4/cluster/ctdb/config.mk
+++ b/source4/cluster/ctdb/config.mk
@@ -12,7 +12,7 @@ opendb_ctdb_OBJ_FILES = $(ctdbsrcdir)/opendb_ctdb.o
##################
[SUBSYSTEM::ctdb]
-PUBLIC_DEPENDENCIES = TDB_WRAP LIBTALLOC
+PUBLIC_DEPENDENCIES = TDB_WRAP LIBTALLOC LIBEVENTS
ctdb_OBJ_FILES = $(addprefix $(ctdbsrcdir)/, \
ctdb_cluster.o \
diff --git a/source4/cluster/ctdb/ctdb_cluster.c b/source4/cluster/ctdb/ctdb_cluster.c
index 1c96319986..9b0c9a8aa4 100644
--- a/source4/cluster/ctdb/ctdb_cluster.c
+++ b/source4/cluster/ctdb/ctdb_cluster.c
@@ -20,7 +20,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "cluster/cluster.h"
#include "system/filesys.h"
#include "cluster/cluster_private.h"
diff --git a/source4/configure.ac b/source4/configure.ac
index 53e093e813..7162081bbb 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -34,7 +34,7 @@ m4_include(../nsswitch/nsstest.m4)
m4_include(../pidl/config.m4)
AC_CONFIG_FILES(lib/registry/registry.pc)
-AC_CONFIG_FILES(lib/events/events.pc)
+AC_CONFIG_FILES(../lib/tevent/tevent.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
AC_CONFIG_FILES(../lib/torture/torture.pc)
@@ -96,7 +96,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1,
SMB_INCLUDE_MK(lib/ldb/python.mk)
m4_include(lib/tls/config.m4)
-m4_include(lib/events/libevents.m4)
+m4_include(../lib/tevent/libtevent.m4)
dnl m4_include(auth/kerberos/config.m4)
m4_include(auth/gensec/config.m4)
diff --git a/source4/dsdb/samdb/ldb_modules/anr.c b/source4/dsdb/samdb/ldb_modules/anr.c
index da23030ed3..49e453ffa1 100644
--- a/source4/dsdb/samdb/ldb_modules/anr.c
+++ b/source4/dsdb/samdb/ldb_modules/anr.c
@@ -289,7 +289,7 @@ static int anr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
switch (ares->type) {
case LDB_REPLY_ENTRY:
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
return ldb_module_send_referral(ac->req, ares->referral);
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 1387066256..1c50923eba 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -171,15 +171,39 @@ INIT_FUNCTION = LDB_MODULE(kludge_acl)
ldb_kludge_acl_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/kludge_acl.o
################################################
-# Start MODULE ldb_extended_dn
-[MODULE::ldb_extended_dn]
+# Start MODULE ldb_extended_dn_in
+[MODULE::ldb_extended_dn_in]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR LIBSECURITY SAMDB
-INIT_FUNCTION = LDB_MODULE(extended_dn)
-# End MODULE ldb_extended_dn
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_in)
+# End MODULE ldb_extended_dn_in
################################################
-ldb_extended_dn_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn.o
+ldb_extended_dn_in_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_in.o
+
+################################################
+# Start MODULE ldb_extended_dn_out
+[MODULE::ldb_extended_dn_out]
+SUBSYSTEM = LIBLDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_out_ldb),LDB_MODULE(extended_dn_out_dereference)
+ENABLE = YES
+ALIASES = extended_dn_out_ldb extended_dn_out_dereference
+# End MODULE ldb_extended_dn_out
+################################################
+
+ldb_extended_dn_out_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_out.o
+
+################################################
+# Start MODULE ldb_extended_dn_store
+[MODULE::ldb_extended_dn_store]
+SUBSYSTEM = LIBLDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS
+INIT_FUNCTION = LDB_MODULE(extended_dn_store)
+# End MODULE ldb_extended_dn_store
+################################################
+
+ldb_extended_dn_store_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_store.o
################################################
# Start MODULE ldb_show_deleted
@@ -288,18 +312,6 @@ SUBSYSTEM = LIBLDB
ldb_anr_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/anr.o
################################################
-# Start MODULE ldb_normalise
-[MODULE::ldb_normalise]
-INIT_FUNCTION = LDB_MODULE(normalise)
-CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSAMBA-UTIL SAMDB
-SUBSYSTEM = LIBLDB
-# End MODULE ldb_normalise
-################################################
-
-ldb_normalise_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/normalise.o
-
-################################################
# Start MODULE ldb_instancetype
[MODULE::ldb_instancetype]
INIT_FUNCTION = LDB_MODULE(instancetype)
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn.c b/source4/dsdb/samdb/ldb_modules/extended_dn.c
deleted file mode 100644
index a0602d9281..0000000000
--- a/source4/dsdb/samdb/ldb_modules/extended_dn.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- ldb database library
-
- Copyright (C) Simo Sorce 2005-2008
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Name: ldb
- *
- * Component: ldb extended dn control module
- *
- * Description: this module builds a special dn
- *
- * Author: Simo Sorce
- */
-
-#include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_errors.h"
-#include "ldb/include/ldb_private.h"
-#include "librpc/gen_ndr/ndr_misc.h"
-#include "dsdb/samdb/samdb.h"
-#include "libcli/security/security.h"
-
-#include <time.h>
-
-static bool is_attr_in_list(const char * const * attrs, const char *attr)
-{
- int i;
-
- for (i = 0; attrs[i]; i++) {
- if (strcasecmp(attrs[i], attr) == 0)
- return true;
- }
-
- return false;
-}
-
-static char **copy_attrs(void *mem_ctx, const char * const * attrs)
-{
- char **new;
- int i, num;
-
- for (num = 0; attrs[num]; num++);
-
- new = talloc_array(mem_ctx, char *, num + 1);
- if (!new) return NULL;
-
- for(i = 0; i < num; i++) {
- new[i] = talloc_strdup(new, attrs[i]);
- if (!new[i]) {
- talloc_free(new);
- return NULL;
- }
- }
- new[i] = NULL;
-
- return new;
-}
-
-static bool add_attrs(void *mem_ctx, char ***attrs, const char *attr)
-{
- char **new;
- int num;
-
- for (num = 0; (*attrs)[num]; num++);
-
- new = talloc_realloc(mem_ctx, *attrs, char *, num + 2);
- if (!new) return false;
-
- *attrs = new;
-
- new[num] = talloc_strdup(new, attr);
- if (!new[num]) return false;
-
- new[num + 1] = NULL;
-
- return true;
-}
-
-static int inject_extended_dn(struct ldb_message *msg,
- struct ldb_context *ldb,
- int type,
- bool remove_guid,
- bool remove_sid)
-{
- const struct ldb_val *val;
- struct GUID guid;
- struct dom_sid *sid;
- const DATA_BLOB *guid_blob;
- const DATA_BLOB *sid_blob;
- char *object_guid;
- char *object_sid;
- char *new_dn;
-
- guid_blob = ldb_msg_find_ldb_val(msg, "objectGUID");
- sid_blob = ldb_msg_find_ldb_val(msg, "objectSID");
-
- if (!guid_blob) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- switch (type) {
- case 0:
- /* return things in hexadecimal format */
- if (sid_blob) {
- const char *lower_guid_hex = strlower_talloc(msg, data_blob_hex_string(msg, guid_blob));
- const char *lower_sid_hex = strlower_talloc(msg, data_blob_hex_string(msg, sid_blob));
- if (!lower_guid_hex || !lower_sid_hex) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- new_dn = talloc_asprintf(msg, "<GUID=%s>;<SID=%s>;%s",
- lower_guid_hex,
- lower_sid_hex,
- ldb_dn_get_linearized(msg->dn));
- } else {
- const char *lower_guid_hex = strlower_talloc(msg, data_blob_hex_string(msg, guid_blob));
- if (!lower_guid_hex) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- new_dn = talloc_asprintf(msg, "<GUID=%s>;%s",
- lower_guid_hex,
- ldb_dn_get_linearized(msg->dn));
- }
-
- break;
- case 1:
- /* retrieve object_guid */
- guid = samdb_result_guid(msg, "objectGUID");
- object_guid = GUID_string(msg, &guid);
-
- /* retrieve object_sid */
- object_sid = NULL;
- sid = samdb_result_dom_sid(msg, msg, "objectSID");
- if (sid) {
- object_sid = dom_sid_string(msg, sid);
- if (!object_sid)
- return LDB_ERR_OPERATIONS_ERROR;
-
- }
-
- /* Normal, sane format */
- if (object_sid) {
- new_dn = talloc_asprintf(msg, "<GUID=%s>;<SID=%s>;%s",
- object_guid, object_sid,
- ldb_dn_get_linearized(msg->dn));
- } else {
- new_dn = talloc_asprintf(msg, "<GUID=%s>;%s",
- object_guid,
- ldb_dn_get_linearized(msg->dn));
- }
- break;
- default:
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (!new_dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (remove_guid) {
- ldb_msg_remove_attr(msg, "objectGUID");
- }
-
- if (sid_blob && remove_sid) {
- ldb_msg_remove_attr(msg, "objectSID");
- }
-
- msg->dn = ldb_dn_new(msg, ldb, new_dn);
- if (! ldb_dn_validate(msg->dn))
- return LDB_ERR_OPERATIONS_ERROR;
-
- val = ldb_msg_find_ldb_val(msg, "distinguishedName");
- if (val) {
- ldb_msg_remove_attr(msg, "distinguishedName");
- if (ldb_msg_add_steal_string(msg, "distinguishedName", new_dn))
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return LDB_SUCCESS;
-}
-
-/* search */
-struct extended_context {
-
- struct ldb_module *module;
- struct ldb_request *req;
- struct ldb_control *control;
- struct ldb_dn *basedn;
- char *wellknown_object;
- bool inject;
- bool remove_guid;
- bool remove_sid;
- int extended_type;
- const char * const *cast_attrs;
-};
-
-static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct extended_context *ac;
- int ret;
-
- ac = talloc_get_type(req->context, struct extended_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
- if (ac->inject) {
- /* for each record returned post-process to add any derived
- attributes that have been asked for */
- ret = inject_extended_dn(ares->message, ac->module->ldb,
- ac->extended_type, ac->remove_guid,
- ac->remove_sid);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
- }
- }
-
- return ldb_module_send_entry(ac->req, ares->message);
-
- case LDB_REPLY_REFERRAL:
- return ldb_module_send_referral(ac->req, ares->referral);
-
- case LDB_REPLY_DONE:
- return ldb_module_done(ac->req, ares->controls,
- ares->response, LDB_SUCCESS);
-
- }
- return LDB_SUCCESS;
-}
-
-static int extended_base_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct extended_context *ac;
- struct ldb_request *down_req;
- struct ldb_control **saved_controls;
- struct ldb_message_element *el;
- int ret;
- size_t i;
- size_t wkn_len = 0;
- char *valstr = NULL;
- const char *found = NULL;
-
- ac = talloc_get_type(req->context, struct extended_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
- if (!ac->wellknown_object) {
- ac->basedn = ares->message->dn;
- break;
- }
-
- wkn_len = strlen(ac->wellknown_object);
-
- el = ldb_msg_find_element(ares->message, "wellKnownObjects");
- if (!el) {
- ac->basedn = NULL;
- break;
- }
-
- for (i=0; i < el->num_values; i++) {
- valstr = talloc_strndup(ac,
- (const char *)el->values[i].data,
- el->values[i].length);
- if (!valstr) {
- ldb_oom(ac->module->ldb);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
-
- if (strncasecmp(valstr, ac->wellknown_object, wkn_len) != 0) {
- talloc_free(valstr);
- continue;
- }
-
- found = &valstr[wkn_len];
- break;
- }
-
- if (!found) {
- break;
- }
-
- ac->basedn = ldb_dn_new(ac, ac->module->ldb, found);
- talloc_free(valstr);
- if (!ac->basedn) {
- ldb_oom(ac->module->ldb);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
-
- break;
-
- case LDB_REPLY_REFERRAL:
- break;
-
- case LDB_REPLY_DONE:
-
- if (!ac->basedn) {
- const char *str = talloc_asprintf(req, "Base-DN '%s' not found",
- ldb_dn_get_linearized(ac->req->op.search.base));
- ldb_set_errstring(ac->module->ldb, str);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_NO_SUCH_OBJECT);
- }
-
- ret = ldb_build_search_req_ex(&down_req,
- ac->module->ldb, ac,
- ac->basedn,
- ac->req->op.search.scope,
- ac->req->op.search.tree,
- ac->cast_attrs,
- ac->req->controls,
- ac, extended_callback,
- ac->req);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
- }
-
- if (ac->control) {
- /* 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(ac->control, down_req, &saved_controls)) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- }
-
- /* perform the search */
- return ldb_next_request(ac->module, down_req);
- }
- return LDB_SUCCESS;
-}
-
-static int extended_search(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_control *control;
- struct ldb_extended_dn_control *extended_ctrl = NULL;
- struct ldb_control **saved_controls;
- struct extended_context *ac;
- struct ldb_request *down_req;
- char **new_attrs;
- int ret;
- struct ldb_dn *base_dn = NULL;
- enum ldb_scope base_dn_scope = LDB_SCOPE_BASE;
- const char *base_dn_filter = NULL;
- const char * const *base_dn_attrs = NULL;
- char *wellknown_object = NULL;
- static const char *dnattr[] = {
- "distinguishedName",
- NULL
- };
- static const char *wkattr[] = {
- "wellKnownObjects",
- NULL
- };
-
- if (ldb_dn_is_special(req->op.search.base)) {
- char *dn;
-
- dn = ldb_dn_alloc_linearized(req, req->op.search.base);
- if (!dn) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (strncasecmp(dn, "<SID=", 5) == 0) {
- char *str;
- char *valstr;
- char *p;
-
- p = strchr(dn, '=');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- str = p;
-
- p = strchr(str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- if (strncasecmp(str, "S-", 2) == 0) {
- valstr = str;
- } else {
- DATA_BLOB binary;
- binary = strhex_to_data_blob(NULL, str);
- if (!binary.data) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- valstr = ldb_binary_encode(req, binary);
- data_blob_free(&binary);
- if (!valstr) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* TODO: do a search over all partitions */
- base_dn = ldb_get_default_basedn(module->ldb);
- base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", valstr);
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_SUBTREE;
- base_dn_attrs = dnattr;
- } else if (strncasecmp(dn, "<GUID=", 6) == 0) {
- char *str;
- char *valstr;
- char *p;
-
- p = strchr(dn, '=');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- str = p;
-
- p = strchr(str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- if (strchr(str, '-')) {
- valstr = str;
- } else {
- DATA_BLOB binary;
- binary = strhex_to_data_blob(NULL, str);
- if (!binary.data) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- valstr = ldb_binary_encode(req, binary);
- data_blob_free(&binary);
- if (!valstr) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* TODO: do a search over all partitions */
- base_dn = ldb_get_default_basedn(module->ldb);
- base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", valstr);
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_SUBTREE;
- base_dn_attrs = dnattr;
- } else if (strncasecmp(dn, "<WKGUID=", 8) == 0) {
- char *tail_str;
- char *p;
-
- p = strchr(dn, ',');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
-
- p[0] = '\0';
- p++;
-
- wellknown_object = talloc_asprintf(req, "B:32:%s:", &dn[8]);
- if (!wellknown_object) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- tail_str = p;
- p = strchr(tail_str, '>');
- if (!p) {
- return LDB_ERR_INVALID_DN_SYNTAX;
- }
- p[0] = '\0';
-
- base_dn = ldb_dn_new(req, module->ldb, tail_str);
- if (!base_dn) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_filter = talloc_strdup(req, "(objectClass=*)");
- if (!base_dn_filter) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- base_dn_scope = LDB_SCOPE_BASE;
- base_dn_attrs = wkattr;
- }
- talloc_free(dn);
- }
-
- /* check if there's an extended dn control */
- control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
- if (control == NULL && base_dn_filter == NULL) {
- /* not found go on */
- return ldb_next_request(module, req);
- }
-
- if (control && control->data) {
- extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
- if (!extended_ctrl) {
- return LDB_ERR_PROTOCOL_ERROR;
- }
- }
-
- ac = talloc_zero(req, struct extended_context);
- if (ac == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ac->module = module;
- ac->req = req;
- ac->control = control;
- ac->basedn = NULL;
- ac->wellknown_object = wellknown_object;
- ac->inject = false;
- ac->remove_guid = false;
- ac->remove_sid = false;
-
- if (control) {
- ac->inject = true;
- if (extended_ctrl) {
- ac->extended_type = extended_ctrl->type;
- } else {
- ac->extended_type = 0;
- }
-
- /* check if attrs only is specified, in that case check wether we need to modify them */
- if (req->op.search.attrs) {
- if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) {
- ac->remove_guid = true;
- }
- if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
- ac->remove_sid = true;
- }
- if (ac->remove_guid || ac->remove_sid) {
- new_attrs = copy_attrs(ac, req->op.search.attrs);
- if (new_attrs == NULL) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ac->remove_guid) {
- if (!add_attrs(ac, &new_attrs, "objectGUID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (ac->remove_sid) {
- if (!add_attrs(ac, &new_attrs, "objectSID"))
- return LDB_ERR_OPERATIONS_ERROR;
- }
- ac->cast_attrs = (const char * const *)new_attrs;
- } else {
- ac->cast_attrs = req->op.search.attrs;
- }
- }
- }
-
- if (base_dn) {
- ret = ldb_build_search_req(&down_req,
- module->ldb, ac,
- base_dn,
- base_dn_scope,
- base_dn_filter,
- base_dn_attrs,
- NULL,
- ac, extended_base_callback,
- req);
- if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* perform the search */
- return ldb_next_request(module, down_req);
- }
-
- ret = ldb_build_search_req_ex(&down_req,
- module->ldb, ac,
- req->op.search.base,
- req->op.search.scope,
- req->op.search.tree,
- ac->cast_attrs,
- req->controls,
- ac, extended_callback,
- req);
- if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (ac->control) {
- /* 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)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- /* perform the search */
- return ldb_next_request(module, down_req);
-}
-
-static int extended_init(struct ldb_module *module)
-{
- int ret;
-
- ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
- if (ret != LDB_SUCCESS) {
- ldb_debug(module->ldb, LDB_DEBUG_ERROR,
- "extended_dn: Unable to register control with rootdse!\n");
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return ldb_next_init(module);
-}
-
-_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_module_ops = {
- .name = "extended_dn",
- .search = extended_search,
- .init_context = extended_init
-};
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c
new file mode 100644
index 0000000000..c3db4fa588
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c
@@ -0,0 +1,394 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module interprets DNs of the form <SID=S-1-2-4456> into normal DNs.
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+
+/* search */
+struct extended_search_context {
+ struct ldb_module *module;
+ struct ldb_request *req;
+ struct ldb_dn *basedn;
+ char *wellknown_object;
+ int extended_type;
+};
+
+/* An extra layer of indirection because LDB does not allow the original request to be altered */
+
+static int extended_final_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret = LDB_ERR_OPERATIONS_ERROR;
+ struct extended_search_context *ac;
+ ac = talloc_get_type(req->context, struct extended_search_context);
+
+ if (ares->error != LDB_SUCCESS) {
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ } else {
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
+ break;
+ case LDB_REPLY_REFERRAL:
+
+ ret = ldb_module_send_referral(ac->req, ares->referral);
+ break;
+ case LDB_REPLY_DONE:
+
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int extended_base_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ struct ldb_message_element *el;
+ int ret;
+ size_t i;
+ size_t wkn_len = 0;
+ char *valstr = NULL;
+ const char *found = NULL;
+
+ ac = talloc_get_type(req->context, struct extended_search_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+ if (!ac->wellknown_object) {
+ ac->basedn = talloc_steal(ac, ares->message->dn);
+ break;
+ }
+
+ wkn_len = strlen(ac->wellknown_object);
+
+ el = ldb_msg_find_element(ares->message, "wellKnownObjects");
+ if (!el) {
+ ac->basedn = NULL;
+ break;
+ }
+
+ for (i=0; i < el->num_values; i++) {
+ valstr = talloc_strndup(ac,
+ (const char *)el->values[i].data,
+ el->values[i].length);
+ if (!valstr) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (strncasecmp(valstr, ac->wellknown_object, wkn_len) != 0) {
+ talloc_free(valstr);
+ continue;
+ }
+
+ found = &valstr[wkn_len];
+ break;
+ }
+
+ if (!found) {
+ break;
+ }
+
+ ac->basedn = ldb_dn_new(ac, ac->module->ldb, found);
+ talloc_free(valstr);
+ if (!ac->basedn) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ break;
+
+ case LDB_REPLY_REFERRAL:
+ break;
+
+ case LDB_REPLY_DONE:
+
+ if (!ac->basedn) {
+ const char *str = talloc_asprintf(req, "Base-DN '%s' not found",
+ ldb_dn_get_linearized(ac->req->op.search.base));
+ ldb_set_errstring(ac->module->ldb, str);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_NO_SUCH_OBJECT);
+ }
+
+ switch (ac->req->operation) {
+ case LDB_SEARCH:
+ ret = ldb_build_search_req_ex(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->op.search.scope,
+ ac->req->op.search.tree,
+ ac->req->op.search.attrs,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ case LDB_ADD:
+ {
+ struct ldb_message *add_msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
+ if (!add_msg) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ add_msg->dn = ac->basedn;
+
+ ret = ldb_build_add_req(&down_req,
+ ac->module->ldb, ac->req,
+ add_msg,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ }
+ case LDB_MODIFY:
+ {
+ struct ldb_message *mod_msg = ldb_msg_copy_shallow(ac, ac->req->op.mod.message);
+ if (!mod_msg) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ mod_msg->dn = ac->basedn;
+
+ ret = ldb_build_mod_req(&down_req,
+ ac->module->ldb, ac->req,
+ mod_msg,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ }
+ case LDB_DELETE:
+ ret = ldb_build_del_req(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ case LDB_RENAME:
+ ret = ldb_build_rename_req(&down_req,
+ ac->module->ldb, ac->req,
+ ac->basedn,
+ ac->req->op.rename.newdn,
+ ac->req->controls,
+ ac, extended_final_callback,
+ ac->req);
+ break;
+ default:
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+
+ return ldb_next_request(ac->module, down_req);
+ }
+ talloc_free(ares);
+ return LDB_SUCCESS;
+}
+
+static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req, struct ldb_dn *dn)
+{
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ int ret;
+ struct ldb_dn *base_dn = NULL;
+ enum ldb_scope base_dn_scope = LDB_SCOPE_BASE;
+ const char *base_dn_filter = NULL;
+ const char * const *base_dn_attrs = NULL;
+ char *wellknown_object = NULL;
+ static const char *no_attr[] = {
+ NULL
+ };
+ static const char *wkattr[] = {
+ "wellKnownObjects",
+ NULL
+ };
+
+ if (!ldb_dn_has_extended(dn)) {
+ /* Move along there isn't anything to see here */
+ return ldb_next_request(module, req);
+ } else {
+ /* It looks like we need to map the DN */
+ const struct ldb_val *sid_val, *guid_val, *wkguid_val;
+
+ sid_val = ldb_dn_get_extended_component(dn, "SID");
+ guid_val = ldb_dn_get_extended_component(dn, "GUID");
+ wkguid_val = ldb_dn_get_extended_component(dn, "WKGUID");
+
+ if (sid_val) {
+ /* TODO: do a search over all partitions */
+ base_dn = ldb_get_default_basedn(module->ldb);
+ base_dn_filter = talloc_asprintf(req, "(objectSid=%s)",
+ ldb_binary_encode(req, *sid_val));
+ if (!base_dn_filter) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_scope = LDB_SCOPE_SUBTREE;
+ base_dn_attrs = no_attr;
+
+ } else if (guid_val) {
+
+ /* TODO: do a search over all partitions */
+ base_dn = ldb_get_default_basedn(module->ldb);
+ base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)",
+ ldb_binary_encode(req, *guid_val));
+ if (!base_dn_filter) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_scope = LDB_SCOPE_SUBTREE;
+ base_dn_attrs = no_attr;
+
+
+ } else if (wkguid_val) {
+ char *wkguid_dup;
+ char *tail_str;
+ char *p;
+
+ wkguid_dup = talloc_strndup(req, (char *)wkguid_val->data, wkguid_val->length);
+
+ p = strchr(wkguid_dup, ',');
+ if (!p) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ p[0] = '\0';
+ p++;
+
+ wellknown_object = talloc_asprintf(req, "B:32:%s:", wkguid_dup);
+ if (!wellknown_object) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ tail_str = p;
+
+ base_dn = ldb_dn_new(req, module->ldb, tail_str);
+ talloc_free(wkguid_dup);
+ if (!base_dn) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_filter = talloc_strdup(req, "(objectClass=*)");
+ if (!base_dn_filter) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ base_dn_scope = LDB_SCOPE_BASE;
+ base_dn_attrs = wkattr;
+ } else {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ ac = talloc_zero(req, struct extended_search_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ac->module = module;
+ ac->req = req;
+ ac->basedn = NULL; /* Filled in if the search finds the DN by SID/GUID etc */
+ ac->wellknown_object = wellknown_object;
+
+ /* If the base DN was an extended DN (perhaps a well known
+ * GUID) then search for that, so we can proceed with the original operation */
+
+ ret = ldb_build_search_req(&down_req,
+ module->ldb, ac,
+ base_dn,
+ base_dn_scope,
+ base_dn_filter,
+ base_dn_attrs,
+ NULL,
+ ac, extended_base_callback,
+ req);
+ if (ret != LDB_SUCCESS) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* perform the search */
+ return ldb_next_request(module, down_req);
+ }
+}
+
+static int extended_dn_in_search(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.search.base);
+}
+
+static int extended_dn_in_modify(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.mod.message->dn);
+}
+
+static int extended_dn_in_del(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.del.dn);
+}
+
+static int extended_dn_in_rename(struct ldb_module *module, struct ldb_request *req)
+{
+ return extended_dn_in_fix(module, req, req->op.rename.olddn);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_in_module_ops = {
+ .name = "extended_dn_in",
+ .search = extended_dn_in_search,
+ .modify = extended_dn_in_modify,
+ .del = extended_dn_in_del,
+ .rename = extended_dn_in_rename,
+};
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
new file mode 100644
index 0000000000..058c51bdb8
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
@@ -0,0 +1,655 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module builds a special dn for returned search
+ * results, and fixes some other aspects of the result (returned case issues)
+ * values.
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/ndr/libndr.h"
+#include "dsdb/samdb/samdb.h"
+
+struct extended_dn_out_private {
+ bool dereference;
+ bool normalise;
+ struct dsdb_openldap_dereference_control *dereference_control;
+};
+
+static bool is_attr_in_list(const char * const * attrs, const char *attr)
+{
+ int i;
+
+ for (i = 0; attrs[i]; i++) {
+ if (ldb_attr_cmp(attrs[i], attr) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static char **copy_attrs(void *mem_ctx, const char * const * attrs)
+{
+ char **new;
+ int i, num;
+
+ for (num = 0; attrs[num]; num++);
+
+ new = talloc_array(mem_ctx, char *, num + 1);
+ if (!new) return NULL;
+
+ for(i = 0; i < num; i++) {
+ new[i] = talloc_strdup(new, attrs[i]);
+ if (!new[i]) {
+ talloc_free(new);
+ return NULL;
+ }
+ }
+ new[i] = NULL;
+
+ return new;
+}
+
+static bool add_attrs(void *mem_ctx, char ***attrs, const char *attr)
+{
+ char **new;
+ int num;
+
+ for (num = 0; (*attrs)[num]; num++);
+
+ new = talloc_realloc(mem_ctx, *attrs, char *, num + 2);
+ if (!new) return false;
+
+ *attrs = new;
+
+ new[num] = talloc_strdup(new, attr);
+ if (!new[num]) return false;
+
+ new[num + 1] = NULL;
+
+ return true;
+}
+
+/* Fix the DN so that the relative attribute names are in upper case so that the DN:
+ cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
+ CN=Adminstrator,CN=users,DC=samba,DC=example,DC=com
+*/
+
+
+static int fix_dn(struct ldb_dn *dn)
+{
+ int i, ret;
+ char *upper_rdn_attr;
+
+ for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
+ /* We need the attribute name in upper case */
+ upper_rdn_attr = strupper_talloc(dn,
+ ldb_dn_get_component_name(dn, i));
+ if (!upper_rdn_attr) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* And replace it with CN=foo (we need the attribute in upper case */
+ ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
+ *ldb_dn_get_component_val(dn, i));
+ talloc_free(upper_rdn_attr);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ return LDB_SUCCESS;
+}
+
+/* Inject the extended DN components, so the DN cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com becomes
+ <GUID=541203ae-f7d6-47ef-8390-bfcf019f9583>;<SID=S-1-5-21-4177067393-1453636373-93818737-500>;cn=Adminstrator,cn=users,dc=samba,dc=example,dc=com */
+
+static int inject_extended_dn_out(struct ldb_reply *ares,
+ struct ldb_context *ldb,
+ int type,
+ bool remove_guid,
+ bool remove_sid)
+{
+ int ret;
+ const DATA_BLOB *guid_blob;
+ const DATA_BLOB *sid_blob;
+
+ guid_blob = ldb_msg_find_ldb_val(ares->message, "objectGUID");
+ sid_blob = ldb_msg_find_ldb_val(ares->message, "objectSID");
+
+ if (!guid_blob) {
+ ldb_set_errstring(ldb, "Did not find objectGUID to inject into extended DN");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_dn_set_extended_component(ares->message->dn, "GUID", guid_blob);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (sid_blob) {
+ ret = ldb_dn_set_extended_component(ares->message->dn, "SID", sid_blob);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ if (remove_guid) {
+ ldb_msg_remove_attr(ares->message, "objectGUID");
+ }
+
+ if (sid_blob && remove_sid) {
+ ldb_msg_remove_attr(ares->message, "objectSID");
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int handle_dereference(struct ldb_dn *dn,
+ struct dsdb_openldap_dereference_result **dereference_attrs,
+ const char *attr, const DATA_BLOB *val)
+{
+ const struct ldb_val *entryUUIDblob, *sid_blob;
+ struct ldb_message fake_msg; /* easier to use routines that expect an ldb_message */
+ int j;
+
+ fake_msg.num_elements = 0;
+
+ /* Look for this attribute in the returned control */
+ for (j = 0; dereference_attrs && dereference_attrs[j]; j++) {
+ struct ldb_val source_dn = data_blob_string_const(dereference_attrs[j]->dereferenced_dn);
+ if (ldb_attr_cmp(dereference_attrs[j]->source_attribute, attr) == 0
+ && data_blob_cmp(&source_dn, val) == 0) {
+ fake_msg.num_elements = dereference_attrs[j]->num_attributes;
+ fake_msg.elements = dereference_attrs[j]->attributes;
+ break;
+ }
+ }
+ if (!fake_msg.num_elements) {
+ return LDB_SUCCESS;
+ }
+ /* Look for an OpenLDAP entryUUID */
+
+ entryUUIDblob = ldb_msg_find_ldb_val(&fake_msg, "entryUUID");
+ if (entryUUIDblob) {
+ NTSTATUS status;
+ enum ndr_err_code ndr_err;
+
+ struct ldb_val guid_blob;
+ struct GUID guid;
+
+ status = GUID_from_data_blob(entryUUIDblob, &guid);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ ndr_err = ndr_push_struct_blob(&guid_blob, NULL, NULL, &guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+ }
+
+ sid_blob = ldb_msg_find_ldb_val(&fake_msg, "objectSID");
+
+ /* Look for the objectSID */
+ if (sid_blob) {
+ ldb_dn_set_extended_component(dn, "SID", sid_blob);
+ }
+ return LDB_SUCCESS;
+}
+
+/* search */
+struct extended_search_context {
+ struct ldb_module *module;
+ const struct dsdb_schema *schema;
+ struct ldb_request *req;
+ bool inject;
+ bool remove_guid;
+ bool remove_sid;
+ int extended_type;
+};
+
+static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_search_context *ac;
+ struct ldb_control *control;
+ struct dsdb_openldap_dereference_result_control *dereference_control = NULL;
+ int ret, i, j;
+ struct ldb_message *msg = ares->message;
+ struct extended_dn_out_private *private;
+
+ ac = talloc_get_type(req->context, struct extended_search_context);
+ private = talloc_get_type(ac->module->private_data, struct extended_dn_out_private);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ switch (ares->type) {
+ case LDB_REPLY_REFERRAL:
+ return ldb_module_send_referral(ac->req, ares->referral);
+
+ case LDB_REPLY_DONE:
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, LDB_SUCCESS);
+ case LDB_REPLY_ENTRY:
+ break;
+ }
+
+ if (private && private->normalise) {
+ ret = fix_dn(ares->message->dn);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ if (ac->inject) {
+ /* for each record returned post-process to add any derived
+ attributes that have been asked for */
+ ret = inject_extended_dn_out(ares, ac->module->ldb,
+ ac->extended_type, ac->remove_guid,
+ ac->remove_sid);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ if ((private && private->normalise) || ac->inject) {
+ const struct ldb_val *val = ldb_msg_find_ldb_val(ares->message, "distinguishedName");
+ if (val) {
+ ldb_msg_remove_attr(ares->message, "distinguishedName");
+ if (ac->inject) {
+ ret = ldb_msg_add_steal_string(ares->message, "distinguishedName",
+ ldb_dn_get_extended_linearized(ares->message, ares->message->dn, ac->extended_type));
+ } else {
+ ret = ldb_msg_add_string(ares->message, "distinguishedName",
+ ldb_dn_get_linearized(ares->message->dn));
+ }
+ if (ret != LDB_SUCCESS) {
+ ldb_oom(ac->module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+ }
+
+ if (private && private->dereference) {
+ control = ldb_reply_get_control(ares, DSDB_OPENLDAP_DEREFERENCE_CONTROL);
+
+ if (control && control->data) {
+ dereference_control = talloc_get_type(control->data, struct dsdb_openldap_dereference_result_control);
+ }
+ }
+
+ /* Walk the retruned elements (but only if we have a schema to interpret the list with) */
+ for (i = 0; ac->schema && i < msg->num_elements; i++) {
+ const struct dsdb_attribute *attribute;
+ attribute = dsdb_attribute_by_lDAPDisplayName(ac->schema, msg->elements[i].name);
+ if (!attribute) {
+ continue;
+ }
+
+ if (private->normalise) {
+ /* If we are also in 'normalise' mode, then
+ * fix the attribute names to be in the
+ * correct case */
+ msg->elements[i].name = talloc_strdup(msg->elements, attribute->lDAPDisplayName);
+ if (!msg->elements[i].name) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
+ }
+ }
+
+ /* distinguishedName has been dealt with above */
+ if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) {
+ continue;
+ }
+
+ /* Look to see if this attributeSyntax is a DN */
+ if (strcmp(attribute->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ for (j = 0; j < msg->elements[i].num_values; j++) {
+ const char *dn_str;
+ struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, &msg->elements[i].values[j]);
+ if (!dn || !ldb_dn_validate(dn)) {
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_INVALID_DN_SYNTAX);
+ }
+
+ if (private->normalise) {
+ ret = fix_dn(dn);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ /* If we are running in dereference mode (such
+ * as against OpenLDAP) then the DN in the msg
+ * above does not contain the extended values,
+ * and we need to look in the dereference
+ * result */
+
+ /* Look for this value in the attribute */
+
+ if (dereference_control) {
+ ret = handle_dereference(dn,
+ dereference_control->attributes,
+ msg->elements[i].name,
+ &msg->elements[i].values[j]);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ }
+
+ if (!ac->inject) {
+ dn_str = talloc_steal(msg->elements[i].values,
+ ldb_dn_get_linearized(dn));
+ } else {
+ dn_str = talloc_steal(msg->elements[i].values,
+ ldb_dn_get_extended_linearized(msg->elements[i].values,
+ dn, ac->extended_type));
+ }
+ if (!dn_str) {
+ ldb_oom(ac->module->ldb);
+ return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
+ }
+ msg->elements[i].values[j] = data_blob_string_const(dn_str);
+ talloc_free(dn);
+ }
+ }
+ return ldb_module_send_entry(ac->req, msg, ares->controls);
+}
+
+
+static int extended_dn_out_search(struct ldb_module *module, struct ldb_request *req)
+{
+ struct ldb_control *control;
+ struct ldb_control *storage_format_control;
+ struct ldb_extended_dn_control *extended_ctrl = NULL;
+ struct ldb_control **saved_controls;
+ struct extended_search_context *ac;
+ struct ldb_request *down_req;
+ char **new_attrs;
+ const char * const *const_attrs;
+ int ret;
+
+ struct extended_dn_out_private *private = talloc_get_type(module->private_data, struct extended_dn_out_private);
+
+ /* check if there's an extended dn control */
+ control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
+ if (control && control->data) {
+ extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
+ if (!extended_ctrl) {
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+ }
+
+ /* Look to see if, as we are in 'store DN+GUID+SID' mode, the
+ * client is after the storage format (to fill in linked
+ * attributes) */
+ storage_format_control = ldb_request_get_control(req, DSDB_CONTROL_DN_STORAGE_FORMAT_OID);
+ if (!control && storage_format_control && storage_format_control->data) {
+ extended_ctrl = talloc_get_type(storage_format_control->data, struct ldb_extended_dn_control);
+ if (!extended_ctrl) {
+ ldb_set_errstring(module->ldb, "extended_dn_out: extended_ctrl was of the wrong data type");
+ return LDB_ERR_PROTOCOL_ERROR;
+ }
+ }
+
+ ac = talloc_zero(req, struct extended_search_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ac->module = module;
+ ac->schema = dsdb_get_schema(module->ldb);
+ ac->req = req;
+ ac->inject = false;
+ ac->remove_guid = false;
+ ac->remove_sid = false;
+
+ const_attrs = req->op.search.attrs;
+
+ /* We only need to do special processing if we were asked for
+ * the extended DN, or we are 'store DN+GUID+SID'
+ * (!dereference) mode. (This is the normal mode for LDB on
+ * tdb). */
+ if (control || (storage_format_control && private && !private->dereference)) {
+ ac->inject = true;
+ if (extended_ctrl) {
+ ac->extended_type = extended_ctrl->type;
+ } else {
+ ac->extended_type = 0;
+ }
+
+ /* check if attrs only is specified, in that case check wether we need to modify them */
+ if (req->op.search.attrs && !is_attr_in_list(req->op.search.attrs, "*")) {
+ if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) {
+ ac->remove_guid = true;
+ }
+ if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
+ ac->remove_sid = true;
+ }
+ if (ac->remove_guid || ac->remove_sid) {
+ new_attrs = copy_attrs(ac, req->op.search.attrs);
+ if (new_attrs == NULL) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (ac->remove_guid) {
+ if (!add_attrs(ac, &new_attrs, "objectGUID"))
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ if (ac->remove_sid) {
+ if (!add_attrs(ac, &new_attrs, "objectSID"))
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ const_attrs = (const char * const *)new_attrs;
+ }
+ }
+ }
+
+ ret = ldb_build_search_req_ex(&down_req,
+ module->ldb, ac,
+ req->op.search.base,
+ req->op.search.scope,
+ req->op.search.tree,
+ const_attrs,
+ req->controls,
+ ac, extended_callback,
+ req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ /* Remove extended DN and storage format controls */
+
+ if (control) {
+ /* 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)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
+ if (storage_format_control) {
+ /* 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(storage_format_control, down_req, &saved_controls)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ }
+
+ /* Add in dereference control, if we were asked to, we are
+ * using the 'dereference' mode (such as with an OpenLDAP
+ * backend) and have the control prepared */
+ if (control && private && private->dereference && private->dereference_control) {
+ ret = ldb_request_add_control(down_req,
+ DSDB_OPENLDAP_DEREFERENCE_CONTROL,
+ false, private->dereference_control);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ /* perform the search */
+ return ldb_next_request(module, down_req);
+}
+
+static int extended_dn_out_ldb_init(struct ldb_module *module)
+{
+ int ret;
+
+ struct extended_dn_out_private *private = talloc(module, struct extended_dn_out_private);
+
+ module->private_data = private;
+
+ if (!private) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ private->dereference = false;
+ private->normalise = false;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return ldb_next_init(module);
+}
+
+static int extended_dn_out_dereference_init(struct ldb_module *module)
+{
+ int ret, i = 0;
+ struct extended_dn_out_private *private;
+ struct dsdb_openldap_dereference_control *dereference_control;
+ struct dsdb_attribute *cur;
+
+ struct dsdb_schema *schema;
+
+ module->private_data = private = talloc_zero(module, struct extended_dn_out_private);
+
+ if (!private) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ private->dereference = true;
+
+ /* At the moment, servers that need dereference also need the
+ * DN and attribute names to be normalised */
+ private->normalise = true;
+
+ ret = ldb_mod_register_control(module, LDB_CONTROL_EXTENDED_DN_OID);
+ if (ret != LDB_SUCCESS) {
+ ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+ "extended_dn_out: Unable to register control with rootdse!\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_next_init(module);
+
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ schema = dsdb_get_schema(module->ldb);
+ if (!schema) {
+ /* No schema on this DB (yet) */
+ return LDB_SUCCESS;
+ }
+
+ private->dereference_control = dereference_control
+ = talloc_zero(private, struct dsdb_openldap_dereference_control);
+
+ if (!private->dereference_control) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ for (cur = schema->attributes; cur; cur = cur->next) {
+ static const char *attrs[] = {
+ "entryUUID",
+ "objectSID",
+ NULL
+ };
+
+ if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+ dereference_control->dereference
+ = talloc_realloc(private, dereference_control->dereference,
+ struct dsdb_openldap_dereference *, i + 2);
+ if (!dereference_control) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dereference_control->dereference[i] = talloc(dereference_control->dereference,
+ struct dsdb_openldap_dereference);
+ if (!dereference_control->dereference[i]) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dereference_control->dereference[i]->source_attribute = cur->lDAPDisplayName;
+ dereference_control->dereference[i]->dereference_attribute = attrs;
+ i++;
+ dereference_control->dereference[i] = NULL;
+ }
+ return LDB_SUCCESS;
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_ldb_module_ops = {
+ .name = "extended_dn_out_ldb",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_ldb_init,
+};
+
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_out_dereference_module_ops = {
+ .name = "extended_dn_out_dereference",
+ .search = extended_dn_out_search,
+ .init_context = extended_dn_out_dereference_init,
+};
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
new file mode 100644
index 0000000000..4f4e9d0fd7
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
@@ -0,0 +1,431 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-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/>.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb extended dn control module
+ *
+ * Description: this module builds a special dn for returned search
+ * results nad creates the special DN in the backend store for new
+ * values.
+ *
+ * This also has the curious result that we convert <SID=S-1-2-345>
+ * in an attribute value into a normal DN for the rest of the stack
+ * to process
+ *
+ * Authors: Simo Sorce
+ * Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "dsdb/samdb/samdb.h"
+#include "libcli/security/security.h"
+
+#include <time.h>
+
+struct extended_dn_replace_list {
+ struct extended_dn_replace_list *next;
+ struct ldb_dn *dn;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_val *replace_dn;
+ struct extended_dn_context *ac;
+ struct ldb_request *search_req;
+};
+
+
+struct extended_dn_context {
+ const struct dsdb_schema *schema;
+ struct ldb_module *module;
+ struct ldb_request *req;
+ struct ldb_request *new_req;
+
+ struct extended_dn_replace_list *ops;
+ struct extended_dn_replace_list *cur;
+};
+
+
+static struct extended_dn_context *extended_dn_context_init(struct ldb_module *module,
+ struct ldb_request *req)
+{
+ struct extended_dn_context *ac;
+
+ ac = talloc_zero(req, struct extended_dn_context);
+ if (ac == NULL) {
+ ldb_oom(module->ldb);
+ return NULL;
+ }
+
+ ac->schema = dsdb_get_schema(module->ldb);
+ ac->module = module;
+ ac->req = req;
+
+ return ac;
+}
+
+/* An extra layer of indirection because LDB does not allow the original request to be altered */
+
+static int extended_final_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret = LDB_ERR_OPERATIONS_ERROR;
+ struct extended_dn_context *ac;
+ ac = talloc_get_type(req->context, struct extended_dn_context);
+
+ if (ares->error != LDB_SUCCESS) {
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ } else {
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
+ break;
+ case LDB_REPLY_REFERRAL:
+
+ ret = ldb_module_send_referral(ac->req, ares->referral);
+ break;
+ case LDB_REPLY_DONE:
+
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int extended_replace_dn(struct ldb_request *req, struct ldb_reply *ares)
+{
+ struct extended_dn_replace_list *os = talloc_get_type(req->context,
+ struct extended_dn_replace_list);
+
+ if (!ares) {
+ return ldb_module_done(os->ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error == LDB_ERR_NO_SUCH_OBJECT) {
+ /* Don't worry too much about dangling references */
+
+ ldb_reset_err_string(os->ac->module->ldb);
+ if (os->next) {
+ struct extended_dn_replace_list *next;
+
+ next = os->next;
+
+ talloc_free(os);
+
+ os = next;
+ return ldb_next_request(os->ac->module, next->search_req);
+ } else {
+ /* Otherwise, we are done - let's run the
+ * request now we have swapped the DNs for the
+ * full versions */
+ return ldb_next_request(os->ac->module, os->ac->req);
+ }
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(os->ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ /* Only entries are interesting, and we only want the olddn */
+ switch (ares->type) {
+ case LDB_REPLY_ENTRY:
+ {
+ /* This *must* be the right DN, as this is a base
+ * search. We can't check, as it could be an extended
+ * DN, so a module below will resolve it */
+ struct ldb_dn *dn = ares->message->dn;
+
+ /* Replace the DN with the extended version of the DN
+ * (ie, add SID and GUID) */
+ *os->replace_dn = data_blob_string_const(
+ ldb_dn_get_extended_linearized(os->mem_ctx,
+ dn, 1));
+ if (os->replace_dn->data == NULL) {
+ return ldb_module_done(os->ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ break;
+ }
+ case LDB_REPLY_REFERRAL:
+ /* ignore */
+ break;
+
+ case LDB_REPLY_DONE:
+
+ talloc_free(ares);
+
+ /* Run the next search */
+
+ if (os->next) {
+ struct extended_dn_replace_list *next;
+
+ next = os->next;
+
+ talloc_free(os);
+
+ os = next;
+ return ldb_next_request(os->ac->module, next->search_req);
+ } else {
+ /* Otherwise, we are done - let's run the
+ * request now we have swapped the DNs for the
+ * full versions */
+ return ldb_next_request(os->ac->module, os->ac->new_req);
+ }
+ }
+
+ talloc_free(ares);
+ return LDB_SUCCESS;
+}
+
+/* We have a 'normal' DN in the inbound request. We need to find out
+ * what the GUID and SID are on the DN it points to, so we can
+ * construct an extended DN for storage.
+ *
+ * This creates a list of DNs to look up, and the plain DN to replace
+ */
+
+static int extended_store_replace(struct extended_dn_context *ac,
+ TALLOC_CTX *callback_mem_ctx,
+ struct ldb_val *plain_dn)
+{
+ int ret;
+ struct extended_dn_replace_list *os;
+ static const char *attrs[] = {
+ "objectSid",
+ "objectGUID",
+ NULL
+ };
+
+ os = talloc_zero(ac, struct extended_dn_replace_list);
+ if (!os) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ os->ac = ac;
+
+ os->mem_ctx = callback_mem_ctx;
+
+ os->dn = ldb_dn_from_ldb_val(os, ac->module->ldb, plain_dn);
+ if (!os->dn || !ldb_dn_validate(os->dn)) {
+ talloc_free(os);
+ ldb_asprintf_errstring(ac->module->ldb,
+ "could not parse %.*s as a DN", (int)plain_dn->length, plain_dn->data);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+
+ os->replace_dn = plain_dn;
+
+ /* The search request here might happen to be for an
+ * 'extended' style DN, such as <GUID=abced...>. The next
+ * module in the stack will convert this into a normal DN for
+ * processing */
+ ret = ldb_build_search_req(&os->search_req,
+ ac->module->ldb, os, os->dn, LDB_SCOPE_BASE, NULL,
+ attrs, NULL, os, extended_replace_dn,
+ ac->req);
+
+ if (ret != LDB_SUCCESS) {
+ talloc_free(os);
+ return ret;
+ }
+
+ ret = ldb_request_add_control(os->search_req,
+ DSDB_CONTROL_DN_STORAGE_FORMAT_OID,
+ true, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(os);
+ return ret;
+ }
+
+ if (ac->ops) {
+ ac->cur->next = os;
+ } else {
+ ac->ops = os;
+ }
+ ac->cur = os;
+
+ return LDB_SUCCESS;
+}
+
+
+/* add */
+static int extended_dn_add(struct ldb_module *module, struct ldb_request *req)
+{
+ struct extended_dn_context *ac;
+ int ret;
+ int i, j;
+
+ if (ldb_dn_is_special(req->op.add.message->dn)) {
+ /* do not manipulate our control entries */
+ return ldb_next_request(module, req);
+ }
+
+ ac = extended_dn_context_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ for (i=0; i < req->op.add.message->num_elements; i++) {
+ const struct ldb_message_element *el = &req->op.add.message->elements[i];
+ const struct dsdb_attribute *schema_attr
+ = dsdb_attribute_by_lDAPDisplayName(ac->schema, el->name);
+ if (!schema_attr) {
+ continue;
+ }
+
+ /* We only setup an extended DN GUID on these particular DN objects */
+ if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ /* Before we setup a procedure to modify the incoming message, we must copy it */
+ if (!ac->new_req) {
+ struct ldb_message *msg = ldb_msg_copy(ac, req->op.add.message);
+ if (!msg) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_add_req(&ac->new_req, module->ldb, ac, msg, req->controls, ac, extended_final_callback, req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ /* Re-calculate el */
+ el = &ac->new_req->op.add.message->elements[i];
+ for (j = 0; j < el->num_values; j++) {
+ ret = extended_store_replace(ac, ac->new_req->op.add.message->elements, &el->values[j]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
+ /* if DNs were set continue */
+ if (ac->ops == NULL) {
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the searches */
+ return ldb_next_request(module, ac->ops->search_req);
+}
+
+/* modify */
+static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req)
+{
+ /* Look over list of modifications */
+ /* Find if any are for linked attributes */
+ /* Determine the effect of the modification */
+ /* Apply the modify to the linked entry */
+
+ int i, j;
+ struct extended_dn_context *ac;
+ int ret;
+
+ if (ldb_dn_is_special(req->op.mod.message->dn)) {
+ /* do not manipulate our control entries */
+ return ldb_next_request(module, req);
+ }
+
+ ac = extended_dn_context_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ return ldb_next_request(module, req);
+ }
+
+ for (i=0; i < req->op.mod.message->num_elements; i++) {
+ const struct ldb_message_element *el = &req->op.mod.message->elements[i];
+ const struct dsdb_attribute *schema_attr
+ = dsdb_attribute_by_lDAPDisplayName(ac->schema, el->name);
+ if (!schema_attr) {
+ continue;
+ }
+
+ /* We only setup an extended DN GUID on these particular DN objects */
+ if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0) {
+ continue;
+ }
+
+ /* Before we setup a procedure to modify the incoming message, we must copy it */
+ if (!ac->new_req) {
+ struct ldb_message *msg = ldb_msg_copy(ac, req->op.mod.message);
+ if (!msg) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_mod_req(&ac->new_req, module->ldb, ac, msg, req->controls, ac, extended_final_callback, req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ /* Re-calculate el */
+ el = &ac->new_req->op.mod.message->elements[i];
+ /* For each value being added, we need to setup the lookups to fill in the extended DN */
+ for (j = 0; j < el->num_values; j++) {
+ struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, module->ldb, &el->values[j]);
+ if (!dn || !ldb_dn_validate(dn)) {
+ ldb_asprintf_errstring(module->ldb,
+ "could not parse attribute %s as a DN", el->name);
+ return LDB_ERR_INVALID_DN_SYNTAX;
+ }
+ if (((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_DELETE) && !ldb_dn_has_extended(dn)) {
+ /* NO need to figure this DN out, it's going to be deleted anyway */
+ continue;
+ }
+ ret = extended_store_replace(ac, req->op.mod.message->elements, &el->values[j]);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
+ /* if DNs were set continue */
+ if (ac->ops == NULL) {
+ talloc_free(ac);
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the searches */
+ return ldb_next_request(module, ac->ops->search_req);
+}
+
+_PUBLIC_ const struct ldb_module_ops ldb_extended_dn_store_module_ops = {
+ .name = "extended_dn_store",
+ .add = extended_dn_add,
+ .modify = extended_dn_modify,
+};
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
index 97179a8126..275e9b5299 100644
--- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -301,7 +301,7 @@ static int kludge_acl_callback(struct ldb_request *req, struct ldb_reply *ares)
}
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
return ldb_module_send_referral(ac->req, ares->referral);
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index f16eb215a6..a3318ccabd 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -32,10 +32,12 @@
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_errors.h"
#include "ldb/include/ldb_private.h"
+#include "ldb/include/dlinklist.h"
#include "dsdb/samdb/samdb.h"
struct la_op_store {
struct la_op_store *next;
+ struct la_op_store *prev;
enum la_op {LA_OP_ADD, LA_OP_DEL} op;
struct ldb_dn *dn;
char *name;
@@ -52,10 +54,12 @@ struct la_context {
const struct dsdb_schema *schema;
struct ldb_module *module;
struct ldb_request *req;
-
+ struct ldb_dn *add_dn;
+ struct ldb_dn *del_dn;
struct replace_context *rc;
struct la_op_store *ops;
- struct la_op_store *cur;
+ struct ldb_extended *op_response;
+ struct ldb_control **op_controls;
};
static struct la_context *linked_attributes_init(struct ldb_module *module,
@@ -65,7 +69,7 @@ static struct la_context *linked_attributes_init(struct ldb_module *module,
ac = talloc_zero(req, struct la_context);
if (ac == NULL) {
- ldb_set_errstring(module->ldb, "Out of Memory");
+ ldb_oom(module->ldb);
return NULL;
}
@@ -80,9 +84,9 @@ static struct la_context *linked_attributes_init(struct ldb_module *module,
* series of modify requests */
static int la_store_op(struct la_context *ac,
enum la_op op, struct ldb_val *dn,
- const char *name, const char *value)
+ const char *name)
{
- struct la_op_store *os, *tmp;
+ struct la_op_store *os;
struct ldb_dn *op_dn;
op_dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, dn);
@@ -92,68 +96,30 @@ static int la_store_op(struct la_context *ac,
return LDB_ERR_INVALID_DN_SYNTAX;
}
- /* optimize out del - add operations that would end up
- * with no changes */
- if (ac->ops && op == LA_OP_DEL) {
- /* do a linear search to find out if there is
- * an equivalent add */
- os = ac->ops;
- while (os->next) {
-
- tmp = os->next;
- if (tmp->op == LA_OP_ADD) {
-
- if ((strcmp(name, tmp->name) == 0) &&
- (strcmp(value, tmp->value) == 0) &&
- (ldb_dn_compare(op_dn, tmp->dn) == 0)) {
-
- break;
- }
- }
- os = os->next;
- }
- if (os->next) {
- /* pair found, remove it and return */
- os->next = tmp->next;
- talloc_free(tmp);
- talloc_free(op_dn);
- return LDB_SUCCESS;
- }
- }
-
os = talloc_zero(ac, struct la_op_store);
if (!os) {
+ ldb_oom(ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
os->op = op;
os->dn = talloc_steal(os, op_dn);
- if (!os->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
os->name = talloc_strdup(os, name);
if (!os->name) {
+ ldb_oom(ac->module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- if ((op != LA_OP_DEL) && (value == NULL)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (value) {
- os->value = talloc_strdup(os, value);
- if (!os->value) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
- if (ac->ops) {
- ac->cur->next = os;
+ /* Do deletes before adds */
+ if (op == LA_OP_ADD) {
+ DLIST_ADD_END(ac->ops, os, struct la_op_store *);
} else {
- ac->ops = os;
+ /* By adding to the head of the list, we do deletes before
+ * adds when processing a replace */
+ DLIST_ADD(ac->ops, os);
}
- ac->cur = os;
return LDB_SUCCESS;
}
@@ -164,8 +130,6 @@ static int la_do_mod_request(struct la_context *ac);
static int la_mod_callback(struct ldb_request *req,
struct ldb_reply *ares);
static int la_down_req(struct la_context *ac);
-static int la_down_callback(struct ldb_request *req,
- struct ldb_reply *ares);
@@ -175,7 +139,6 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
const struct dsdb_attribute *target_attr;
struct la_context *ac;
const char *attr_name;
- const char *attr_val;
int ret;
int i, j;
@@ -231,12 +194,11 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
}
attr_name = target_attr->lDAPDisplayName;
- attr_val = ldb_dn_get_linearized(ac->req->op.add.message->dn);
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_ADD,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -245,6 +207,7 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
/* if no linked attributes are present continue */
if (ac->ops == NULL) {
+ /* nothing to do for this module, proceed */
talloc_free(ac);
return ldb_next_request(module, req);
}
@@ -265,7 +228,6 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
struct replace_context *rc;
struct la_context *ac;
const char *attr_name;
- const char *dn;
int i, j;
int ret = LDB_SUCCESS;
@@ -286,16 +248,18 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
case LDB_REPLY_ENTRY:
if (ldb_dn_compare(ares->message->dn, ac->req->op.mod.message->dn) != 0) {
+ ldb_asprintf_errstring(ac->module->ldb,
+ "linked_attributes: %s is not the DN we were looking for", ldb_dn_get_linearized(ares->message->dn));
/* Guh? We only asked for this DN */
- ldb_oom(ac->module->ldb);
talloc_free(ares);
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- dn = ldb_dn_get_linearized(ac->req->op.add.message->dn);
+ ac->add_dn = ac->del_dn = talloc_steal(ac, ares->message->dn);
- for (i = 0; i < rc->num_elements; i++) {
+ /* We don't populate 'rc' for ADD - it can't be deleting elements anyway */
+ for (i = 0; rc && i < rc->num_elements; i++) {
schema_attr = dsdb_attribute_by_lDAPDisplayName(ac->schema, rc->el[i].name);
if (!schema_attr) {
@@ -330,11 +294,11 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
}
attr_name = target_attr->lDAPDisplayName;
- /* make sure we manage each value */
+ /* Now we know what was there, we can remove it for the re-add */
for (j = 0; j < search_el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&search_el->values[j],
- attr_name, dn);
+ attr_name);
if (ret != LDB_SUCCESS) {
talloc_free(ares);
return ldb_module_done(ac->req,
@@ -353,10 +317,20 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
talloc_free(ares);
- /* Start with the original request */
- ret = la_down_req(ac);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
+ if (ac->req->operation == LDB_ADD) {
+ /* Start the modifies to the backlinks */
+ ret = la_do_mod_request(ac);
+
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+ } else {
+ /* Start with the original request */
+ ret = la_down_req(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
}
return LDB_SUCCESS;
}
@@ -377,6 +351,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
int i, j;
struct la_context *ac;
struct ldb_request *search_req;
+ const char **attrs;
+
int ret;
if (ldb_dn_is_special(req->op.mod.message->dn)) {
@@ -394,12 +370,15 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
return ldb_next_request(module, req);
}
- ac->rc = NULL;
+ ac->rc = talloc_zero(ac, struct replace_context);
+ if (!ac->rc) {
+ ldb_oom(module->ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
for (i=0; i < req->op.mod.message->num_elements; i++) {
bool store_el = false;
const char *attr_name;
- const char *attr_val;
const struct dsdb_attribute *target_attr;
const struct ldb_message_element *el = &req->op.mod.message->elements[i];
const struct dsdb_attribute *schema_attr
@@ -437,8 +416,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
}
attr_name = target_attr->lDAPDisplayName;
- attr_val = ldb_dn_get_linearized(ac->req->op.mod.message->dn);
-
+
switch (el->flags & LDB_FLAG_MOD_MASK) {
case LDB_FLAG_MOD_REPLACE:
/* treat as just a normal add the delete part is handled by the callback */
@@ -452,7 +430,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_ADD,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -466,7 +444,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&el->values[j],
- attr_name, attr_val);
+ attr_name);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -484,15 +462,6 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
if (store_el) {
struct ldb_message_element *search_el;
- /* Fill out ac->rc only if we have to find the old values */
- if (!ac->rc) {
- ac->rc = talloc_zero(ac, struct replace_context);
- if (!ac->rc) {
- ldb_oom(module->ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- }
-
search_el = talloc_realloc(ac->rc, ac->rc->el,
struct ldb_message_element,
ac->rc->num_elements +1);
@@ -506,25 +475,21 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
ac->rc->num_elements++;
}
}
-
- /* both replace and delete without values are handled in the callback
- * after the search on the entry to be modified is performed */
-
- /* Only bother doing a search of this entry (to find old
- * values) if replace or delete operations are attempted */
- if (ac->rc) {
- const char **attrs;
-
- attrs = talloc_array(ac->rc, const char *, ac->rc->num_elements +1);
+
+ if (ac->ops || ac->rc->el) {
+ /* both replace and delete without values are handled in the callback
+ * after the search on the entry to be modified is performed */
+
+ attrs = talloc_array(ac->rc, const char *, ac->rc->num_elements + 1);
if (!attrs) {
ldb_oom(module->ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- for (i = 0; i < ac->rc->num_elements; i++) {
+ for (i = 0; ac->rc && i < ac->rc->num_elements; i++) {
attrs[i] = ac->rc->el[i].name;
}
attrs[i] = NULL;
-
+
/* The callback does all the hard work here */
ret = ldb_build_search_req(&search_req, module->ldb, ac,
req->op.mod.message->dn,
@@ -534,32 +499,31 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
ac, la_mod_search_callback,
req);
+ /* We need to figure out our own extended DN, to fill in as the backlink target */
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
if (ret == LDB_SUCCESS) {
talloc_steal(search_req, attrs);
-
+
ret = ldb_next_request(module, search_req);
}
-
} else {
- if (ac->ops) {
- /* Start with the original request */
- ret = la_down_req(ac);
- } else {
- /* nothing to do for this module, proceed */
- talloc_free(ac);
- ret = ldb_next_request(module, req);
- }
+ /* nothing to do for this module, proceed */
+ talloc_free(ac);
+ ret = ldb_next_request(module, req);
}
return ret;
}
/* delete, rename */
-static int linked_attributes_op(struct ldb_module *module, struct ldb_request *req)
+static int linked_attributes_del(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_request *search_req;
- struct ldb_dn *base_dn;
struct la_context *ac;
const char **attrs;
WERROR werr;
@@ -574,17 +538,6 @@ static int linked_attributes_op(struct ldb_module *module, struct ldb_request *r
- Regain our sainity
*/
- switch (req->operation) {
- case LDB_RENAME:
- base_dn = req->op.rename.olddn;
- break;
- case LDB_DELETE:
- base_dn = req->op.del.dn;
- break;
- default:
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
ac = linked_attributes_init(module, req);
if (!ac) {
return LDB_ERR_OPERATIONS_ERROR;
@@ -601,7 +554,7 @@ static int linked_attributes_op(struct ldb_module *module, struct ldb_request *r
}
ret = ldb_build_search_req(&search_req, module->ldb, req,
- base_dn, LDB_SCOPE_BASE,
+ req->op.del.dn, LDB_SCOPE_BASE,
"(objectClass=*)", attrs,
NULL,
ac, la_op_search_callback,
@@ -616,6 +569,35 @@ static int linked_attributes_op(struct ldb_module *module, struct ldb_request *r
return ldb_next_request(module, search_req);
}
+/* delete, rename */
+static int linked_attributes_rename(struct ldb_module *module, struct ldb_request *req)
+{
+ struct la_context *ac;
+
+ /* This gets complex: We need to:
+ - Do a search for the entry
+ - Wait for these result to appear
+ - In the callback for the result, issue a modify
+ request based on the linked attributes found
+ - Wait for each modify result
+ - Regain our sainity
+ */
+
+ ac = linked_attributes_init(module, req);
+ if (!ac) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ if (!ac->schema) {
+ /* without schema, this doesn't make any sense */
+ return ldb_next_request(module, req);
+ }
+
+ /* start with the original request */
+ return la_down_req(ac);
+}
+
+
static int la_op_search_callback(struct ldb_request *req,
struct ldb_reply *ares)
{
@@ -624,8 +606,6 @@ static int la_op_search_callback(struct ldb_request *req,
const struct dsdb_attribute *target_attr;
const struct ldb_message_element *el;
const char *attr_name;
- const char *deldn;
- const char *adddn;
int i, j;
int ret;
@@ -659,15 +639,16 @@ static int la_op_search_callback(struct ldb_request *req,
switch (ac->req->operation) {
case LDB_DELETE:
- deldn = ldb_dn_get_linearized(ac->req->op.del.dn);
- adddn = NULL;
+ ac->del_dn = talloc_steal(ac, ares->message->dn);
break;
case LDB_RENAME:
- deldn = ldb_dn_get_linearized(ac->req->op.rename.olddn);
- adddn = ldb_dn_get_linearized(ac->req->op.rename.newdn);
+ ac->add_dn = talloc_steal(ac, ares->message->dn);
+ ac->del_dn = talloc_steal(ac, ac->req->op.rename.olddn);
break;
default:
talloc_free(ares);
+ ldb_set_errstring(ac->module->ldb,
+ "operations must be delete or rename");
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
@@ -708,16 +689,15 @@ static int la_op_search_callback(struct ldb_request *req,
for (j = 0; j < el->num_values; j++) {
ret = la_store_op(ac, LA_OP_DEL,
&el->values[j],
- attr_name, deldn);
- if (ret != LDB_SUCCESS) {
- talloc_free(ares);
- return ldb_module_done(ac->req,
- NULL, NULL, ret);
+ attr_name);
+
+ /* for renames, ensure we add it back */
+ if (ret == LDB_SUCCESS
+ && ac->req->operation == LDB_RENAME) {
+ ret = la_store_op(ac, LA_OP_ADD,
+ &el->values[j],
+ attr_name);
}
- if (!adddn) continue;
- ret = la_store_op(ac, LA_OP_ADD,
- &el->values[j],
- attr_name, adddn);
if (ret != LDB_SUCCESS) {
talloc_free(ares);
return ldb_module_done(ac->req,
@@ -736,10 +716,31 @@ static int la_op_search_callback(struct ldb_request *req,
talloc_free(ares);
- /* start the mod requests chain */
- ret = la_down_req(ac);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
+
+ switch (ac->req->operation) {
+ case LDB_DELETE:
+ /* start the mod requests chain */
+ ret = la_down_req(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL, ret);
+ }
+ break;
+ case LDB_RENAME:
+
+ ret = la_do_mod_request(ac);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ return ret;
+
+ default:
+ talloc_free(ares);
+ ldb_set_errstring(ac->module->ldb,
+ "operations must be delete or rename");
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
}
return LDB_SUCCESS;
}
@@ -757,6 +758,12 @@ static int la_do_mod_request(struct la_context *ac)
struct ldb_context *ldb;
int ret;
+ /* If we have no modifies in the queue, we are done! */
+ if (!ac->ops) {
+ return ldb_module_done(ac->req, ac->op_controls,
+ ac->op_response, LDB_SUCCESS);
+ }
+
ldb = ac->module->ldb;
/* Create the modify request */
@@ -765,10 +772,7 @@ static int la_do_mod_request(struct la_context *ac)
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- new_msg->dn = ldb_dn_copy(new_msg, ac->ops->dn);
- if (!new_msg->dn) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ new_msg->dn = ac->ops->dn;
if (ac->ops->op == LA_OP_ADD) {
ret = ldb_msg_add_empty(new_msg, ac->ops->name,
@@ -785,8 +789,19 @@ static int la_do_mod_request(struct la_context *ac)
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
}
- ret_el->values[0] = data_blob_string_const(ac->ops->value);
ret_el->num_values = 1;
+ if (ac->ops->op == LA_OP_ADD) {
+ ret_el->values[0] = data_blob_string_const(ldb_dn_get_extended_linearized(new_msg, ac->add_dn, 1));
+ } else {
+ ret_el->values[0] = data_blob_string_const(ldb_dn_get_extended_linearized(new_msg, ac->del_dn, 1));
+ }
+
+#if 0
+ ldb_debug(ac->module->ldb, LDB_DEBUG_WARNING,
+ "link on %s %s: %s %s\n",
+ ldb_dn_get_linearized(new_msg->dn), ret_el->name,
+ ret_el->values[0].data, ac->ops->op == LA_OP_ADD ? "added" : "deleted");
+#endif
/* use ac->ops as the mem_ctx so that the request will be freed
* in the callback as soon as completed */
@@ -808,7 +823,6 @@ static int la_mod_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct la_context *ac;
struct la_op_store *os;
- int ret;
ac = talloc_get_type(req->context, struct la_context);
@@ -831,30 +845,180 @@ static int la_mod_callback(struct ldb_request *req, struct ldb_reply *ares)
talloc_free(ares);
- if (ac->ops) {
- os = ac->ops;
- ac->ops = os->next;
+ os = ac->ops;
+ DLIST_REMOVE(ac->ops, os);
+
+ /* this frees the request too
+ * DO NOT access 'req' after this point */
+ talloc_free(os);
- /* this frees the request too
- * DO NOT access 'req' after this point */
- talloc_free(os);
+ return la_do_mod_request(ac);
+}
+
+/* Having done the original operation, then try to fix up all the linked attributes for modify and delete */
+static int la_mod_del_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
}
- /* If we still have modifies in the queue, then run them */
- if (ac->ops) {
- ret = la_do_mod_request(ac);
- } else {
- /* Otherwise, we are done! */
- ret = ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
}
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+ /* If we have modfies to make, this is the time to do them for modify and delete */
+ ret = la_do_mod_request(ac);
+
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
+ talloc_free(ares);
+
+ /* la_do_mod_request has already sent the callbacks */
return LDB_SUCCESS;
+
+}
+
+/* Having done the original rename try to fix up all the linked attributes */
+static int la_rename_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ struct ldb_request *search_req;
+ const char **attrs;
+ WERROR werr;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ werr = dsdb_linked_attribute_lDAPDisplayName_list(ac->schema, ac, &attrs);
+ if (!W_ERROR_IS_OK(werr)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_search_req(&search_req, ac->module->ldb, req,
+ ac->req->op.rename.newdn, LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs,
+ NULL,
+ ac, la_op_search_callback,
+ req);
+
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ talloc_steal(search_req, attrs);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+
+ return ldb_next_request(ac->module, search_req);
+}
+
+/* Having done the original add, then try to fix up all the linked attributes
+
+ This is done after the add so the links can get the extended DNs correctly.
+ */
+static int la_add_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+ int ret;
+ struct la_context *ac;
+ ac = talloc_get_type(req->context, struct la_context);
+
+ if (!ares) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ ldb_set_errstring(ac->module->ldb,
+ "invalid ldb_reply_type in callback");
+ talloc_free(ares);
+ return ldb_module_done(ac->req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ac->ops) {
+ struct ldb_request *search_req;
+ static const char *attrs[] = { NULL };
+
+ /* The callback does all the hard work here - we need
+ * the objectGUID and SID of the added record */
+ ret = ldb_build_search_req(&search_req, ac->module->ldb, ac,
+ ac->req->op.add.message->dn,
+ LDB_SCOPE_BASE,
+ "(objectClass=*)", attrs,
+ NULL,
+ ac, la_mod_search_callback,
+ ac->req);
+
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_request_add_control(search_req,
+ LDB_CONTROL_EXTENDED_DN_OID,
+ false, NULL);
+ }
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+
+ ac->op_controls = talloc_steal(ac, ares->controls);
+ ac->op_response = talloc_steal(ac, ares->response);
+
+ return ldb_next_request(ac->module, search_req);
+
+ } else {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
}
+/* Reconstruct the original request, but pointing at our local callback to finish things off */
static int la_down_req(struct la_context *ac)
{
struct ldb_request *down_req;
@@ -865,21 +1029,21 @@ static int la_down_req(struct la_context *ac)
ret = ldb_build_add_req(&down_req, ac->module->ldb, ac,
ac->req->op.add.message,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_add_callback,
ac->req);
break;
case LDB_MODIFY:
ret = ldb_build_mod_req(&down_req, ac->module->ldb, ac,
ac->req->op.mod.message,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_mod_del_callback,
ac->req);
break;
case LDB_DELETE:
ret = ldb_build_del_req(&down_req, ac->module->ldb, ac,
ac->req->op.del.dn,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_mod_del_callback,
ac->req);
break;
case LDB_RENAME:
@@ -887,7 +1051,7 @@ static int la_down_req(struct la_context *ac)
ac->req->op.rename.olddn,
ac->req->op.rename.newdn,
ac->req->controls,
- ac, la_down_callback,
+ ac, la_rename_callback,
ac->req);
break;
default:
@@ -900,42 +1064,11 @@ static int la_down_req(struct la_context *ac)
return ldb_next_request(ac->module, down_req);
}
-/* Having done the original operation, then try to fix up all the linked attributes */
-static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct la_context *ac;
-
- ac = talloc_get_type(req->context, struct la_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- if (ares->type != LDB_REPLY_DONE) {
- ldb_set_errstring(ac->module->ldb,
- "invalid ldb_reply_type in callback");
- talloc_free(ares);
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- /* If we have modfies to make, then run them */
- if (ac->ops) {
- return la_do_mod_request(ac);
- } else {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-}
_PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {
.name = "linked_attributes",
.add = linked_attributes_add,
.modify = linked_attributes_modify,
- .del = linked_attributes_op,
- .rename = linked_attributes_op,
+ .del = linked_attributes_del,
+ .rename = linked_attributes_rename,
};
diff --git a/source4/dsdb/samdb/ldb_modules/local_password.c b/source4/dsdb/samdb/ldb_modules/local_password.c
index 622e444166..55d895791a 100644
--- a/source4/dsdb/samdb/ldb_modules/local_password.c
+++ b/source4/dsdb/samdb/ldb_modules/local_password.c
@@ -47,7 +47,8 @@
Each incoming add/modify is split into a remote, and a local request, done in that order.
- We maintain a list of attributes that are kept locally:
+ We maintain a list of attributes that are kept locally - perhaps
+ this should use the @KLUDGE_ACL list of passwordAttribute
*/
static const char * const password_attrs[] = {
@@ -819,7 +820,7 @@ static int lpdb_local_search_callback(struct ldb_request *req,
/* free the rest */
talloc_free(ares);
- return ldb_module_send_entry(ac->req, merge->message);
+ return ldb_module_send_entry(ac->req, merge->message, merge->controls);
case LDB_REPLY_REFERRAL:
/* ignore */
@@ -832,7 +833,7 @@ static int lpdb_local_search_callback(struct ldb_request *req,
/* if this entry was not returned yet, return it now */
if (lr->remote) {
- ret = ldb_module_send_entry(ac->req, ac->remote->message);
+ ret = ldb_module_send_entry(ac->req, ac->remote->message, ac->remote->controls);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req,
NULL, NULL, ret);
@@ -898,7 +899,7 @@ static int lpdb_remote_search_callback(struct ldb_request *req,
ldb_msg_remove_attr(ares->message, "objectClass");
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
}
if (ldb_msg_find_ldb_val(ares->message, "objectGUID") == NULL) {
diff --git a/source4/dsdb/samdb/ldb_modules/normalise.c b/source4/dsdb/samdb/ldb_modules/normalise.c
deleted file mode 100644
index 2366bc7856..0000000000
--- a/source4/dsdb/samdb/ldb_modules/normalise.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- ldb database library
-
- Copyright (C) Amdrew Bartlett <abartlet@samba.org> 2007-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/>.
-*/
-
-/*
- * Name: ldb
- *
- * Component: ldb normalisation module
- *
- * Description: module to ensure all DNs and attribute names are normalised
- *
- * Author: Andrew Bartlett
- */
-
-#include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_errors.h"
-#include "ldb/include/ldb_private.h"
-#include "dsdb/samdb/samdb.h"
-
-/* Fix up the DN to be in the standard form, taking particular care to match the parent DN
-
- This should mean that if the parent is:
- CN=Users,DC=samba,DC=example,DC=com
- and a proposed child is
- cn=Admins ,cn=USERS,dc=Samba,dc=example,dc=COM
-
- The resulting DN should be:
-
- CN=Admins,CN=Users,DC=samba,DC=example,DC=com
-
- */
-
-struct norm_context {
- struct ldb_module *module;
- struct ldb_request *req;
-
- const struct dsdb_schema *schema;
-};
-
-static int fix_dn(struct ldb_dn *dn)
-{
- int i, ret;
- char *upper_rdn_attr;
-
- for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
- /* We need the attribute name in upper case */
- upper_rdn_attr = strupper_talloc(dn,
- ldb_dn_get_component_name(dn, i));
- if (!upper_rdn_attr) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* And replace it with CN=foo (we need the attribute in upper case */
- ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
- *ldb_dn_get_component_val(dn, i));
- talloc_free(upper_rdn_attr);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- }
- return LDB_SUCCESS;
-}
-
-static int normalize_search_callback(struct ldb_request *req, struct ldb_reply *ares)
-{
- struct ldb_message *msg;
- struct norm_context *ac;
- int i, j, ret;
-
- ac = talloc_get_type(req->context, struct norm_context);
-
- if (!ares) {
- return ldb_module_done(ac->req, NULL, NULL,
- LDB_ERR_OPERATIONS_ERROR);
- }
- if (ares->error != LDB_SUCCESS) {
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- /* Only entries are interesting, and we handle the case of the parent seperatly */
-
- switch (ares->type) {
- case LDB_REPLY_ENTRY:
-
- /* OK, we have one of *many* search results passing by here,
- * but we should get them one at a time */
- msg = ares->message;
-
- ret = fix_dn(msg->dn);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
- }
-
- for (i = 0; i < msg->num_elements; i++) {
- const struct dsdb_attribute *attribute = dsdb_attribute_by_lDAPDisplayName(ac->schema, msg->elements[i].name);
- if (!attribute) {
- continue;
- }
- /* Look to see if this attributeSyntax is a DN */
- if (!((strcmp(attribute->attributeSyntax_oid, "2.5.5.1") == 0) ||
- (strcmp(attribute->attributeSyntax_oid, "2.5.5.7") == 0))) {
- continue;
- }
- for (j = 0; j < msg->elements[i].num_values; j++) {
- const char *dn_str;
- struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, &msg->elements[i].values[j]);
- if (!dn) {
- return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
- }
- ret = fix_dn(dn);
- if (ret != LDB_SUCCESS) {
- return ldb_module_done(ac->req, NULL, NULL, ret);
- }
- dn_str = talloc_steal(msg->elements[i].values, ldb_dn_get_linearized(dn));
- msg->elements[i].values[j] = data_blob_string_const(dn_str);
- talloc_free(dn);
- }
- }
-
- return ldb_module_send_entry(ac->req, msg);
-
- case LDB_REPLY_REFERRAL:
-
- return ldb_module_send_referral(ac->req, ares->referral);
-
- case LDB_REPLY_DONE:
-
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
- }
-
- return LDB_SUCCESS;
-}
-
-/* search */
-static int normalise_search(struct ldb_module *module, struct ldb_request *req)
-{
- struct ldb_request *down_req;
- struct norm_context *ac;
- int ret;
-
- ac = talloc(req, struct norm_context);
- if (ac == NULL) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ac->module = module;
- ac->req = req;
-
- /* if schema not yet present just skip over */
- ac->schema = dsdb_get_schema(ac->module->ldb);
- if (ac->schema == NULL) {
- talloc_free(ac);
- return ldb_next_request(module, req);
- }
-
- ret = ldb_build_search_req_ex(&down_req, module->ldb, ac,
- req->op.search.base,
- req->op.search.scope,
- req->op.search.tree,
- req->op.search.attrs,
- req->controls,
- ac, normalize_search_callback,
- req);
- if (ret != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- return ldb_next_request(module, down_req);
-}
-
-
-
-_PUBLIC_ const struct ldb_module_ops ldb_normalise_module_ops = {
- .name = "normalise",
- .search = normalise_search,
-};
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 2a321e29c5..0d2ce64604 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -186,7 +186,7 @@ static int partition_req_callback(struct ldb_request *req,
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_DONE:
if (ares->error == LDB_SUCCESS) {
@@ -895,6 +895,14 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque
return ret;
}
+ ret = ldb_request_add_control(treq,
+ DSDB_CONTROL_CURRENT_PARTITION_OID,
+ false, data->partitions[i]);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(res);
+ return ret;
+ }
+
ret = partition_request(data->partitions[i]->module, treq);
if (ret != LDB_SUCCESS) {
talloc_free(res);
diff --git a/source4/dsdb/samdb/ldb_modules/proxy.c b/source4/dsdb/samdb/ldb_modules/proxy.c
index 2ff42297b7..23116be9ac 100644
--- a/source4/dsdb/samdb/ldb_modules/proxy.c
+++ b/source4/dsdb/samdb/ldb_modules/proxy.c
@@ -280,7 +280,7 @@ static int proxy_search_callback(struct ldb_request *req,
ac->count++;
#endif
proxy_convert_record(ac->module->ldb, proxy, ares->message);
- ret = ldb_module_send_entry(ac->req, ares->message);
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
break;
case LDB_REPLY_REFERRAL:
diff --git a/source4/dsdb/samdb/ldb_modules/ranged_results.c b/source4/dsdb/samdb/ldb_modules/ranged_results.c
index b8e43a7e88..eeb161bdde 100644
--- a/source4/dsdb/samdb/ldb_modules/ranged_results.c
+++ b/source4/dsdb/samdb/ldb_modules/ranged_results.c
@@ -164,7 +164,7 @@ static int rr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
}
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
}
/* search */
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index b38e182cf7..461a554ec0 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -278,7 +278,7 @@ static int rootdse_callback(struct ldb_request *req, struct ldb_reply *ares)
return ldb_module_done(ac->req, NULL, NULL, ret);
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
/* should we allow the backend to return referrals in this case
@@ -301,8 +301,7 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
int ret;
/* see if its for the rootDSE - only a base search on the "" DN qualifies */
- if (req->op.search.scope != LDB_SCOPE_BASE ||
- ( ! ldb_dn_is_null(req->op.search.base))) {
+ if (!(req->op.search.scope == LDB_SCOPE_BASE && ldb_dn_is_null(req->op.search.base))) {
/* Otherwise, pass down to the rest of the stack */
return ldb_next_request(module, req);
}
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 95a16b5527..7ecc41d2c3 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -346,13 +346,14 @@ static int samldb_get_parent_domain_callback(struct ldb_request *req,
}
nextRid = ldb_msg_find_attr_as_string(ares->message,
- "nextRid", NULL);
+ "nextRid", NULL);
if (nextRid == NULL) {
ldb_asprintf_errstring(ac->module->ldb,
- "attribute nextRid not found in %s\n",
- ldb_dn_get_linearized(ares->message->dn));
+ "while looking for domain above %s attribute nextRid not found in %s\n",
+ ldb_dn_get_linearized(ac->req->op.add.message->dn),
+ ldb_dn_get_linearized(ares->message->dn));
ret = LDB_ERR_OPERATIONS_ERROR;
- break;;
+ break;
}
ac->next_rid = strtol(nextRid, NULL, 0);
@@ -369,6 +370,7 @@ static int samldb_get_parent_domain_callback(struct ldb_request *req,
talloc_free(ares);
ret = LDB_SUCCESS;
+ ldb_reset_err_string(ac->module->ldb);
break;
case LDB_REPLY_REFERRAL:
@@ -1067,8 +1069,8 @@ static int samldb_foreign_notice_sid_callback(struct ldb_request *req,
"nextRid", NULL);
if (nextRid == NULL) {
ldb_asprintf_errstring(ac->module->ldb,
- "attribute nextRid not found in %s\n",
- ldb_dn_get_linearized(ares->message->dn));
+ "while looking for forign sid %s attribute nextRid not found in %s\n",
+ dom_sid_string(ares, ac->sid), ldb_dn_get_linearized(ares->message->dn));
ret = LDB_ERR_OPERATIONS_ERROR;
break;
}
@@ -1118,6 +1120,7 @@ static int samldb_foreign_notice_sid(struct samldb_ctx *ac)
{
static const char * const attrs[3] = { "nextRid", "name", NULL };
struct ldb_request *req;
+ NTSTATUS status;
char *filter;
int ret;
@@ -1125,12 +1128,10 @@ static int samldb_foreign_notice_sid(struct samldb_ctx *ac)
return LDB_ERR_OPERATIONS_ERROR;
}
- ac->domain_sid = dom_sid_dup(ac, ac->sid);
- if (!ac->domain_sid) {
+ status = dom_sid_split_rid(ac, ac->sid, &ac->domain_sid, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
return LDB_ERR_OPERATIONS_ERROR;
}
- /* get the domain component part of the provided SID */
- ac->domain_sid->num_auths--;
filter = talloc_asprintf(ac, "(&(objectSid=%s)(objectclass=domain))",
ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index df409a8ae3..bfcf239f3a 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -406,7 +406,7 @@ static int schema_fsmo_search_callback(struct ldb_request *req, struct ldb_reply
case LDB_REPLY_ENTRY:
if (ldb_dn_compare(ares->message->dn, mc->aggregate_dn) != 0) {
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
}
for (i=0; i < ARRAY_SIZE(generated_attrs); i++) {
@@ -418,7 +418,7 @@ static int schema_fsmo_search_callback(struct ldb_request *req, struct ldb_reply
}
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
diff --git a/source4/dsdb/samdb/ldb_modules/show_deleted.c b/source4/dsdb/samdb/ldb_modules/show_deleted.c
index 0e3b46debe..0914e51ebe 100644
--- a/source4/dsdb/samdb/ldb_modules/show_deleted.c
+++ b/source4/dsdb/samdb/ldb_modules/show_deleted.c
@@ -64,7 +64,7 @@ static int show_deleted_search_callback(struct ldb_request *req,
switch (ares->type) {
case LDB_REPLY_ENTRY:
- return ldb_module_send_entry(ar->req, ares->message);
+ return ldb_module_send_entry(ar->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
return ldb_module_send_referral(ar->req, ares->referral);
diff --git a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
index c353914e2c..0e42f7869a 100644
--- a/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
+++ b/source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
@@ -44,7 +44,7 @@ struct entryuuid_private {
static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct GUID guid;
- NTSTATUS status = GUID_from_string((char *)val->data, &guid);
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
enum ndr_err_code ndr_err;
struct ldb_val out = data_blob(NULL, 0);
@@ -62,27 +62,13 @@ static struct ldb_val encode_guid(struct ldb_module *module, TALLOC_CTX *ctx, co
static struct ldb_val guid_always_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
- struct GUID *guid;
struct ldb_val out = data_blob(NULL, 0);
- if (val->length >= 32 && val->data[val->length] == '\0') {
- ldb_handler_copy(module->ldb, ctx, val, &out);
- } else {
- enum ndr_err_code ndr_err;
-
- guid = talloc(ctx, struct GUID);
- if (guid == NULL) {
- return out;
- }
- ndr_err = ndr_pull_struct_blob(val, guid, NULL, guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(guid);
- return out;
- }
- out = data_blob_string_const(GUID_string(ctx, guid));
- talloc_free(guid);
+ struct GUID guid;
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return out;
}
- return out;
+ return data_blob_string_const(GUID_string(ctx, &guid));
}
static struct ldb_val encode_ns_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
@@ -107,27 +93,12 @@ static struct ldb_val encode_ns_guid(struct ldb_module *module, TALLOC_CTX *ctx,
static struct ldb_val guid_ns_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
struct ldb_val out = data_blob(NULL, 0);
- if (val->length >= 32 && val->data[val->length] == '\0') {
- struct GUID guid;
- GUID_from_string((char *)val->data, &guid);
- out = data_blob_string_const(NS_GUID_string(ctx, &guid));
- } else {
- enum ndr_err_code ndr_err;
- struct GUID *guid_p;
- guid_p = talloc(ctx, struct GUID);
- if (guid_p == NULL) {
- return out;
- }
- ndr_err = ndr_pull_struct_blob(val, guid_p, NULL, guid_p,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(guid_p);
- return out;
- }
- out = data_blob_string_const(NS_GUID_string(ctx, guid_p));
- talloc_free(guid_p);
+ struct GUID guid;
+ NTSTATUS status = GUID_from_data_blob(val, &guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return out;
}
- return out;
+ return data_blob_string_const(NS_GUID_string(ctx, &guid));
}
/* The backend holds binary sids, so just copy them back */
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 93068d66ef..efc467865c 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -59,6 +59,11 @@ struct dsdb_control_current_partition {
#define DSDB_CONTROL_REPLICATED_UPDATE_OID "1.3.6.1.4.1.7165.4.3.3"
/* DSDB_CONTROL_REPLICATED_UPDATE_OID has NULL data */
+#define DSDB_CONTROL_DN_STORAGE_FORMAT_OID "1.3.6.1.4.1.7165.4.3.4"
+/* DSDB_CONTROL_DN_STORAGE_FORMAT_OID has NULL data and behaves very
+ * much like LDB_CONTROL_EXTENDED_DN_OID when the DB stores an
+ * extended DN, and otherwise returns normal DNs */
+
#define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1"
struct dsdb_extended_replicated_object {
struct ldb_message *msg;
@@ -100,4 +105,26 @@ struct dsdb_pdc_fsmo {
*/
#define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2"
+#define DSDB_OPENLDAP_DEREFERENCE_CONTROL "1.3.6.1.4.1.4203.666.5.16"
+
+struct dsdb_openldap_dereference {
+ const char *source_attribute;
+ const char **dereference_attribute;
+};
+
+struct dsdb_openldap_dereference_control {
+ struct dsdb_openldap_dereference **dereference;
+};
+
+struct dsdb_openldap_dereference_result {
+ const char *source_attribute;
+ const char *dereferenced_dn;
+ int num_attributes;
+ struct ldb_message_element *attributes;
+};
+
+struct dsdb_openldap_dereference_result_control {
+ struct dsdb_openldap_dereference_result **attributes;
+};
+
#endif /* __SAMDB_H__ */
diff --git a/source4/headermap.txt b/source4/headermap.txt
index c906282a31..d5e70a7304 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -24,26 +24,6 @@ libcli/util/werror.h: core/werror.h
libcli/util/doserr.h: core/doserr.h
libcli/util/ntstatus.h: core/ntstatus.h
libcli/cldap/cldap.h: cldap.h
-librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h
-librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h
-librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h
-librpc/gen_ndr/ndr_dcerpc.h: gen_ndr/ndr_dcerpc.h
-librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h
-librpc/gen_ndr/ndr_mgmt.h: gen_ndr/ndr_mgmt.h
-librpc/gen_ndr/ndr_mgmt_c.h: gen_ndr/ndr_mgmt_c.h
-librpc/gen_ndr/epmapper.h: gen_ndr/epmapper.h
-librpc/gen_ndr/ndr_epmapper.h: gen_ndr/ndr_epmapper.h
-librpc/gen_ndr/ndr_epmapper_c.h: gen_ndr/ndr_epmapper_c.h
-librpc/gen_ndr/ndr_atsvc.h: gen_ndr/ndr_atsvc.h
-librpc/gen_ndr/atsvc.h: gen_ndr/atsvc.h
-librpc/gen_ndr/ndr_atsvc_c.h: gen_ndr/ndr_atsvc_c.h
-librpc/gen_ndr/misc.h: gen_ndr/misc.h
-librpc/gen_ndr/lsa.h: gen_ndr/lsa.h
-librpc/gen_ndr/samr.h: gen_ndr/samr.h
-librpc/gen_ndr/ndr_samr.h: gen_ndr/ndr_samr.h
-librpc/gen_ndr/ndr_samr_c.h: gen_ndr/ndr_samr_c.h
-librpc/gen_ndr/security.h: gen_ndr/security.h
-librpc/gen_ndr/dom_sid.h: gen_ndr/dom_sid.h
auth/credentials/credentials.h: credentials.h
auth/credentials/credentials_krb5.h: credentials/krb5.h
rpc_server/dcerpc_server.h: dcerpc_server.h
@@ -53,11 +33,7 @@ libcli/auth/credentials.h: domain_credentials.h
libcli/ldap/ldap.h: ldap-util.h
../lib/torture/torture.h: torture.h
libcli/libcli.h: client.h
-librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
librpc/gen_ndr/ntp_signd.h: gen_ndr/ntp_signd.h
-librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h
-librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h
-librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h
lib/cmdline/popt_common.h: samba/popt.h
../lib/util/dlinklist.h: dlinklist.h
../lib/util/data_blob.h: util/data_blob.h
@@ -69,7 +45,6 @@ param/param.h: param.h
lib/tdb_wrap.h: tdb_wrap.h
lib/ldb_wrap.h: ldb_wrap.h
torture/smbtorture.h: smbtorture.h
-librpc/gen_ndr/winbind.h: gen_ndr/winbind.h
param/share.h: share.h
../lib/util/util_tdb.h: util_tdb.h
../lib/util/util_ldb.h: util_ldb.h
@@ -79,5 +54,57 @@ lib/events/events_internal.h: events/events_internal.h
libcli/ldap/ldap_ndr.h: ldap_ndr.h
lib/events/events.h: events.h
lib/events/events_internal.h: events_internal.h
+../lib/tevent/tevent.h: tevent.h
+../lib/tevent/tevent_internal.h: tevent_internal.h
auth/session.h: samba/session.h
../talloc/talloc.h: talloc.h
+
+# pidl generated files
+# we need some of them with and without '../'
+librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h
+librpc/gen_ndr/ndr_dcerpc.h: gen_ndr/ndr_dcerpc.h
+librpc/gen_ndr/winbind.h: gen_ndr/winbind.h
+librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h
+librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h
+librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h
+librpc/gen_ndr/ndr_mgmt.h: gen_ndr/ndr_mgmt.h
+librpc/gen_ndr/ndr_mgmt_c.h: gen_ndr/ndr_mgmt_c.h
+librpc/gen_ndr/epmapper.h: gen_ndr/epmapper.h
+librpc/gen_ndr/ndr_epmapper.h: gen_ndr/ndr_epmapper.h
+librpc/gen_ndr/ndr_epmapper_c.h: gen_ndr/ndr_epmapper_c.h
+librpc/gen_ndr/ndr_atsvc.h: gen_ndr/ndr_atsvc.h
+librpc/gen_ndr/atsvc.h: gen_ndr/atsvc.h
+librpc/gen_ndr/ndr_atsvc_c.h: gen_ndr/ndr_atsvc_c.h
+librpc/gen_ndr/misc.h: gen_ndr/misc.h
+librpc/gen_ndr/lsa.h: gen_ndr/lsa.h
+librpc/gen_ndr/samr.h: gen_ndr/samr.h
+librpc/gen_ndr/ndr_samr.h: gen_ndr/ndr_samr.h
+librpc/gen_ndr/ndr_samr_c.h: gen_ndr/ndr_samr_c.h
+librpc/gen_ndr/security.h: gen_ndr/security.h
+librpc/gen_ndr/server_id.h: gen_ndr/server_id.h
+librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
+librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h
+librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h
+librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h
+../librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h
+../librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h
+../librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h
+../librpc/gen_ndr/ndr_mgmt.h: gen_ndr/ndr_mgmt.h
+../librpc/gen_ndr/ndr_mgmt_c.h: gen_ndr/ndr_mgmt_c.h
+../librpc/gen_ndr/epmapper.h: gen_ndr/epmapper.h
+../librpc/gen_ndr/ndr_epmapper.h: gen_ndr/ndr_epmapper.h
+../librpc/gen_ndr/ndr_epmapper_c.h: gen_ndr/ndr_epmapper_c.h
+../librpc/gen_ndr/ndr_atsvc.h: gen_ndr/ndr_atsvc.h
+../librpc/gen_ndr/atsvc.h: gen_ndr/atsvc.h
+../librpc/gen_ndr/ndr_atsvc_c.h: gen_ndr/ndr_atsvc_c.h
+../librpc/gen_ndr/misc.h: gen_ndr/misc.h
+../librpc/gen_ndr/lsa.h: gen_ndr/lsa.h
+../librpc/gen_ndr/samr.h: gen_ndr/samr.h
+../librpc/gen_ndr/ndr_samr.h: gen_ndr/ndr_samr.h
+../librpc/gen_ndr/ndr_samr_c.h: gen_ndr/ndr_samr_c.h
+../librpc/gen_ndr/security.h: gen_ndr/security.h
+../librpc/gen_ndr/server_id.h: gen_ndr/server_id.h
+../librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
+../librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h
+../librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h
+../librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 2adff2a1df..a091c1d11e 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -159,6 +159,8 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
struct ldb_request *lreq;
struct ldb_control *search_control;
struct ldb_search_options_control *search_options;
+ struct ldb_control *extended_dn_control;
+ struct ldb_extended_dn_control *extended_dn_decoded = NULL;
enum ldb_scope scope = LDB_SCOPE_DEFAULT;
const char **attrs = NULL;
const char *scope_str, *errstr = NULL;
@@ -166,6 +168,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
int result = -1;
int ldb_ret = -1;
int i, j;
+ int extended_type = 1;
DEBUG(10, ("SearchRequest"));
DEBUGADD(10, (" basedn: %s", req->basedn));
@@ -245,6 +248,18 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
ldb_request_add_control(lreq, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options);
}
}
+
+ extended_dn_control = ldb_request_get_control(lreq, LDB_CONTROL_EXTENDED_DN_OID);
+
+ if (extended_dn_control) {
+ if (extended_dn_control->data) {
+ extended_dn_decoded = talloc_get_type(extended_dn_control->data, struct ldb_extended_dn_control);
+ extended_type = extended_dn_decoded->type;
+ } else {
+ extended_type = 0;
+ }
+ }
+
ldb_set_timeout(samdb, lreq, req->timelimit);
ldb_ret = ldb_request(samdb, lreq);
@@ -266,7 +281,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
talloc_steal(ent_r, res->msgs[i]);
ent = &ent_r->msg->r.SearchResultEntry;
- ent->dn = ldb_dn_alloc_linearized(ent_r, res->msgs[i]->dn);
+ ent->dn = ldb_dn_get_extended_linearized(ent_r, res->msgs[i]->dn, extended_type);
ent->num_attributes = 0;
ent->attributes = NULL;
if (res->msgs[i]->num_elements == 0) {
diff --git a/source4/lib/events/Makefile.in b/source4/lib/events/Makefile.in
deleted file mode 100644
index 4257119849..0000000000
--- a/source4/lib/events/Makefile.in
+++ /dev/null
@@ -1,81 +0,0 @@
-#!gmake
-#
-# Makefile for tdb directory
-#
-
-CC = @CC@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-includedir = @includedir@
-libdir = @libdir@
-VPATH = @srcdir@:@libreplacedir@
-srcdir = @srcdir@
-builddir = @builddir@
-sharedbuilddir = @sharedbuilddir@
-INSTALLCMD = @INSTALL@
-CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I.
-LDFLAGS = @LDFLAGS@
-EXEEXT = @EXEEXT@
-SHLD = @SHLD@
-SHLD_FLAGS = @SHLD_FLAGS@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PICFLAG = @PICFLAG@
-SHLIBEXT = @SHLIBEXT@
-SWIG = swig
-PYTHON = @PYTHON@
-PYTHON_CONFIG = @PYTHON_CONFIG@
-PYTHON_BUILD_TARGET = @PYTHON_BUILD_TARGET@
-PYTHON_INSTALL_TARGET = @PYTHON_INSTALL_TARGET@
-PYTHON_CHECK_TARGET = @PYTHON_CHECK_TARGET@
-LIB_PATH_VAR = @LIB_PATH_VAR@
-eventsdir = @eventsdir@
-
-TALLOC_CFLAGS = @TALLOC_CFLAGS@
-TALLOC_LDFLAGS = @TALLOC_CFLAGS@
-TALLOC_LIBS = @TALLOC_LIBS@
-
-EVENTS_CFLAGS = @EVENTS_CFLAGS@
-EVENTS_LDFLAGS = @EVENTS_CFLAGS@
-EVENTS_LIBS = @EVENTS_LIBS@
-
-CFLAGS = $(CPPFLAGS) $(TALLOC_CFLAGS) $(EVENTS_CFLAGS) @CFLAGS@
-LDFLAGS = $(TALLOC_LDFLAGS) $(EVENTS_LDFLAGS) @LDFLAGS@
-LIBS = $(TALLOC_LIBS) $(EVENTS_LIBS) @LIBS@
-
-EVENTS_OBJ = @EVENTS_OBJ@ @LIBREPLACEOBJ@
-
-default: all
-
-include $(eventsdir)/events.mk
-include $(eventsdir)/rules.mk
-
-all:: showflags dirs $(PROGS) $(EVENTS_SOLIB) libevents.a $(PYTHON_BUILD_TARGET)
-
-install:: all
-$(EVENTS_SOLIB): $(EVENTS_OBJ)
- $(SHLD) $(SHLD_FLAGS) $(LDFLAGS) $(LIBS) -o $@ $(EVENTS_OBJ) @SONAMEFLAG@$(EVENTS_SONAME)
-
-shared-build: all
- ${INSTALLCMD} -d $(sharedbuilddir)/lib
- ${INSTALLCMD} -m 644 libevents.a $(sharedbuilddir)/lib
- ${INSTALLCMD} -m 755 $(EVENTS_SOLIB) $(sharedbuilddir)/lib
- ln -sf $(EVENTS_SOLIB) $(sharedbuilddir)/lib/$(EVENTS_SONAME)
- ln -sf $(EVENTS_SOLIB) $(sharedbuilddir)/lib/libevents.so
- ${INSTALLCMD} -d $(sharedbuilddir)/include
- ${INSTALLCMD} -m 644 $(srcdir)/events.h $(sharedbuilddir)/include
-
-check: test
-
-test:: $(PYTHON_CHECK_TARGET)
-installcheck:: test install
-
-clean::
- rm -f *.o *.a */*.o
-
-distclean:: clean
- rm -f config.log config.status include/config.h config.cache
- rm -f Makefile
-
-realdistclean:: distclean
- rm -f configure include/config.h.in
diff --git a/source4/lib/events/autogen.sh b/source4/lib/events/autogen.sh
deleted file mode 100755
index fec05f54d4..0000000000
--- a/source4/lib/events/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"
-autoconf $IPATHS || exit 1
-autoheader $IPATHS || exit 1
-
-rm -rf autom4te.cache
-
-swig -O -Wall -python -keyword events.i # Ignore errors for now
-
-echo "Now run ./configure and then make."
-exit 0
-
diff --git a/source4/lib/events/build_macros.m4 b/source4/lib/events/build_macros.m4
deleted file mode 100644
index c036668cd1..0000000000
--- a/source4/lib/events/build_macros.m4
+++ /dev/null
@@ -1,14 +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"
- LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib"
- fi
- AC_SUBST(sharedbuilddir)
- ])
-
diff --git a/source4/lib/events/config.mk b/source4/lib/events/config.mk
index 127d964775..b9d6879b3c 100644
--- a/source4/lib/events/config.mk
+++ b/source4/lib/events/config.mk
@@ -1,58 +1,7 @@
-##############################
-[MODULE::EVENTS_AIO]
-PRIVATE_DEPENDENCIES = LIBAIO_LINUX
-SUBSYSTEM = LIBEVENTS
-INIT_FUNCTION = s4_events_aio_init
-##############################
-
-EVENTS_AIO_OBJ_FILES = $(libeventssrcdir)/events_aio.o
-
-##############################
-[MODULE::EVENTS_EPOLL]
-SUBSYSTEM = LIBEVENTS
-INIT_FUNCTION = s4_events_epoll_init
-##############################
-
-EVENTS_EPOLL_OBJ_FILES = $(libeventssrcdir)/events_epoll.o
-
-##############################
-[MODULE::EVENTS_SELECT]
-SUBSYSTEM = LIBEVENTS
-INIT_FUNCTION = s4_events_select_init
-##############################
-
-EVENTS_SELECT_OBJ_FILES = $(libeventssrcdir)/events_select.o
-
-##############################
-[MODULE::EVENTS_STANDARD]
-SUBSYSTEM = LIBEVENTS
-INIT_FUNCTION = s4_events_standard_init
-##############################
-
-EVENTS_STANDARD_OBJ_FILES = $(libeventssrcdir)/events_standard.o
-
-################################################
-# Start SUBSYSTEM LIBEVENTS
-[LIBRARY::LIBEVENTS]
-PUBLIC_DEPENDENCIES = LIBTALLOC
-OUTPUT_TYPE = MERGED_OBJ
+[SUBSYSTEM::LIBEVENTS]
+PUBLIC_DEPENDENCIES = LIBTEVENT
CFLAGS = -Ilib/events
-#
-# End SUBSYSTEM LIBEVENTS
-################################################
-LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events.o events_timed.o events_signal.o events_debug.o events_util.o events_s4.o)
+LIBEVENTS_OBJ_FILES = $(addprefix $(libeventssrcdir)/, events_dummy.o)
PUBLIC_HEADERS += $(addprefix $(libeventssrcdir)/, events.h events_internal.h)
-
-[PYTHON::swig_events]
-LIBRARY_REALNAME = samba/_events.$(SHLIBEXT)
-PRIVATE_DEPENDENCIES = LIBEVENTS LIBSAMBA-HOSTCONFIG LIBSAMBA-UTIL
-
-swig_events_OBJ_FILES = $(libeventssrcdir)/events_wrap.o
-
-$(eval $(call python_py_module_template,samba/events.py,$(libeventssrcdir)/events.py))
-
-$(swig_events_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
-
-PC_FILES += $(libeventssrcdir)/events.pc
diff --git a/source4/lib/events/configure.ac b/source4/lib/events/configure.ac
deleted file mode 100644
index 895f2a1daa..0000000000
--- a/source4/lib/events/configure.ac
+++ /dev/null
@@ -1,40 +0,0 @@
-AC_PREREQ(2.50)
-AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
-AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
-AC_DEFUN([SMB_ENABLE], [echo -n ""])
-AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
-AC_INIT(events, 1.0.0)
-AC_CONFIG_SRCDIR([events.c])
-AC_CONFIG_HEADER(config.h)
-AC_LIBREPLACE_ALL_CHECKS
-
-AC_LD_EXPORT_DYNAMIC
-AC_LD_SONAMEFLAG
-AC_LD_PICFLAG
-AC_LD_SHLIBEXT
-AC_LIBREPLACE_SHLD
-AC_LIBREPLACE_SHLD_FLAGS
-AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR
-
-m4_include(build_macros.m4)
-BUILD_WITH_SHARED_BUILD_DIR
-
-m4_include(pkg.m4)
-m4_include(libtalloc.m4)
-
-m4_include(libevents.m4)
-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_INSTALL_TARGET=""
- PYTHON_CHECK_TARGET=""
-fi
-AC_OUTPUT(Makefile events.pc)
diff --git a/source4/lib/events/events.c b/source4/lib/events/events.c
deleted file mode 100644
index 52699d968e..0000000000
--- a/source4/lib/events/events.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- main select loop and event handling
- Copyright (C) Andrew Tridgell 2003
-
- 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/>.
-*/
-
-/*
- PLEASE READ THIS BEFORE MODIFYING!
-
- This module is a general abstraction for the main select loop and
- event handling. Do not ever put any localised hacks in here, instead
- register one of the possible event types and implement that event
- somewhere else.
-
- There are 2 types of event handling that are handled in this module:
-
- 1) a file descriptor becoming readable or writeable. This is mostly
- used for network sockets, but can be used for any type of file
- descriptor. You may only register one handler for each file
- descriptor/io combination or you will get unpredictable results
- (this means that you can have a handler for read events, and a
- separate handler for write events, but not two handlers that are
- both handling read events)
-
- 2) a timed event. You can register an event that happens at a
- specific time. You can register as many of these as you
- like. They are single shot - add a new timed event in the event
- handler to get another event.
-
- To setup a set of events you first need to create a event_context
- structure using the function event_context_init(); This returns a
- 'struct event_context' that you use in all subsequent calls.
-
- After that you can add/remove events that you are interested in
- using event_add_*() and talloc_free()
-
- Finally, you call event_loop_wait_once() to block waiting for one of the
- events to occor or event_loop_wait() which will loop
- forever.
-
-*/
-#include "replace.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-
-struct event_ops_list {
- struct event_ops_list *next, *prev;
- const char *name;
- const struct event_ops *ops;
-};
-
-/* list of registered event backends */
-static struct event_ops_list *event_backends = NULL;
-static char *event_default_backend = NULL;
-
-/*
- register an events backend
-*/
-bool event_register_backend(const char *name, const struct event_ops *ops)
-{
- struct event_ops_list *e;
-
- for (e = event_backends; e != NULL; e = e->next) {
- if (0 == strcmp(e->name, name)) {
- /* already registered, skip it */
- return true;
- }
- }
-
- e = talloc(talloc_autofree_context(), struct event_ops_list);
- if (e == NULL) return false;
-
- e->name = name;
- e->ops = ops;
- DLIST_ADD(event_backends, e);
-
- return true;
-}
-
-/*
- set the default event backend
- */
-void event_set_default_backend(const char *backend)
-{
- if (event_default_backend) free(event_default_backend);
- event_default_backend = strdup(backend);
-}
-
-/*
- initialise backends if not already done
-*/
-static void event_backend_init(void)
-{
- events_select_init();
- events_standard_init();
-#if HAVE_EVENTS_EPOLL
- events_epoll_init();
-#endif
-#if HAVE_LINUX_AIO
- events_aio_init();
-#endif
-}
-
-/*
- list available backends
-*/
-const char **event_backend_list(TALLOC_CTX *mem_ctx)
-{
- const char **list = NULL;
- struct event_ops_list *e;
-
- event_backend_init();
-
- for (e=event_backends;e;e=e->next) {
- list = ev_str_list_add(list, e->name);
- }
-
- talloc_steal(mem_ctx, list);
-
- return list;
-}
-
-/*
- create a event_context structure for a specific implemementation.
- This must be the first events call, and all subsequent calls pass
- this event_context as the first element. Event handlers also
- receive this as their first argument.
-
- This function is for allowing third-party-applications to hook in gluecode
- to their own event loop code, so that they can make async usage of our client libs
-
- NOTE: use event_context_init() inside of samba!
-*/
-static struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx,
- const struct event_ops *ops)
-{
- struct event_context *ev;
- int ret;
-
- ev = talloc_zero(mem_ctx, struct event_context);
- if (!ev) return NULL;
-
- ev->ops = ops;
-
- ret = ev->ops->context_init(ev);
- if (ret != 0) {
- talloc_free(ev);
- return NULL;
- }
-
- return ev;
-}
-
-/*
- create a event_context structure. This must be the first events
- call, and all subsequent calls pass this event_context as the first
- element. Event handlers also receive this as their first argument.
-*/
-struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name)
-{
- struct event_ops_list *e;
-
- event_backend_init();
-
- if (name == NULL) {
- name = event_default_backend;
- }
- if (name == NULL) {
- name = "standard";
- }
-
- for (e=event_backends;e;e=e->next) {
- if (strcmp(name, e->name) == 0) {
- return event_context_init_ops(mem_ctx, e->ops);
- }
- }
- return NULL;
-}
-
-
-/*
- create a event_context structure. This must be the first events
- call, and all subsequent calls pass this event_context as the first
- element. Event handlers also receive this as their first argument.
-*/
-struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
-{
- return event_context_init_byname(mem_ctx, NULL);
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-
- if flags contains EVENT_FD_AUTOCLOSE then the fd will be closed when
- the returned fd_event context is freed
-*/
-struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags, event_fd_handler_t handler,
- void *private_data)
-{
- return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
-}
-
-/*
- add a disk aio event
-*/
-struct aio_event *event_add_aio(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data)
-{
- if (ev->ops->add_aio == NULL) return NULL;
- return ev->ops->add_aio(ev, mem_ctx, iocb, handler, private_data);
-}
-
-/*
- return the fd event flags
-*/
-uint16_t event_get_fd_flags(struct fd_event *fde)
-{
- if (!fde) return 0;
- return fde->event_ctx->ops->get_fd_flags(fde);
-}
-
-/*
- set the fd event flags
-*/
-void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- if (!fde) return;
- fde->event_ctx->ops->set_fd_flags(fde, flags);
-}
-
-/*
- add a timed event
- return NULL on failure
-*/
-struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data)
-{
- return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
-}
-
-/*
- add a signal event
-
- sa_flags are flags to sigaction(2)
-
- return NULL on failure
-*/
-struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- event_signal_handler_t handler,
- void *private_data)
-{
- return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data);
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-int event_loop_once(struct event_context *ev)
-{
- return ev->ops->loop_once(ev);
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-int event_loop_wait(struct event_context *ev)
-{
- return ev->ops->loop_wait(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 event_context *event_context_find(TALLOC_CTX *mem_ctx)
-{
- struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
- if (ev == NULL) {
- ev = event_context_init(mem_ctx);
- }
- return ev;
-}
diff --git a/source4/lib/events/events.h b/source4/lib/events/events.h
index 1ece49697f..d2e81f5279 100644
--- a/source4/lib/events/events.h
+++ b/source4/lib/events/events.h
@@ -1,98 +1 @@
-/*
- Unix SMB/CIFS implementation.
-
- generalised event loop handling
-
- Copyright (C) Andrew Tridgell 2005
-
- 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 __EVENTS_H__
-#define __EVENTS_H__
-
-#include <stdint.h>
-#include <talloc.h>
-
-struct event_context;
-struct event_ops;
-struct fd_event;
-struct timed_event;
-struct aio_event;
-struct signal_event;
-
-/* event handler types */
-typedef void (*event_fd_handler_t)(struct event_context *, struct fd_event *,
- uint16_t , void *);
-typedef void (*event_timed_handler_t)(struct event_context *, struct timed_event *,
- struct timeval , void *);
-typedef void (*event_signal_handler_t)(struct event_context *, struct signal_event *,
- int , int, void *, void *);
-typedef void (*event_aio_handler_t)(struct event_context *, struct aio_event *,
- int, void *);
-
-#ifdef _SAMBA_BUILD_
-struct event_context *s4_event_context_init(TALLOC_CTX *mem_ctx);
-#endif
-
-struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
-struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
-const char **event_backend_list(TALLOC_CTX *mem_ctx);
-void event_set_default_backend(const char *backend);
-
-struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags, event_fd_handler_t handler,
- void *private_data);
-
-struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data);
-
-struct signal_event *event_add_signal(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int signum, int sa_flags,
- event_signal_handler_t handler,
- void *private_data);
-
-struct iocb;
-struct aio_event *event_add_aio(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data);
-
-int event_loop_once(struct event_context *ev);
-int event_loop_wait(struct event_context *ev);
-
-uint16_t event_get_fd_flags(struct fd_event *fde);
-void event_set_fd_flags(struct fd_event *fde, uint16_t flags);
-
-struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
-
-/* bits for file descriptor event flags */
-#define EVENT_FD_READ 1
-#define EVENT_FD_WRITE 2
-#define EVENT_FD_AUTOCLOSE 4
-
-#define EVENT_FD_WRITEABLE(fde) \
- event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
-#define EVENT_FD_READABLE(fde) \
- event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
-
-#define EVENT_FD_NOT_WRITEABLE(fde) \
- event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
-#define EVENT_FD_NOT_READABLE(fde) \
- event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
-
-#endif /* __EVENTS_H__ */
+#include <tevent.h>
diff --git a/source4/lib/events/events.i b/source4/lib/events/events.i
deleted file mode 100644
index 8a0d9c4b6f..0000000000
--- a/source4/lib/events/events.i
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- 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/>.
-*/
-
-%module(docstring="Event management.",package="samba.events") events;
-
-%import "../../../lib/talloc/talloc.i";
-
-%{
-#include "events.h"
-typedef struct event_context event;
-%}
-
-typedef struct event_context {
- %extend {
- %feature("docstring") event "S.__init__()";
- event(TALLOC_CTX *mem_ctx) { return event_context_init(mem_ctx); }
- %feature("docstring") loop_once "S.loop_once() -> int";
- int loop_once(void);
- %feature("docstring") loop_wait "S.loop_wait() -> int";
- int loop_wait(void);
- }
-} event;
-%talloctype(event);
-
-%typemap(default,noblock=1) struct event_context * {
- $1 = event_context_init(NULL);
-}
-
-%typemap(default,noblock=1) struct event_context * {
- $1 = event_context_init(NULL);
-}
-
-struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
-
-%feature("docstring") event_backend_list "event_backend_list() -> list";
-const char **event_backend_list(TALLOC_CTX *mem_ctx);
-%feature("docstring") event_set_default_backend "event_set_default_backend(name) -> None";
-%rename(set_default_backend) event_set_default_backend;
-void event_set_default_backend(const char *backend);
diff --git a/source4/lib/events/events.mk b/source4/lib/events/events.mk
deleted file mode 100644
index 2bc6221689..0000000000
--- a/source4/lib/events/events.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-
-EVENTS_SONAME = libevents.$(SHLIBEXT).0
-EVENTS_SOLIB = libevents.$(SHLIBEXT).$(PACKAGE_VERSION)
-
-libevents.a: $(EVENTS_OBJ)
- ar -rv libevents.a $(EVENTS_OBJ)
-
-libevents.$(SHLIBEXT): $(EVENTS_SOLIB)
- ln -fs $< $@
-
-$(EVENTS_SONAME): $(EVENTS_SOLIB)
- ln -fs $< $@
-
-dirs::
- @mkdir -p lib
-
-installdirs::
- mkdir -p $(DESTDIR)$(includedir)
- mkdir -p $(DESTDIR)$(libdir)
- mkdir -p $(DESTDIR)$(libdir)/pkgconfig
-
-installheaders:: installdirs
- cp $(srcdir)/events.h $(DESTDIR)$(includedir)
-
-installlibs:: installdirs
- cp events.pc $(DESTDIR)$(libdir)/pkgconfig
- cp libevents.a $(EVENTS_SOLIB) $(DESTDIR)$(libdir)
-
-install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET)
-
-clean::
- rm -f $(EVENTS_SONAME) $(EVENTS_SOLIB) libevents.a libevents.$(SHLIBEXT)
- rm -f events.pc
- rm -f _libevents.$(SHLIBEXT)
-
-
-#python stuff
-
-check-python:: build-python
- $(LIB_PATH_VAR)=. PYTHONPATH=".:$(eventsdir)" $(PYTHON) $(eventsdir)/python/tests/simple.py
-
-install-swig::
- mkdir -p $(DESTDIR)`$(SWIG) -swiglib`
- cp events.i $(DESTDIR)`$(SWIG) -swiglib`
-
-build-python:: _libevents.$(SHLIBEXT)
-
-events_wrap.o: $(eventsdir)/events_wrap.c
- $(CC) $(PICFLAG) -c $(eventsdir)/events_wrap.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-
-_libevents.$(SHLIBEXT): libevents.$(SHLIBEXT) events_wrap.o
- $(SHLD) $(SHLD_FLAGS) -o $@ events_wrap.o -L. -levents `$(PYTHON_CONFIG) --libs`
-
-install-python:: build-python
- mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"` \
- $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
- cp $(eventsdir)/events.py $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(0, prefix='$(prefix)')"`
- cp _libevents.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
-
diff --git a/source4/lib/events/events.pc.in b/source4/lib/events/events.pc.in
deleted file mode 100644
index 4a4c012d73..0000000000
--- a/source4/lib/events/events.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: events
-Description: An event system library
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -levents
-Cflags: -I${includedir}
-URL: http://samba.org/
diff --git a/source4/lib/events/events.py b/source4/lib/events/events.py
deleted file mode 100644
index c15ea8b9e5..0000000000
--- a/source4/lib/events/events.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 1.3.36
-#
-# Don't modify this file, modify the SWIG interface instead.
-
-"""
-Event management.
-"""
-
-import _events
-import new
-new_instancemethod = new.instancemethod
-try:
- _swig_property = property
-except NameError:
- pass # Python < 2.2 doesn't have 'property'.
-def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
- if (name == "thisown"): return self.this.own(value)
- if (name == "this"):
- if type(value).__name__ == 'PySwigObject':
- self.__dict__[name] = value
- return
- method = class_type.__swig_setmethods__.get(name,None)
- if method: return method(self,value)
- if (not static) or hasattr(self,name):
- self.__dict__[name] = value
- else:
- raise AttributeError("You cannot add attributes to %s" % self)
-
-def _swig_setattr(self,class_type,name,value):
- return _swig_setattr_nondynamic(self,class_type,name,value,0)
-
-def _swig_getattr(self,class_type,name):
- if (name == "thisown"): return self.this.own()
- method = class_type.__swig_getmethods__.get(name,None)
- if method: return method(self)
- raise AttributeError,name
-
-def _swig_repr(self):
- try: strthis = "proxy of " + self.this.__repr__()
- except: strthis = ""
- return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
-
-import types
-try:
- _object = types.ObjectType
- _newclass = 1
-except AttributeError:
- class _object : pass
- _newclass = 0
-del types
-
-
-def _swig_setattr_nondynamic_method(set):
- def set_attr(self,name,value):
- if (name == "thisown"): return self.this.own(value)
- if hasattr(self,name) or (name == "this"):
- set(self,name,value)
- else:
- raise AttributeError("You cannot add attributes to %s" % self)
- return set_attr
-
-
-class event(object):
- thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
- __repr__ = _swig_repr
- def __init__(self, *args, **kwargs):
- """S.__init__()"""
- _events.event_swiginit(self,_events.new_event(*args, **kwargs))
- def loop_once(*args, **kwargs):
- """S.loop_once() -> int"""
- return _events.event_loop_once(*args, **kwargs)
-
- def loop_wait(*args, **kwargs):
- """S.loop_wait() -> int"""
- return _events.event_loop_wait(*args, **kwargs)
-
- __swig_destroy__ = _events.delete_event
-event.loop_once = new_instancemethod(_events.event_loop_once,None,event)
-event.loop_wait = new_instancemethod(_events.event_loop_wait,None,event)
-event_swigregister = _events.event_swigregister
-event_swigregister(event)
-
-event_context_init_byname = _events.event_context_init_byname
-
-def event_backend_list(*args):
- """event_backend_list() -> list"""
- return _events.event_backend_list(*args)
-
-def set_default_backend(*args, **kwargs):
- """event_set_default_backend(name) -> None"""
- return _events.set_default_backend(*args, **kwargs)
-
-
diff --git a/source4/lib/events/events_aio.c b/source4/lib/events/events_aio.c
deleted file mode 100644
index e30213acbc..0000000000
--- a/source4/lib/events/events_aio.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- main select loop and event handling - aio/epoll hybrid implementation
-
- Copyright (C) Andrew Tridgell 2006
-
- based on events_standard.c
-
- 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/>.
-*/
-/*
- this is a very strange beast. The Linux AIO implementation doesn't
- yet integrate properly with epoll, but there is a kernel patch that
- allows the aio wait primitives to be used to wait for epoll events,
- and this can be used to give us a unified event system incorporating
- both aio events and epoll events
-
- this is _very_ experimental code
-*/
-
-#include "system/filesys.h"
-#include "replace.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-#include <sys/epoll.h>
-#include <libaio.h>
-
-#define MAX_AIO_QUEUE_DEPTH 100
-#ifndef IOCB_CMD_EPOLL_WAIT
-#define IOCB_CMD_EPOLL_WAIT 9
-#endif
-
-struct aio_event_context {
- /* a pointer back to the generic event_context */
- struct event_context *ev;
-
- /* list of filedescriptor events */
- struct fd_event *fd_events;
-
- /* number of registered fd event handlers */
- int num_fd_events;
-
- uint32_t destruction_count;
-
- io_context_t ioctx;
-
- struct epoll_event epevent[MAX_AIO_QUEUE_DEPTH];
-
- struct iocb *epoll_iocb;
-
- int epoll_fd;
- int is_epoll_set;
- pid_t pid;
-};
-
-struct aio_event {
- struct event_context *event_ctx;
- struct iocb iocb;
- void *private_data;
- event_aio_handler_t handler;
-};
-
-/*
- map from EVENT_FD_* to EPOLLIN/EPOLLOUT
-*/
-static uint32_t epoll_map_flags(uint16_t flags)
-{
- uint32_t ret = 0;
- if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
- if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
- return ret;
-}
-
-/*
- free the epoll fd
-*/
-static int aio_ctx_destructor(struct aio_event_context *aio_ev)
-{
- io_queue_release(aio_ev->ioctx);
- close(aio_ev->epoll_fd);
- aio_ev->epoll_fd = -1;
- return 0;
-}
-
-static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde);
-
-/*
- reopen the epoll handle when our pid changes
- see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
- demonstration of why this is needed
- */
-static void epoll_check_reopen(struct aio_event_context *aio_ev)
-{
- struct fd_event *fde;
-
- if (aio_ev->pid == getpid()) {
- return;
- }
-
- close(aio_ev->epoll_fd);
- aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH);
- if (aio_ev->epoll_fd == -1) {
- ev_debug(aio_ev->ev, EV_DEBUG_FATAL, "Failed to recreate epoll handle after fork\n");
- return;
- }
- aio_ev->pid = getpid();
- for (fde=aio_ev->fd_events;fde;fde=fde->next) {
- epoll_add_event(aio_ev, fde);
- }
-}
-
-#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
-#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
-#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
-
-/*
- add the epoll event to the given fd_event
-*/
-static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (aio_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if we don't want events yet, don't add an aio_event */
- if (fde->flags == 0) return;
-
- memset(&event, 0, sizeof(event));
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event);
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-/*
- delete the epoll event for given fd_event
-*/
-static void epoll_del_event(struct aio_event_context *aio_ev, struct fd_event *fde)
-{
- struct epoll_event event;
-
- DLIST_REMOVE(aio_ev->fd_events, fde);
-
- if (aio_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if there's no aio_event, we don't need to delete it */
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-}
-
-/*
- change the epoll event to the given fd_event
-*/
-static void epoll_mod_event(struct aio_event_context *aio_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (aio_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- epoll_ctl(aio_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event);
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-static void epoll_change_event(struct aio_event_context *aio_ev, struct fd_event *fde)
-{
- bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
-
- if (aio_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* there's already an event */
- if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
- if (want_read || (want_write && !got_error)) {
- epoll_mod_event(aio_ev, fde);
- return;
- }
- epoll_del_event(aio_ev, fde);
- return;
- }
-
- /* there's no aio_event attached to the fde */
- if (want_read || (want_write && !got_error)) {
- DLIST_ADD(aio_ev->fd_events, fde);
- epoll_add_event(aio_ev, fde);
- return;
- }
-}
-
-static int setup_epoll_wait(struct aio_event_context *aio_ev)
-{
- if (aio_ev->is_epoll_set) {
- return 0;
- }
- memset(aio_ev->epoll_iocb, 0, sizeof(*aio_ev->epoll_iocb));
- aio_ev->epoll_iocb->aio_fildes = aio_ev->epoll_fd;
- aio_ev->epoll_iocb->aio_lio_opcode = IOCB_CMD_EPOLL_WAIT;
- aio_ev->epoll_iocb->aio_reqprio = 0;
-
- aio_ev->epoll_iocb->u.c.nbytes = MAX_AIO_QUEUE_DEPTH;
- aio_ev->epoll_iocb->u.c.offset = -1;
- aio_ev->epoll_iocb->u.c.buf = aio_ev->epevent;
-
- if (io_submit(aio_ev->ioctx, 1, &aio_ev->epoll_iocb) != 1) {
- return -1;
- }
- aio_ev->is_epoll_set = 1;
-
- return 0;
-}
-
-
-/*
- event loop handling using aio/epoll hybrid
-*/
-static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tvalp)
-{
- int ret, i;
- uint32_t destruction_count = ++aio_ev->destruction_count;
- struct timespec timeout;
- struct io_event events[8];
-
- if (aio_ev->epoll_fd == -1) return -1;
-
- if (aio_ev->ev->num_signal_handlers &&
- common_event_check_signal(aio_ev->ev)) {
- return 0;
- }
-
- if (tvalp) {
- timeout.tv_sec = tvalp->tv_sec;
- timeout.tv_nsec = tvalp->tv_usec;
- timeout.tv_nsec *= 1000;
- }
-
- if (setup_epoll_wait(aio_ev) < 0)
- return -1;
-
- ret = io_getevents(aio_ev->ioctx, 1, 8,
- events, tvalp?&timeout:NULL);
-
- if (ret == -EINTR) {
- if (aio_ev->ev->num_signal_handlers) {
- common_event_check_signal(aio_ev->ev);
- }
- return 0;
- }
-
- if (ret == 0 && tvalp) {
- /* we don't care about a possible delay here */
- common_event_loop_timer_delay(aio_ev->ev);
- return 0;
- }
-
- for (i=0;i<ret;i++) {
- struct io_event *event = &events[i];
- struct iocb *finished = event->obj;
-
- switch (finished->aio_lio_opcode) {
- case IO_CMD_PWRITE:
- case IO_CMD_PREAD: {
- struct aio_event *ae = talloc_get_type(finished->data,
- struct aio_event);
- if (ae) {
- talloc_set_destructor(ae, NULL);
- ae->handler(ae->event_ctx, ae,
- event->res, ae->private_data);
- talloc_free(ae);
- }
- break;
- }
- case IOCB_CMD_EPOLL_WAIT: {
- struct epoll_event *ep = (struct epoll_event *)finished->u.c.buf;
- struct fd_event *fde;
- uint16_t flags = 0;
- int j;
-
- aio_ev->is_epoll_set = 0;
-
- for (j=0; j<event->res; j++, ep++) {
- fde = talloc_get_type(ep->data.ptr,
- struct fd_event);
- if (fde == NULL) {
- return -1;
- }
- if (ep->events & (EPOLLHUP|EPOLLERR)) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
- epoll_del_event(aio_ev, fde);
- continue;
- }
- flags |= EVENT_FD_READ;
- }
- if (ep->events & EPOLLIN) flags |= EVENT_FD_READ;
- if (ep->events & EPOLLOUT) flags |= EVENT_FD_WRITE;
- if (flags) {
- fde->handler(aio_ev->ev, fde, flags, fde->private_data);
- }
- }
- break;
- }
- }
- if (destruction_count != aio_ev->destruction_count) {
- return 0;
- }
- }
-
- return 0;
-}
-
-/*
- create a aio_event_context structure.
-*/
-static int aio_event_context_init(struct event_context *ev)
-{
- struct aio_event_context *aio_ev;
-
- aio_ev = talloc_zero(ev, struct aio_event_context);
- if (!aio_ev) return -1;
-
- aio_ev->ev = ev;
- aio_ev->epoll_iocb = talloc(aio_ev, struct iocb);
-
- if (io_queue_init(MAX_AIO_QUEUE_DEPTH, &aio_ev->ioctx) != 0) {
- talloc_free(aio_ev);
- return -1;
- }
-
- aio_ev->epoll_fd = epoll_create(MAX_AIO_QUEUE_DEPTH);
- if (aio_ev->epoll_fd == -1) {
- talloc_free(aio_ev);
- return -1;
- }
- aio_ev->pid = getpid();
-
- talloc_set_destructor(aio_ev, aio_ctx_destructor);
-
- ev->additional_data = aio_ev;
-
- if (setup_epoll_wait(aio_ev) < 0) {
- talloc_free(aio_ev);
- return -1;
- }
-
- return 0;
-}
-
-/*
- destroy an fd_event
-*/
-static int aio_event_fd_destructor(struct fd_event *fde)
-{
- struct event_context *ev = fde->event_ctx;
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
-
- epoll_check_reopen(aio_ev);
-
- aio_ev->num_fd_events--;
- aio_ev->destruction_count++;
-
- epoll_del_event(aio_ev, fde);
-
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
- fde->fd = -1;
- }
-
- return 0;
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-*/
-static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
-{
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
- struct fd_event *fde;
-
- epoll_check_reopen(aio_ev);
-
- fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
- if (!fde) return NULL;
-
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->private_data = private_data;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
-
- aio_ev->num_fd_events++;
- talloc_set_destructor(fde, aio_event_fd_destructor);
-
- DLIST_ADD(aio_ev->fd_events, fde);
- epoll_add_event(aio_ev, fde);
-
- return fde;
-}
-
-
-/*
- return the fd event flags
-*/
-static uint16_t aio_event_get_fd_flags(struct fd_event *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void aio_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- struct event_context *ev;
- struct aio_event_context *aio_ev;
-
- if (fde->flags == flags) return;
-
- ev = fde->event_ctx;
- aio_ev = talloc_get_type(ev->additional_data, struct aio_event_context);
-
- fde->flags = flags;
-
- epoll_check_reopen(aio_ev);
-
- epoll_change_event(aio_ev, fde);
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-static int aio_event_loop_once(struct event_context *ev)
-{
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
- struct timeval tval;
-
- tval = common_event_loop_timer_delay(ev);
- if (ev_timeval_is_zero(&tval)) {
- return 0;
- }
-
- epoll_check_reopen(aio_ev);
-
- return aio_event_loop(aio_ev, &tval);
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-static int aio_event_loop_wait(struct event_context *ev)
-{
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
- while (aio_ev->num_fd_events) {
- if (aio_event_loop_once(ev) != 0) {
- break;
- }
- }
-
- return 0;
-}
-
-/*
- called when a disk IO event needs to be cancelled
-*/
-static int aio_destructor(struct aio_event *ae)
-{
- struct event_context *ev = ae->event_ctx;
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
- struct io_event result;
- io_cancel(aio_ev->ioctx, &ae->iocb, &result);
- /* TODO: handle errors from io_cancel()! */
- return 0;
-}
-
-/* submit an aio disk IO event */
-static struct aio_event *aio_event_add_aio(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data)
-{
- struct aio_event_context *aio_ev = talloc_get_type(ev->additional_data,
- struct aio_event_context);
- struct iocb *iocbp;
- struct aio_event *ae = talloc(mem_ctx?mem_ctx:ev, struct aio_event);
- if (ae == NULL) return NULL;
-
- ae->event_ctx = ev;
- ae->iocb = *iocb;
- ae->handler = handler;
- ae->private_data = private_data;
- iocbp = &ae->iocb;
-
- if (io_submit(aio_ev->ioctx, 1, &iocbp) != 1) {
- talloc_free(ae);
- return NULL;
- }
- ae->iocb.data = ae;
- talloc_set_destructor(ae, aio_destructor);
-
- return ae;
-}
-
-static const struct event_ops aio_event_ops = {
- .context_init = aio_event_context_init,
- .add_fd = aio_event_add_fd,
- .add_aio = aio_event_add_aio,
- .get_fd_flags = aio_event_get_fd_flags,
- .set_fd_flags = aio_event_set_fd_flags,
- .add_timed = common_event_add_timed,
- .add_signal = common_event_add_signal,
- .loop_once = aio_event_loop_once,
- .loop_wait = aio_event_loop_wait,
-};
-
-bool events_aio_init(void)
-{
- return event_register_backend("aio", &aio_event_ops);
-}
-
diff --git a/source4/lib/events/events_debug.c b/source4/lib/events/events_debug.c
deleted file mode 100644
index 233844f024..0000000000
--- a/source4/lib/events/events_debug.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 2005
- Copyright (C) Jelmer Vernooij 2005
-
- 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 "replace.h"
-#include "events.h"
-#include "events_internal.h"
-
-/********************************************************************
- * Debug wrapper functions, modeled (with lot's of code copied as is)
- * after the ev debug wrapper functions
- ********************************************************************/
-
-/*
- this allows the user to choose their own debug function
-*/
-int ev_set_debug(struct event_context *ev,
- void (*debug)(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap),
- void *context)
-{
- ev->debug_ops.debug = debug;
- ev->debug_ops.context = context;
- return 0;
-}
-
-/*
- debug function for ev_set_debug_stderr
-*/
-void ev_debug_stderr(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
-void ev_debug_stderr(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap)
-{
- if (level <= EV_DEBUG_WARNING) {
- vfprintf(stderr, fmt, ap);
- }
-}
-
-/*
- convenience function to setup debug messages on stderr
- messages of level EV_DEBUG_WARNING and higher are printed
-*/
-int ev_set_debug_stderr(struct event_context *ev)
-{
- return ev_set_debug(ev, ev_debug_stderr, ev);
-}
-
-/*
- * log a message
- *
- * The default debug action is to ignore debugging messages.
- * This is the most appropriate action for a library.
- * Applications using the library must decide where to
- * redirect debugging messages
-*/
-void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...)
-{
- va_list ap;
- if (ev->debug_ops.debug == NULL) {
- return;
- }
- va_start(ap, fmt);
- ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap);
- va_end(ap);
-}
-
diff --git a/source4/lib/events/events_dummy.c b/source4/lib/events/events_dummy.c
new file mode 100644
index 0000000000..15bb25e953
--- /dev/null
+++ b/source4/lib/events/events_dummy.c
@@ -0,0 +1,4 @@
+void __events_dummy(void)
+{
+}
+
diff --git a/source4/lib/events/events_epoll.c b/source4/lib/events/events_epoll.c
deleted file mode 100644
index d46d5c2bbc..0000000000
--- a/source4/lib/events/events_epoll.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- main select loop and event handling - epoll implementation
-
- Copyright (C) Andrew Tridgell 2003-2005
- Copyright (C) Stefan Metzmacher 2005
-
- 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 "replace.h"
-#include "system/filesys.h"
-#include "system/network.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-#include <sys/epoll.h>
-
-struct epoll_event_context {
- /* a pointer back to the generic event_context */
- struct event_context *ev;
-
- /* list of filedescriptor events */
- struct fd_event *fd_events;
-
- /* number of registered fd event handlers */
- int num_fd_events;
-
- /* this is changed by the destructors for the fd event
- type. It is used to detect event destruction by event
- handlers, which means the code that is calling the event
- handler needs to assume that the linked list is no longer
- valid
- */
- uint32_t destruction_count;
-
- /* when using epoll this is the handle from epoll_create */
- int epoll_fd;
-
- pid_t pid;
-};
-
-/*
- called when a epoll call fails, and we should fallback
- to using select
-*/
-static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason)
-{
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
- "%s (%s) - calling abort()\n", reason, strerror(errno));
- abort();
-}
-
-/*
- map from EVENT_FD_* to EPOLLIN/EPOLLOUT
-*/
-static uint32_t epoll_map_flags(uint16_t flags)
-{
- uint32_t ret = 0;
- if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
- if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
- return ret;
-}
-
-/*
- free the epoll fd
-*/
-static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev)
-{
- close(epoll_ev->epoll_fd);
- epoll_ev->epoll_fd = -1;
- return 0;
-}
-
-/*
- init the epoll fd
-*/
-static int epoll_init_ctx(struct epoll_event_context *epoll_ev)
-{
- epoll_ev->epoll_fd = epoll_create(64);
- epoll_ev->pid = getpid();
- talloc_set_destructor(epoll_ev, epoll_ctx_destructor);
- if (epoll_ev->epoll_fd == -1) {
- return -1;
- }
- return 0;
-}
-
-static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde);
-
-/*
- reopen the epoll handle when our pid changes
- see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
- demonstration of why this is needed
- */
-static void epoll_check_reopen(struct epoll_event_context *epoll_ev)
-{
- struct fd_event *fde;
-
- if (epoll_ev->pid == getpid()) {
- return;
- }
-
- close(epoll_ev->epoll_fd);
- epoll_ev->epoll_fd = epoll_create(64);
- if (epoll_ev->epoll_fd == -1) {
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
- "Failed to recreate epoll handle after fork\n");
- return;
- }
- epoll_ev->pid = getpid();
- for (fde=epoll_ev->fd_events;fde;fde=fde->next) {
- epoll_add_event(epoll_ev, fde);
- }
-}
-
-#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
-#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
-#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
-
-/*
- add the epoll event to the given fd_event
-*/
-static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
-{
- struct epoll_event event;
-
- if (epoll_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if we don't want events yet, don't add an epoll_event */
- if (fde->flags == 0) return;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
- epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed");
- }
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-/*
- delete the epoll event for given fd_event
-*/
-static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
-{
- struct epoll_event event;
-
- if (epoll_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if there's no epoll_event, we don't need to delete it */
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event) != 0) {
- ev_debug(epoll_ev->ev, EV_DEBUG_FATAL,
- "epoll_del_event failed! probable early close bug (%s)\n",
- strerror(errno));
- }
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-}
-
-/*
- change the epoll event to the given fd_event
-*/
-static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (epoll_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
- epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed");
- }
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-static void epoll_change_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
-{
- bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
-
- if (epoll_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* there's already an event */
- if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
- if (want_read || (want_write && !got_error)) {
- epoll_mod_event(epoll_ev, fde);
- return;
- }
- /*
- * if we want to match the select behavior, we need to remove the epoll_event
- * when the caller isn't interested in events.
- *
- * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
- */
- epoll_del_event(epoll_ev, fde);
- return;
- }
-
- /* there's no epoll_event attached to the fde */
- if (want_read || (want_write && !got_error)) {
- epoll_add_event(epoll_ev, fde);
- return;
- }
-}
-
-/*
- event loop handling using epoll
-*/
-static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp)
-{
- int ret, i;
-#define MAXEVENTS 32
- struct epoll_event events[MAXEVENTS];
- uint32_t destruction_count = ++epoll_ev->destruction_count;
- int timeout = -1;
-
- if (epoll_ev->epoll_fd == -1) return -1;
-
- if (tvalp) {
- /* it's better to trigger timed events a bit later than to early */
- timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
- }
-
- if (epoll_ev->ev->num_signal_handlers &&
- common_event_check_signal(epoll_ev->ev)) {
- return 0;
- }
-
- ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout);
-
- if (ret == -1 && errno == EINTR && epoll_ev->ev->num_signal_handlers) {
- if (common_event_check_signal(epoll_ev->ev)) {
- return 0;
- }
- }
-
- if (ret == -1 && errno != EINTR) {
- epoll_panic(epoll_ev, "epoll_wait() failed");
- return -1;
- }
-
- if (ret == 0 && tvalp) {
- /* we don't care about a possible delay here */
- common_event_loop_timer_delay(epoll_ev->ev);
- return 0;
- }
-
- for (i=0;i<ret;i++) {
- struct fd_event *fde = talloc_get_type(events[i].data.ptr,
- struct fd_event);
- uint16_t flags = 0;
-
- if (fde == NULL) {
- epoll_panic(epoll_ev, "epoll_wait() gave bad data");
- return -1;
- }
- if (events[i].events & (EPOLLHUP|EPOLLERR)) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
- /*
- * if we only wait for EVENT_FD_WRITE, we should not tell the
- * event handler about it, and remove the epoll_event,
- * as we only report errors when waiting for read events,
- * to match the select() behavior
- */
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
- epoll_del_event(epoll_ev, fde);
- continue;
- }
- flags |= EVENT_FD_READ;
- }
- if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
- if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
- if (flags) {
- fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
- if (destruction_count != epoll_ev->destruction_count) {
- break;
- }
- }
- }
-
- return 0;
-}
-
-/*
- create a epoll_event_context structure.
-*/
-static int epoll_event_context_init(struct event_context *ev)
-{
- int ret;
- struct epoll_event_context *epoll_ev;
-
- epoll_ev = talloc_zero(ev, struct epoll_event_context);
- if (!epoll_ev) return -1;
- epoll_ev->ev = ev;
- epoll_ev->epoll_fd = -1;
-
- ret = epoll_init_ctx(epoll_ev);
- if (ret != 0) {
- talloc_free(epoll_ev);
- return ret;
- }
-
- ev->additional_data = epoll_ev;
- return 0;
-}
-
-/*
- destroy an fd_event
-*/
-static int epoll_event_fd_destructor(struct fd_event *fde)
-{
- struct event_context *ev = fde->event_ctx;
- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
- struct epoll_event_context);
-
- epoll_check_reopen(epoll_ev);
-
- epoll_ev->num_fd_events--;
- epoll_ev->destruction_count++;
-
- DLIST_REMOVE(epoll_ev->fd_events, fde);
-
- epoll_del_event(epoll_ev, fde);
-
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
- fde->fd = -1;
- }
-
- return 0;
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-*/
-static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
-{
- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
- struct epoll_event_context);
- struct fd_event *fde;
-
- epoll_check_reopen(epoll_ev);
-
- fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
- if (!fde) return NULL;
-
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->private_data = private_data;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
-
- epoll_ev->num_fd_events++;
- talloc_set_destructor(fde, epoll_event_fd_destructor);
-
- DLIST_ADD(epoll_ev->fd_events, fde);
- epoll_add_event(epoll_ev, fde);
-
- return fde;
-}
-
-
-/*
- return the fd event flags
-*/
-static uint16_t epoll_event_get_fd_flags(struct fd_event *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void epoll_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- struct event_context *ev;
- struct epoll_event_context *epoll_ev;
-
- if (fde->flags == flags) return;
-
- ev = fde->event_ctx;
- epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context);
-
- fde->flags = flags;
-
- epoll_check_reopen(epoll_ev);
-
- epoll_change_event(epoll_ev, fde);
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-static int epoll_event_loop_once(struct event_context *ev)
-{
- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
- struct epoll_event_context);
- struct timeval tval;
-
- tval = common_event_loop_timer_delay(ev);
- if (ev_timeval_is_zero(&tval)) {
- return 0;
- }
-
- epoll_check_reopen(epoll_ev);
-
- return epoll_event_loop(epoll_ev, &tval);
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-static int epoll_event_loop_wait(struct event_context *ev)
-{
- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
- struct epoll_event_context);
- while (epoll_ev->num_fd_events) {
- if (epoll_event_loop_once(ev) != 0) {
- break;
- }
- }
-
- return 0;
-}
-
-static const struct event_ops epoll_event_ops = {
- .context_init = epoll_event_context_init,
- .add_fd = epoll_event_add_fd,
- .get_fd_flags = epoll_event_get_fd_flags,
- .set_fd_flags = epoll_event_set_fd_flags,
- .add_timed = common_event_add_timed,
- .add_signal = common_event_add_signal,
- .loop_once = epoll_event_loop_once,
- .loop_wait = epoll_event_loop_wait,
-};
-
-bool events_epoll_init(void)
-{
- return event_register_backend("epoll", &epoll_event_ops);
-}
diff --git a/source4/lib/events/events_internal.h b/source4/lib/events/events_internal.h
index 0d0755f298..308587ce2f 100644
--- a/source4/lib/events/events_internal.h
+++ b/source4/lib/events/events_internal.h
@@ -1,158 +1 @@
-/*
- Unix SMB/CIFS implementation.
-
- generalised event loop handling
-
- Internal structs
-
- Copyright (C) Stefan Metzmacher 2005
-
- 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/>.
-*/
-
-struct event_ops {
- /* conntext init */
- int (*context_init)(struct event_context *ev);
-
- /* fd_event functions */
- struct fd_event *(*add_fd)(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data);
- uint16_t (*get_fd_flags)(struct fd_event *fde);
- void (*set_fd_flags)(struct fd_event *fde, uint16_t flags);
-
- /* timed_event functions */
- struct timed_event *(*add_timed)(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data);
- /* disk aio event functions */
- struct aio_event *(*add_aio)(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- struct iocb *iocb,
- event_aio_handler_t handler,
- void *private_data);
- /* signal functions */
- struct signal_event *(*add_signal)(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum, int sa_flags,
- event_signal_handler_t handler,
- void *private_data);
-
- /* loop functions */
- int (*loop_once)(struct event_context *ev);
- int (*loop_wait)(struct event_context *ev);
-};
-
-struct fd_event {
- struct fd_event *prev, *next;
- struct event_context *event_ctx;
- int fd;
- uint16_t flags; /* see EVENT_FD_* flags */
- event_fd_handler_t handler;
- /* this is private for the specific handler */
- void *private_data;
- /* this is private for the events_ops implementation */
- uint16_t additional_flags;
- void *additional_data;
-};
-
-struct timed_event {
- struct timed_event *prev, *next;
- struct event_context *event_ctx;
- struct timeval next_event;
- event_timed_handler_t handler;
- /* this is private for the specific handler */
- void *private_data;
- /* this is private for the events_ops implementation */
- void *additional_data;
-};
-
-struct signal_event {
- struct signal_event *prev, *next;
- struct event_context *event_ctx;
- event_signal_handler_t handler;
- void *private_data;
- int signum;
- int sa_flags;
-};
-
-/* DEBUG */
-enum ev_debug_level {EV_DEBUG_FATAL, EV_DEBUG_ERROR,
- EV_DEBUG_WARNING, EV_DEBUG_TRACE};
-
-struct ev_debug_ops {
- void (*debug)(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
- void *context;
-};
-
-int ev_set_debug(struct event_context *ev,
- void (*debug)(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap),
- void *context);
-int ev_set_debug_stderr(struct event_context *ev);
-void ev_debug(struct event_context *ev, enum ev_debug_level level, const char *fmt, ...);
-
-/* aio event is private to the aio backend */
-struct aio_event;
-
-struct event_context {
- /* the specific events implementation */
- const struct event_ops *ops;
-
- /* list of timed events - used by common code */
- struct timed_event *timed_events;
-
- /* this is private for the events_ops implementation */
- void *additional_data;
-
- /* number of signal event handlers */
- int num_signal_handlers;
-
- /* pipe hack used with signal handlers */
- struct fd_event *pipe_fde;
-
- /* debugging operations */
- struct ev_debug_ops debug_ops;
-};
-
-
-bool event_register_backend(const char *name, const struct event_ops *ops);
-
-bool ev_timeval_is_zero(const struct timeval *tv);
-struct timed_event *common_event_add_timed(struct event_context *, TALLOC_CTX *,
- struct timeval, event_timed_handler_t, void *);
-struct timeval common_event_loop_timer_delay(struct event_context *);
-
-struct signal_event *common_event_add_signal(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- event_signal_handler_t handler,
- void *private_data);
-int common_event_check_signal(struct event_context *ev);
-
-
-bool events_standard_init(void);
-bool events_select_init(void);
-#if HAVE_EVENTS_EPOLL
-bool events_epoll_init(void);
-#endif
-#if HAVE_LINUX_AIO
-bool events_aio_init(void);
-#endif
+#include <tevent_internal.h>
diff --git a/source4/lib/events/events_liboop.c b/source4/lib/events/events_liboop.c
deleted file mode 100644
index 339297a3cf..0000000000
--- a/source4/lib/events/events_liboop.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- main select loop and event handling
- wrapper for http://liboop.org/
-
- Copyright (C) Stefan Metzmacher 2005
-
- 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 "events.h"
-#include "events_internal.h"
-
-#include <oop.h>
-
-/*
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- NOTE: this code compiles fine, but is completly *UNTESTED*
- and is only commited as example
-
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-*/
-
-static int oop_event_context_destructor(struct event_context *ev)
-{
- oop_source_sys *oop_sys = ev->additional_data;
-
- oop_sys_delete(oop_sys);
-
- return 0;
-}
-
-/*
- create a oop_event_context structure.
-*/
-static int oop_event_context_init(struct event_context *ev, void *private_data)
-{
- oop_source_sys *oop_sys = private_data;
-
- if (!oop_sys) {
- oop_sys = oop_sys_new();
- if (!oop_sys) {
- return -1;
- }
-
- talloc_set_destructor(ev, oop_event_context_destructor);
- }
-
- ev->additional_data = oop_sys;
-
- return 0;
-}
-
-static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
-{
- struct fd_event *fde = ptr;
-
- if (fd != fde->fd) return OOP_ERROR;
-
- switch(oop_type) {
- case OOP_READ:
- fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
- return OOP_CONTINUE;
- case OOP_WRITE:
- fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
- return OOP_CONTINUE;
- case OOP_EXCEPTION:
- return OOP_ERROR;
- case OOP_NUM_EVENTS:
- return OOP_ERROR;
- }
-
- return OOP_ERROR;
-}
-
-/*
- destroy an fd_event
-*/
-static int oop_event_fd_destructor(struct fd_event *fde)
-{
- struct event_context *ev = fde->event_ctx;
- oop_source_sys *oop_sys = ev->additional_data;
- oop_source *oop = oop_sys_source(oop_sys);
-
- if (fde->flags & EVENT_FD_READ)
- oop->cancel_fd(oop, fde->fd, OOP_READ);
- if (fde->flags & EVENT_FD_WRITE)
- oop->cancel_fd(oop, fde->fd, OOP_WRITE);
-
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
- fde->fd = -1;
- }
-
- return 0;
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-*/
-static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
-{
- struct fd_event *fde;
- oop_source_sys *oop_sys = ev->additional_data;
- oop_source *oop = oop_sys_source(oop_sys);
-
- fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
- if (!fde) return NULL;
-
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->private_data = private_data;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
-
- if (fde->flags & EVENT_FD_READ)
- oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
- if (fde->flags & EVENT_FD_WRITE)
- oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
-
- talloc_set_destructor(fde, oop_event_fd_destructor);
-
- return fde;
-}
-
-/*
- return the fd event flags
-*/
-static uint16_t oop_event_get_fd_flags(struct fd_event *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- oop_source_sys *oop_sys;
- oop_source *oop;
-
- oop_sys = fde->event_ctx->additional_data;
- oop = oop_sys_source(oop_sys);
-
- if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
- oop->cancel_fd(oop, fde->fd, OOP_READ);
-
- if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
- oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
-
- if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
- oop->cancel_fd(oop, fde->fd, OOP_WRITE);
-
- if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
- oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
-
- fde->flags = flags;
-}
-
-static int oop_event_timed_destructor(struct timed_event *te);
-
-static int oop_event_timed_deny_destructor(struct timed_event *te)
-{
- return -1;
-}
-
-static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
-{
- struct timed_event *te = ptr;
-
- /* deny the handler to free the event */
- talloc_set_destructor(te, oop_event_timed_deny_destructor);
- te->handler(te->event_ctx, te, t, te->private_data);
-
- talloc_set_destructor(te, oop_event_timed_destructor);
- talloc_free(te);
-
- return OOP_CONTINUE;
-}
-
-/*
- destroy a timed event
-*/
-static int oop_event_timed_destructor(struct timed_event *te)
-{
- struct event_context *ev = te->event_ctx;
- oop_source_sys *oop_sys = ev->additional_data;
- oop_source *oop = oop_sys_source(oop_sys);
-
- oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
-
- return 0;
-}
-
-/*
- add a timed event
- return NULL on failure (memory allocation error)
-*/
-static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data)
-{
- oop_source_sys *oop_sys = ev->additional_data;
- oop_source *oop = oop_sys_source(oop_sys);
- struct timed_event *te;
-
- te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
- if (te == NULL) return NULL;
-
- te->event_ctx = ev;
- te->next_event = next_event;
- te->handler = handler;
- te->private_data = private_data;
- te->additional_data = NULL;
-
- oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
-
- talloc_set_destructor(te, oop_event_timed_destructor);
-
- return te;
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-static int oop_event_loop_once(struct event_context *ev)
-{
- void *oop_ret;
- oop_source_sys *oop_sys = ev->additional_data;
-
- oop_ret = oop_sys_run_once(oop_sys);
- if (oop_ret == OOP_CONTINUE) {
- return 0;
- }
-
- return -1;
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-static int oop_event_loop_wait(struct event_context *ev)
-{
- void *oop_ret;
- oop_source_sys *oop_sys = ev->additional_data;
-
- oop_ret = oop_sys_run(oop_sys);
- if (oop_ret == OOP_CONTINUE) {
- return 0;
- }
-
- return -1;
-}
-
-static const struct event_ops event_oop_ops = {
- .context_init = oop_event_context_init,
- .add_fd = oop_event_add_fd,
- .get_fd_flags = oop_event_get_fd_flags,
- .set_fd_flags = oop_event_set_fd_flags,
- .add_timed = oop_event_add_timed,
- .add_signal = common_event_add_signal,
- .loop_once = oop_event_loop_once,
- .loop_wait = oop_event_loop_wait,
-};
-
-const struct event_ops *event_liboop_get_ops(void)
-{
- return &event_oop_ops;
-}
diff --git a/source4/lib/events/events_s4.c b/source4/lib/events/events_s4.c
deleted file mode 100644
index 134f899cf8..0000000000
--- a/source4/lib/events/events_s4.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Copyright (C) Andrew Tridgell 2003
-
- 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 "events.h"
-#include "events_internal.h"
-
-NTSTATUS s4_events_standard_init(void)
-{
- if (!events_standard_init()) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-
-NTSTATUS s4_events_select_init(void)
-{
- if (!events_select_init()) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-
-#if HAVE_EVENTS_EPOLL
-NTSTATUS s4_events_epoll_init(void)
-{
- if (!events_epoll_init()) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-#endif
-
-#if HAVE_LINUX_AIO
-NTSTATUS s4_events_aio_init(void)
-{
- if (!events_aio_init()) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-#endif
-
-/*
- this is used to catch debug messages from events
-*/
-static void ev_wrap_debug(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0);
-
-static void ev_wrap_debug(void *context, enum ev_debug_level level,
- const char *fmt, va_list ap)
-{
- int samba_level = -1;
- char *s = NULL;
- switch (level) {
- case EV_DEBUG_FATAL:
- samba_level = 0;
- break;
- case EV_DEBUG_ERROR:
- samba_level = 1;
- break;
- case EV_DEBUG_WARNING:
- samba_level = 2;
- break;
- case EV_DEBUG_TRACE:
- samba_level = 5;
- break;
-
- };
- vasprintf(&s, fmt, ap);
- if (!s) return;
- DEBUG(samba_level, ("events: %s\n", s));
- free(s);
-}
-
-/*
- create a event_context structure. This must be the first events
- call, and all subsequent calls pass this event_context as the first
- element. Event handlers also receive this as their first argument.
-
- This samba4 specific call sets the samba4 debug handler.
-*/
-struct event_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
-{
- struct event_context *ev;
-
- ev = event_context_init_byname(mem_ctx, NULL);
- if (ev) {
- ev_set_debug(ev, ev_wrap_debug, NULL);
- }
- return ev;
-}
-
diff --git a/source4/lib/events/events_select.c b/source4/lib/events/events_select.c
deleted file mode 100644
index 54d32204f5..0000000000
--- a/source4/lib/events/events_select.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- main select loop and event handling
- Copyright (C) Andrew Tridgell 2003-2005
- Copyright (C) Stefan Metzmacher 2005
-
- 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/>.
-*/
-
-/*
- This is SAMBA's default event loop code
-
-*/
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/select.h"
-#include "events.h"
-#include "events_util.h"
-#include "events_internal.h"
-
-struct select_event_context {
- /* a pointer back to the generic event_context */
- struct event_context *ev;
-
- /* list of filedescriptor events */
- struct fd_event *fd_events;
-
- /* list of timed events */
- struct timed_event *timed_events;
-
- /* the maximum file descriptor number in fd_events */
- int maxfd;
-
- /* information for exiting from the event loop */
- int exit_code;
-
- /* this is incremented when the loop over events causes something which
- could change the events yet to be processed */
- uint32_t destruction_count;
-};
-
-/*
- create a select_event_context structure.
-*/
-static int select_event_context_init(struct event_context *ev)
-{
- struct select_event_context *select_ev;
-
- select_ev = talloc_zero(ev, struct select_event_context);
- if (!select_ev) return -1;
- select_ev->ev = ev;
-
- ev->additional_data = select_ev;
- return 0;
-}
-
-/*
- recalculate the maxfd
-*/
-static void calc_maxfd(struct select_event_context *select_ev)
-{
- struct fd_event *fde;
-
- select_ev->maxfd = 0;
- for (fde = select_ev->fd_events; fde; fde = fde->next) {
- if (fde->fd > select_ev->maxfd) {
- select_ev->maxfd = fde->fd;
- }
- }
-}
-
-
-/* to mark the ev->maxfd invalid
- * this means we need to recalculate it
- */
-#define EVENT_INVALID_MAXFD (-1)
-
-/*
- destroy an fd_event
-*/
-static int select_event_fd_destructor(struct fd_event *fde)
-{
- struct event_context *ev = fde->event_ctx;
- struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
- struct select_event_context);
-
- if (select_ev->maxfd == fde->fd) {
- select_ev->maxfd = EVENT_INVALID_MAXFD;
- }
-
- DLIST_REMOVE(select_ev->fd_events, fde);
- select_ev->destruction_count++;
-
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
- fde->fd = -1;
- }
-
- return 0;
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-*/
-static struct fd_event *select_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
-{
- struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
- struct select_event_context);
- struct fd_event *fde;
-
- fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
- if (!fde) return NULL;
-
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->private_data = private_data;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
-
- DLIST_ADD(select_ev->fd_events, fde);
- if (fde->fd > select_ev->maxfd) {
- select_ev->maxfd = fde->fd;
- }
- talloc_set_destructor(fde, select_event_fd_destructor);
-
- return fde;
-}
-
-
-/*
- return the fd event flags
-*/
-static uint16_t select_event_get_fd_flags(struct fd_event *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void select_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- struct event_context *ev;
- struct select_event_context *select_ev;
-
- if (fde->flags == flags) return;
-
- ev = fde->event_ctx;
- select_ev = talloc_get_type(ev->additional_data, struct select_event_context);
-
- fde->flags = flags;
-}
-
-/*
- event loop handling using select()
-*/
-static int select_event_loop_select(struct select_event_context *select_ev, struct timeval *tvalp)
-{
- fd_set r_fds, w_fds;
- struct fd_event *fde;
- int selrtn;
- uint32_t destruction_count = ++select_ev->destruction_count;
-
- /* we maybe need to recalculate the maxfd */
- if (select_ev->maxfd == EVENT_INVALID_MAXFD) {
- calc_maxfd(select_ev);
- }
-
- FD_ZERO(&r_fds);
- FD_ZERO(&w_fds);
-
- /* setup any fd events */
- for (fde = select_ev->fd_events; fde; fde = fde->next) {
- if (fde->flags & EVENT_FD_READ) {
- FD_SET(fde->fd, &r_fds);
- }
- if (fde->flags & EVENT_FD_WRITE) {
- FD_SET(fde->fd, &w_fds);
- }
- }
-
- if (select_ev->ev->num_signal_handlers &&
- common_event_check_signal(select_ev->ev)) {
- return 0;
- }
-
- selrtn = select(select_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
-
- if (selrtn == -1 && errno == EINTR &&
- select_ev->ev->num_signal_handlers) {
- common_event_check_signal(select_ev->ev);
- return 0;
- }
-
- if (selrtn == -1 && errno == EBADF) {
- /* the socket is dead! this should never
- happen as the socket should have first been
- made readable and that should have removed
- the event, so this must be a bug. This is a
- fatal error. */
- ev_debug(select_ev->ev, EV_DEBUG_FATAL,
- "ERROR: EBADF on select_event_loop_once\n");
- select_ev->exit_code = EBADF;
- return -1;
- }
-
- if (selrtn == 0 && tvalp) {
- /* we don't care about a possible delay here */
- common_event_loop_timer_delay(select_ev->ev);
- return 0;
- }
-
- if (selrtn > 0) {
- /* at least one file descriptor is ready - check
- which ones and call the handler, being careful to allow
- the handler to remove itself when called */
- for (fde = select_ev->fd_events; fde; fde = fde->next) {
- uint16_t flags = 0;
-
- if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
- if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
- if (flags) {
- fde->handler(select_ev->ev, fde, flags, fde->private_data);
- if (destruction_count != select_ev->destruction_count) {
- break;
- }
- }
- }
- }
-
- return 0;
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-static int select_event_loop_once(struct event_context *ev)
-{
- struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
- struct select_event_context);
- struct timeval tval;
-
- tval = common_event_loop_timer_delay(ev);
- if (ev_timeval_is_zero(&tval)) {
- return 0;
- }
-
- return select_event_loop_select(select_ev, &tval);
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-static int select_event_loop_wait(struct event_context *ev)
-{
- struct select_event_context *select_ev = talloc_get_type(ev->additional_data,
- struct select_event_context);
- select_ev->exit_code = 0;
-
- while (select_ev->fd_events && select_ev->exit_code == 0) {
- if (select_event_loop_once(ev) != 0) {
- break;
- }
- }
-
- return select_ev->exit_code;
-}
-
-static const struct event_ops select_event_ops = {
- .context_init = select_event_context_init,
- .add_fd = select_event_add_fd,
- .get_fd_flags = select_event_get_fd_flags,
- .set_fd_flags = select_event_set_fd_flags,
- .add_timed = common_event_add_timed,
- .add_signal = common_event_add_signal,
- .loop_once = select_event_loop_once,
- .loop_wait = select_event_loop_wait,
-};
-
-bool events_select_init(void)
-{
- return event_register_backend("select", &select_event_ops);
-}
-
diff --git a/source4/lib/events/events_signal.c b/source4/lib/events/events_signal.c
deleted file mode 100644
index 652df53d4b..0000000000
--- a/source4/lib/events/events_signal.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- common events code for signal events
-
- Copyright (C) Andrew Tridgell 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 <signal.h>
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/select.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-
-#define NUM_SIGNALS 64
-
-/* maximum number of SA_SIGINFO signals to hold in the queue */
-#define SA_INFO_QUEUE_COUNT 10
-
-struct sigcounter {
- uint32_t count;
- uint32_t seen;
-};
-
-#define SIG_INCREMENT(s) (s).count++
-#define SIG_SEEN(s, n) (s).seen += (n)
-#define SIG_PENDING(s) ((s).seen != (s).count)
-
-
-/*
- the poor design of signals means that this table must be static global
-*/
-static struct sig_state {
- struct signal_event *sig_handlers[NUM_SIGNALS+1];
- struct sigaction *oldact[NUM_SIGNALS+1];
- struct sigcounter signal_count[NUM_SIGNALS+1];
- struct sigcounter got_signal;
- int pipe_hack[2];
-#ifdef SA_SIGINFO
- /* with SA_SIGINFO we get quite a lot of info per signal */
- siginfo_t *sig_info[NUM_SIGNALS+1];
- struct sigcounter sig_blocked[NUM_SIGNALS+1];
-#endif
-} *sig_state;
-
-/*
- return number of sigcounter events not processed yet
-*/
-static uint32_t sig_count(struct sigcounter s)
-{
- if (s.count >= s.seen) {
- return s.count - s.seen;
- }
- return 1 + (0xFFFFFFFF & ~(s.seen - s.count));
-}
-
-/*
- signal handler - redirects to registered signals
-*/
-static void signal_handler(int signum)
-{
- char c = 0;
- SIG_INCREMENT(sig_state->signal_count[signum]);
- SIG_INCREMENT(sig_state->got_signal);
- /* doesn't matter if this pipe overflows */
- write(sig_state->pipe_hack[1], &c, 1);
-}
-
-#ifdef SA_SIGINFO
-/*
- signal handler with SA_SIGINFO - redirects to registered signals
-*/
-static void signal_handler_info(int signum, siginfo_t *info, void *uctx)
-{
- uint32_t count = sig_count(sig_state->signal_count[signum]);
- sig_state->sig_info[signum][count] = *info;
-
- signal_handler(signum);
-
- /* handle SA_SIGINFO */
- if (count+1 == SA_INFO_QUEUE_COUNT) {
- /* we've filled the info array - block this signal until
- these ones are delivered */
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, signum);
- sigprocmask(SIG_BLOCK, &set, NULL);
- SIG_INCREMENT(sig_state->sig_blocked[signum]);
- }
-}
-#endif
-
-/*
- destroy a signal event
-*/
-static int signal_event_destructor(struct signal_event *se)
-{
- se->event_ctx->num_signal_handlers--;
- DLIST_REMOVE(sig_state->sig_handlers[se->signum], se);
- if (sig_state->sig_handlers[se->signum] == NULL) {
- /* restore old handler, if any */
- sigaction(se->signum, sig_state->oldact[se->signum], NULL);
- sig_state->oldact[se->signum] = NULL;
-#ifdef SA_SIGINFO
- if (se->sa_flags & SA_SIGINFO) {
- talloc_free(sig_state->sig_info[se->signum]);
- sig_state->sig_info[se->signum] = NULL;
- }
-#endif
- }
- return 0;
-}
-
-/*
- this is part of the pipe hack needed to avoid the signal race condition
-*/
-static void signal_pipe_handler(struct event_context *ev, struct fd_event *fde,
- uint16_t flags, void *private)
-{
- char c[16];
- /* its non-blocking, doesn't matter if we read too much */
- read(sig_state->pipe_hack[0], c, sizeof(c));
-}
-
-/*
- add a signal event
- return NULL on failure (memory allocation error)
-*/
-struct signal_event *common_event_add_signal(struct event_context *ev,
- TALLOC_CTX *mem_ctx,
- int signum,
- int sa_flags,
- event_signal_handler_t handler,
- void *private_data)
-{
- struct signal_event *se;
-
- if (signum >= NUM_SIGNALS) {
- return NULL;
- }
-
- /* the sig_state needs to be on a global context as it can last across
- multiple event contexts */
- if (sig_state == NULL) {
- sig_state = talloc_zero(talloc_autofree_context(), struct sig_state);
- if (sig_state == NULL) {
- return NULL;
- }
- }
-
- se = talloc(mem_ctx?mem_ctx:ev, struct signal_event);
- if (se == NULL) return NULL;
-
- se->event_ctx = ev;
- se->handler = handler;
- se->private_data = private_data;
- se->signum = signum;
- se->sa_flags = sa_flags;
-
- /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */
- if (!talloc_reference(se, sig_state)) {
- return NULL;
- }
-
- /* only install a signal handler if not already installed */
- if (sig_state->sig_handlers[signum] == NULL) {
- struct sigaction act;
- ZERO_STRUCT(act);
- act.sa_handler = signal_handler;
- act.sa_flags = sa_flags;
-#ifdef SA_SIGINFO
- if (sa_flags & SA_SIGINFO) {
- act.sa_handler = NULL;
- act.sa_sigaction = signal_handler_info;
- if (sig_state->sig_info[signum] == NULL) {
- sig_state->sig_info[signum] = talloc_array(sig_state, siginfo_t, SA_INFO_QUEUE_COUNT);
- if (sig_state->sig_info[signum] == NULL) {
- talloc_free(se);
- return NULL;
- }
- }
- }
-#endif
- sig_state->oldact[signum] = talloc(sig_state, struct sigaction);
- if (sig_state->oldact[signum] == NULL) {
- talloc_free(se);
- return NULL;
- }
- if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) {
- talloc_free(se);
- return NULL;
- }
- }
-
- DLIST_ADD(sig_state->sig_handlers[signum], se);
-
- talloc_set_destructor(se, signal_event_destructor);
-
- /* we need to setup the pipe hack handler if not already
- setup */
- if (ev->pipe_fde == NULL) {
- if (sig_state->pipe_hack[0] == 0 &&
- sig_state->pipe_hack[1] == 0) {
- pipe(sig_state->pipe_hack);
- ev_set_blocking(sig_state->pipe_hack[0], false);
- ev_set_blocking(sig_state->pipe_hack[1], false);
- }
- ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0],
- EVENT_FD_READ, signal_pipe_handler, NULL);
- }
- ev->num_signal_handlers++;
-
- return se;
-}
-
-
-/*
- check if a signal is pending
- return != 0 if a signal was pending
-*/
-int common_event_check_signal(struct event_context *ev)
-{
- int i;
-
- if (!sig_state || !SIG_PENDING(sig_state->got_signal)) {
- return 0;
- }
-
- for (i=0;i<NUM_SIGNALS+1;i++) {
- struct signal_event *se, *next;
- struct sigcounter counter = sig_state->signal_count[i];
- uint32_t count = sig_count(counter);
-
- if (count == 0) {
- continue;
- }
- for (se=sig_state->sig_handlers[i];se;se=next) {
- next = se->next;
-#ifdef SA_SIGINFO
- if (se->sa_flags & SA_SIGINFO) {
- int j;
- for (j=0;j<count;j++) {
- /* note the use of the sig_info array as a
- ring buffer */
- int ofs = ((count-1) + j) % SA_INFO_QUEUE_COUNT;
- se->handler(ev, se, i, 1,
- (void*)&sig_state->sig_info[i][ofs],
- se->private_data);
- }
- if (SIG_PENDING(sig_state->sig_blocked[i])) {
- /* we'd filled the queue, unblock the
- signal now */
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, i);
- SIG_SEEN(sig_state->sig_blocked[i],
- sig_count(sig_state->sig_blocked[i]));
- sigprocmask(SIG_UNBLOCK, &set, NULL);
- }
- if (se->sa_flags & SA_RESETHAND) {
- talloc_free(se);
- }
- continue;
- }
-#endif
- se->handler(ev, se, i, count, NULL, se->private_data);
- if (se->sa_flags & SA_RESETHAND) {
- talloc_free(se);
- }
- }
- SIG_SEEN(sig_state->signal_count[i], count);
- SIG_SEEN(sig_state->got_signal, count);
- }
-
- return 1;
-}
diff --git a/source4/lib/events/events_standard.c b/source4/lib/events/events_standard.c
deleted file mode 100644
index 11128d7623..0000000000
--- a/source4/lib/events/events_standard.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- main select loop and event handling
- Copyright (C) Andrew Tridgell 2003-2005
- Copyright (C) Stefan Metzmacher 2005
-
- 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/>.
-*/
-
-/*
- This is SAMBA's default event loop code
-
- - we try to use epoll if configure detected support for it
- otherwise we use select()
- - if epoll is broken on the system or the kernel doesn't support it
- at runtime we fallback to select()
-*/
-
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/network.h"
-#include "system/select.h" /* needed for HAVE_EVENTS_EPOLL */
-#include "events.h"
-#include "events_util.h"
-#include "events_internal.h"
-
-struct std_event_context {
- /* a pointer back to the generic event_context */
- struct event_context *ev;
-
- /* list of filedescriptor events */
- struct fd_event *fd_events;
-
- /* the maximum file descriptor number in fd_events */
- int maxfd;
-
- /* information for exiting from the event loop */
- int exit_code;
-
- /* this is changed by the destructors for the fd event
- type. It is used to detect event destruction by event
- handlers, which means the code that is calling the event
- handler needs to assume that the linked list is no longer
- valid
- */
- uint32_t destruction_count;
-
- /* when using epoll this is the handle from epoll_create */
- int epoll_fd;
-
- /* our pid at the time the epoll_fd was created */
- pid_t pid;
-};
-
-/* use epoll if it is available */
-#if HAVE_EVENTS_EPOLL
-/*
- called when a epoll call fails, and we should fallback
- to using select
-*/
-static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
-{
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "%s (%s) - falling back to select()\n",
- reason, strerror(errno));
- close(std_ev->epoll_fd);
- std_ev->epoll_fd = -1;
- talloc_set_destructor(std_ev, NULL);
-}
-
-/*
- map from EVENT_FD_* to EPOLLIN/EPOLLOUT
-*/
-static uint32_t epoll_map_flags(uint16_t flags)
-{
- uint32_t ret = 0;
- if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
- if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
- return ret;
-}
-
-/*
- free the epoll fd
-*/
-static int epoll_ctx_destructor(struct std_event_context *std_ev)
-{
- if (std_ev->epoll_fd != -1) {
- close(std_ev->epoll_fd);
- }
- std_ev->epoll_fd = -1;
- return 0;
-}
-
-/*
- init the epoll fd
-*/
-static void epoll_init_ctx(struct std_event_context *std_ev)
-{
- std_ev->epoll_fd = epoll_create(64);
- std_ev->pid = getpid();
- talloc_set_destructor(std_ev, epoll_ctx_destructor);
-}
-
-static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde);
-
-/*
- reopen the epoll handle when our pid changes
- see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
- demonstration of why this is needed
- */
-static void epoll_check_reopen(struct std_event_context *std_ev)
-{
- struct fd_event *fde;
-
- if (std_ev->pid == getpid()) {
- return;
- }
-
- close(std_ev->epoll_fd);
- std_ev->epoll_fd = epoll_create(64);
- if (std_ev->epoll_fd == -1) {
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "Failed to recreate epoll handle after fork\n");
- return;
- }
- std_ev->pid = getpid();
- for (fde=std_ev->fd_events;fde;fde=fde->next) {
- epoll_add_event(std_ev, fde);
- }
-}
-
-#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
-#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
-#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
-
-/*
- add the epoll event to the given fd_event
-*/
-static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (std_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if we don't want events yet, don't add an epoll_event */
- if (fde->flags == 0) return;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
- epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
- }
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-/*
- delete the epoll event for given fd_event
-*/
-static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (std_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if there's no epoll_event, we don't need to delete it */
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
-}
-
-/*
- change the epoll event to the given fd_event
-*/
-static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
-{
- struct epoll_event event;
- if (std_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
- epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
- }
-
- /* only if we want to read we want to tell the event handler about errors */
- if (fde->flags & EVENT_FD_READ) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
- }
-}
-
-static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
-{
- bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
- bool want_read = (fde->flags & EVENT_FD_READ);
- bool want_write= (fde->flags & EVENT_FD_WRITE);
-
- if (std_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* there's already an event */
- if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
- if (want_read || (want_write && !got_error)) {
- epoll_mod_event(std_ev, fde);
- return;
- }
- /*
- * if we want to match the select behavior, we need to remove the epoll_event
- * when the caller isn't interested in events.
- *
- * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
- */
- epoll_del_event(std_ev, fde);
- return;
- }
-
- /* there's no epoll_event attached to the fde */
- if (want_read || (want_write && !got_error)) {
- epoll_add_event(std_ev, fde);
- return;
- }
-}
-
-/*
- event loop handling using epoll
-*/
-static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
-{
- int ret, i;
-#define MAXEVENTS 8
- struct epoll_event events[MAXEVENTS];
- uint32_t destruction_count = ++std_ev->destruction_count;
- int timeout = -1;
-
- if (std_ev->epoll_fd == -1) return -1;
-
- if (tvalp) {
- /* it's better to trigger timed events a bit later than to early */
- timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
- }
-
- if (std_ev->ev->num_signal_handlers &&
- common_event_check_signal(std_ev->ev)) {
- return 0;
- }
-
- ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
-
- if (ret == -1 && errno == EINTR && std_ev->ev->num_signal_handlers) {
- if (common_event_check_signal(std_ev->ev)) {
- return 0;
- }
- }
-
- if (ret == -1 && errno != EINTR) {
- epoll_fallback_to_select(std_ev, "epoll_wait() failed");
- return -1;
- }
-
- if (ret == 0 && tvalp) {
- /* we don't care about a possible delay here */
- common_event_loop_timer_delay(std_ev->ev);
- return 0;
- }
-
- for (i=0;i<ret;i++) {
- struct fd_event *fde = talloc_get_type(events[i].data.ptr,
- struct fd_event);
- uint16_t flags = 0;
-
- if (fde == NULL) {
- epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
- return -1;
- }
- if (events[i].events & (EPOLLHUP|EPOLLERR)) {
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
- /*
- * if we only wait for EVENT_FD_WRITE, we should not tell the
- * event handler about it, and remove the epoll_event,
- * as we only report errors when waiting for read events,
- * to match the select() behavior
- */
- if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
- epoll_del_event(std_ev, fde);
- continue;
- }
- flags |= EVENT_FD_READ;
- }
- if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
- if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
- if (flags) {
- fde->handler(std_ev->ev, fde, flags, fde->private_data);
- if (destruction_count != std_ev->destruction_count) {
- break;
- }
- }
- }
-
- return 0;
-}
-#else
-#define epoll_init_ctx(std_ev)
-#define epoll_add_event(std_ev,fde)
-#define epoll_del_event(std_ev,fde)
-#define epoll_change_event(std_ev,fde)
-#define epoll_event_loop(std_ev,tvalp) (-1)
-#define epoll_check_reopen(std_ev)
-#endif
-
-/*
- create a std_event_context structure.
-*/
-static int std_event_context_init(struct event_context *ev)
-{
- struct std_event_context *std_ev;
-
- std_ev = talloc_zero(ev, struct std_event_context);
- if (!std_ev) return -1;
- std_ev->ev = ev;
- std_ev->epoll_fd = -1;
-
- epoll_init_ctx(std_ev);
-
- ev->additional_data = std_ev;
- return 0;
-}
-
-/*
- recalculate the maxfd
-*/
-static void calc_maxfd(struct std_event_context *std_ev)
-{
- struct fd_event *fde;
-
- std_ev->maxfd = 0;
- for (fde = std_ev->fd_events; fde; fde = fde->next) {
- if (fde->fd > std_ev->maxfd) {
- std_ev->maxfd = fde->fd;
- }
- }
-}
-
-
-/* to mark the ev->maxfd invalid
- * this means we need to recalculate it
- */
-#define EVENT_INVALID_MAXFD (-1)
-
-/*
- destroy an fd_event
-*/
-static int std_event_fd_destructor(struct fd_event *fde)
-{
- struct event_context *ev = fde->event_ctx;
- struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
- struct std_event_context);
-
- epoll_check_reopen(std_ev);
-
- if (std_ev->maxfd == fde->fd) {
- std_ev->maxfd = EVENT_INVALID_MAXFD;
- }
-
- DLIST_REMOVE(std_ev->fd_events, fde);
- std_ev->destruction_count++;
-
- epoll_del_event(std_ev, fde);
-
- if (fde->flags & EVENT_FD_AUTOCLOSE) {
- close(fde->fd);
- fde->fd = -1;
- }
-
- return 0;
-}
-
-/*
- add a fd based event
- return NULL on failure (memory allocation error)
-*/
-static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
- int fd, uint16_t flags,
- event_fd_handler_t handler,
- void *private_data)
-{
- struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
- struct std_event_context);
- struct fd_event *fde;
-
- epoll_check_reopen(std_ev);
-
- fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
- if (!fde) return NULL;
-
- fde->event_ctx = ev;
- fde->fd = fd;
- fde->flags = flags;
- fde->handler = handler;
- fde->private_data = private_data;
- fde->additional_flags = 0;
- fde->additional_data = NULL;
-
- DLIST_ADD(std_ev->fd_events, fde);
- if ((std_ev->maxfd != EVENT_INVALID_MAXFD)
- && (fde->fd > std_ev->maxfd)) {
- std_ev->maxfd = fde->fd;
- }
- talloc_set_destructor(fde, std_event_fd_destructor);
-
- epoll_add_event(std_ev, fde);
-
- return fde;
-}
-
-
-/*
- return the fd event flags
-*/
-static uint16_t std_event_get_fd_flags(struct fd_event *fde)
-{
- return fde->flags;
-}
-
-/*
- set the fd event flags
-*/
-static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
-{
- struct event_context *ev;
- struct std_event_context *std_ev;
-
- if (fde->flags == flags) return;
-
- ev = fde->event_ctx;
- std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
-
- fde->flags = flags;
-
- epoll_check_reopen(std_ev);
-
- epoll_change_event(std_ev, fde);
-}
-
-/*
- event loop handling using select()
-*/
-static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
-{
- fd_set r_fds, w_fds;
- struct fd_event *fde;
- int selrtn;
- uint32_t destruction_count = ++std_ev->destruction_count;
-
- /* we maybe need to recalculate the maxfd */
- if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
- calc_maxfd(std_ev);
- }
-
- FD_ZERO(&r_fds);
- FD_ZERO(&w_fds);
-
- /* setup any fd events */
- for (fde = std_ev->fd_events; fde; fde = fde->next) {
- if (fde->flags & EVENT_FD_READ) {
- FD_SET(fde->fd, &r_fds);
- }
- if (fde->flags & EVENT_FD_WRITE) {
- FD_SET(fde->fd, &w_fds);
- }
- }
-
- if (std_ev->ev->num_signal_handlers &&
- common_event_check_signal(std_ev->ev)) {
- return 0;
- }
-
- selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
-
- if (selrtn == -1 && errno == EINTR &&
- std_ev->ev->num_signal_handlers) {
- common_event_check_signal(std_ev->ev);
- return 0;
- }
-
- if (selrtn == -1 && errno == EBADF) {
- /* the socket is dead! this should never
- happen as the socket should have first been
- made readable and that should have removed
- the event, so this must be a bug. This is a
- fatal error. */
- ev_debug(std_ev->ev, EV_DEBUG_FATAL,
- "ERROR: EBADF on std_event_loop_once\n");
- std_ev->exit_code = EBADF;
- return -1;
- }
-
- if (selrtn == 0 && tvalp) {
- /* we don't care about a possible delay here */
- common_event_loop_timer_delay(std_ev->ev);
- return 0;
- }
-
- if (selrtn > 0) {
- /* at least one file descriptor is ready - check
- which ones and call the handler, being careful to allow
- the handler to remove itself when called */
- for (fde = std_ev->fd_events; fde; fde = fde->next) {
- uint16_t flags = 0;
-
- if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
- if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
- if (flags) {
- fde->handler(std_ev->ev, fde, flags, fde->private_data);
- if (destruction_count != std_ev->destruction_count) {
- break;
- }
- }
- }
- }
-
- return 0;
-}
-
-/*
- do a single event loop using the events defined in ev
-*/
-static int std_event_loop_once(struct event_context *ev)
-{
- struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
- struct std_event_context);
- struct timeval tval;
-
- tval = common_event_loop_timer_delay(ev);
- if (ev_timeval_is_zero(&tval)) {
- return 0;
- }
-
- epoll_check_reopen(std_ev);
-
- if (epoll_event_loop(std_ev, &tval) == 0) {
- return 0;
- }
-
- return std_event_loop_select(std_ev, &tval);
-}
-
-/*
- return on failure or (with 0) if all fd events are removed
-*/
-static int std_event_loop_wait(struct event_context *ev)
-{
- struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
- struct std_event_context);
- std_ev->exit_code = 0;
-
- while (std_ev->fd_events && std_ev->exit_code == 0) {
- if (std_event_loop_once(ev) != 0) {
- break;
- }
- }
-
- return std_ev->exit_code;
-}
-
-static const struct event_ops std_event_ops = {
- .context_init = std_event_context_init,
- .add_fd = std_event_add_fd,
- .get_fd_flags = std_event_get_fd_flags,
- .set_fd_flags = std_event_set_fd_flags,
- .add_timed = common_event_add_timed,
- .add_signal = common_event_add_signal,
- .loop_once = std_event_loop_once,
- .loop_wait = std_event_loop_wait,
-};
-
-
-bool events_standard_init(void)
-{
- return event_register_backend("standard", &std_event_ops);
-}
-
diff --git a/source4/lib/events/events_timed.c b/source4/lib/events/events_timed.c
deleted file mode 100644
index c58c898c6d..0000000000
--- a/source4/lib/events/events_timed.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- common events code for timed events
-
- Copyright (C) Andrew Tridgell 2003-2006
- Copyright (C) Stefan Metzmacher 2005
-
- 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 <sys/time.h>
-#include <time.h>
-#include "replace.h"
-#include "system/filesys.h"
-#include "system/select.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-
-/**
- compare two timeval structures.
- Return -1 if tv1 < tv2
- Return 0 if tv1 == tv2
- Return 1 if tv1 > tv2
-*/
-static int ev_timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
-{
- if (tv1->tv_sec > tv2->tv_sec) return 1;
- if (tv1->tv_sec < tv2->tv_sec) return -1;
- if (tv1->tv_usec > tv2->tv_usec) return 1;
- if (tv1->tv_usec < tv2->tv_usec) return -1;
- return 0;
-}
-
-/**
- return a zero timeval
-*/
-static struct timeval ev_timeval_zero(void)
-{
- struct timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- return tv;
-}
-
-/**
- return a timeval for the current time
-*/
-static struct timeval ev_timeval_current(void)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv;
-}
-
-/**
- return a timeval struct with the given elements
-*/
-static struct timeval ev_timeval_set(uint32_t secs, uint32_t usecs)
-{
- struct timeval tv;
- tv.tv_sec = secs;
- tv.tv_usec = usecs;
- return tv;
-}
-
-/**
- return the difference between two timevals as a timeval
- if tv1 comes after tv2, then return a zero timeval
- (this is *tv2 - *tv1)
-*/
-static struct timeval ev_timeval_until(const struct timeval *tv1,
- const struct timeval *tv2)
-{
- struct timeval t;
- if (ev_timeval_compare(tv1, tv2) >= 0) {
- return ev_timeval_zero();
- }
- t.tv_sec = tv2->tv_sec - tv1->tv_sec;
- if (tv1->tv_usec > tv2->tv_usec) {
- t.tv_sec--;
- t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
- } else {
- t.tv_usec = tv2->tv_usec - tv1->tv_usec;
- }
- return t;
-}
-
-/**
- return true if a timeval is zero
-*/
-bool ev_timeval_is_zero(const struct timeval *tv)
-{
- return tv->tv_sec == 0 && tv->tv_usec == 0;
-}
-
-/*
- destroy a timed event
-*/
-static int common_event_timed_destructor(struct timed_event *te)
-{
- struct event_context *ev = talloc_get_type(te->event_ctx,
- struct event_context);
- DLIST_REMOVE(ev->timed_events, te);
- return 0;
-}
-
-static int common_event_timed_deny_destructor(struct timed_event *te)
-{
- return -1;
-}
-
-/*
- add a timed event
- return NULL on failure (memory allocation error)
-*/
-struct timed_event *common_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
- struct timeval next_event,
- event_timed_handler_t handler,
- void *private_data)
-{
- struct timed_event *te, *last_te, *cur_te;
-
- te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
- if (te == NULL) return NULL;
-
- te->event_ctx = ev;
- te->next_event = next_event;
- te->handler = handler;
- te->private_data = private_data;
- te->additional_data = NULL;
-
- /* keep the list ordered */
- last_te = NULL;
- for (cur_te = ev->timed_events; cur_te; cur_te = cur_te->next) {
- /* if the new event comes before the current one break */
- if (ev_timeval_compare(&te->next_event, &cur_te->next_event) < 0) {
- break;
- }
-
- last_te = cur_te;
- }
-
- DLIST_ADD_AFTER(ev->timed_events, te, last_te);
-
- talloc_set_destructor(te, common_event_timed_destructor);
-
- return te;
-}
-
-/*
- do a single event loop using the events defined in ev
-
- return the delay untill the next timed event,
- or zero if a timed event was triggered
-*/
-struct timeval common_event_loop_timer_delay(struct event_context *ev)
-{
- struct timeval current_time = ev_timeval_zero();
- struct timed_event *te = ev->timed_events;
-
- if (!te) {
- /* have a default tick time of 30 seconds. This guarantees
- that code that uses its own timeout checking will be
- able to proceeed eventually */
- return ev_timeval_set(30, 0);
- }
-
- /*
- * work out the right timeout for the next timed event
- *
- * avoid the syscall to gettimeofday() if the timed event should
- * be triggered directly
- *
- * if there's a delay till the next timed event, we're done
- * with just returning the delay
- */
- if (!ev_timeval_is_zero(&te->next_event)) {
- struct timeval delay;
-
- current_time = ev_timeval_current();
-
- delay = ev_timeval_until(&current_time, &te->next_event);
- if (!ev_timeval_is_zero(&delay)) {
- return delay;
- }
- }
-
- /*
- * ok, we have a timed event that we'll process ...
- */
-
- /* deny the handler to free the event */
- talloc_set_destructor(te, common_event_timed_deny_destructor);
-
- /* We need to remove the timer from the list before calling the
- * handler because in a semi-async inner event loop called from the
- * handler we don't want to come across this event again -- vl */
- DLIST_REMOVE(ev->timed_events, te);
-
- /*
- * If the timed event was registered for a zero current_time,
- * then we pass a zero timeval here too! To avoid the
- * overhead of gettimeofday() calls.
- *
- * otherwise we pass the current time
- */
- te->handler(ev, te, current_time, te->private_data);
-
- /* The destructor isn't necessary anymore, we've already removed the
- * event from the list. */
- talloc_set_destructor(te, NULL);
-
- talloc_free(te);
-
- return ev_timeval_zero();
-}
-
diff --git a/source4/lib/events/events_util.c b/source4/lib/events/events_util.c
deleted file mode 100644
index 9e7d758405..0000000000
--- a/source4/lib/events/events_util.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 2005
- Copyright (C) Jelmer Vernooij 2005
-
- 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 "replace.h"
-#include "talloc.h"
-#include "events.h"
-#include "events_internal.h"
-#include "events_util.h"
-#include <fcntl.h>
-
-/**
- return the number of elements in a string list
-*/
-static size_t str_list_length(const char **list)
-{
- size_t ret;
- for (ret=0;list && list[ret];ret++) /* noop */ ;
- return ret;
-}
-
-/**
- add an entry to a string list
-*/
-const char **ev_str_list_add(const char **list, const char *s)
-{
- size_t len = str_list_length(list);
- const char **ret;
-
- ret = talloc_realloc(NULL, list, const char *, len+2);
- if (ret == NULL) return NULL;
-
- ret[len] = talloc_strdup(ret, s);
- if (ret[len] == NULL) return NULL;
-
- ret[len+1] = NULL;
-
- return ret;
-}
-
-
-/**
- Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
- else
- if SYSV use O_NDELAY
- if BSD use FNDELAY
-**/
-
-int ev_set_blocking(int fd, bool set)
-{
- int val;
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if((val = fcntl(fd, F_GETFL, 0)) == -1)
- return -1;
- if(set) /* Turn blocking on - ie. clear nonblock flag */
- val &= ~FLAG_TO_SET;
- else
- val |= FLAG_TO_SET;
- return fcntl( fd, F_SETFL, val);
-#undef FLAG_TO_SET
-}
diff --git a/source4/lib/events/events_util.h b/source4/lib/events/events_util.h
deleted file mode 100644
index 052b302aae..0000000000
--- a/source4/lib/events/events_util.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 1998-2005
- Copyright (C) Jelmer Vernooij 2005
-
- 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/>.
-*/
-
-/* To use these macros you must have a structure containing a next and
- prev pointer */
-
-#ifndef _DLINKLIST_H
-#define _DLINKLIST_H
-
-
-/* hook into the front of the list */
-#define DLIST_ADD(list, p) \
-do { \
- if (!(list)) { \
- (list) = (p); \
- (p)->next = (p)->prev = NULL; \
- } else { \
- (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. */
-#define DLIST_REMOVE(list, p) \
-do { \
- if ((p) == (list)) { \
- (list) = (p)->next; \
- if (list) (list)->prev = NULL; \
- } else { \
- if ((p)->prev) (p)->prev->next = (p)->next; \
- if ((p)->next) (p)->next->prev = (p)->prev; \
- } \
- if ((p) != (list)) (p)->next = (p)->prev = NULL; \
-} while (0)
-
-/* promote an element to the top of the list */
-#define DLIST_PROMOTE(list, p) \
-do { \
- DLIST_REMOVE(list, p); \
- DLIST_ADD(list, p); \
-} while (0)
-
-/* hook into the end of the list - needs a tmp pointer */
-#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)
-
-/* insert 'p' after the given element 'el' in a list. If el is NULL then
- this is the same as a DLIST_ADD() */
-#define DLIST_ADD_AFTER(list, p, el) \
-do { \
- if (!(list) || !(el)) { \
- DLIST_ADD(list, p); \
- } else { \
- p->prev = el; \
- p->next = el->next; \
- el->next = p; \
- if (p->next) p->next->prev = p; \
- }\
-} while (0)
-
-/* demote an element to the end of the list, needs a tmp pointer */
-#define DLIST_DEMOTE(list, p, tmp) \
-do { \
- DLIST_REMOVE(list, p); \
- DLIST_ADD_END(list, p, tmp); \
-} 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) \
-do { \
- if (!(list1)) { \
- (list1) = (list2); \
- } else { \
- type tmp; \
- for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
- tmp->next = (list2); \
- if (list2) { \
- (list2)->prev = tmp; \
- } \
- } \
-} while (0)
-
-#endif /* _DLINKLIST_H */
-
-const char **ev_str_list_add(const char **list, const char *s);
-int ev_set_blocking(int fd, bool set);
diff --git a/source4/lib/events/events_wrap.c b/source4/lib/events/events_wrap.c
deleted file mode 100644
index 335652101b..0000000000
--- a/source4/lib/events/events_wrap.c
+++ /dev/null
@@ -1,3348 +0,0 @@
-/* ----------------------------------------------------------------------------
- * This file was automatically generated by SWIG (http://www.swig.org).
- * Version 1.3.36
- *
- * This file is not intended to be easily readable and contains a number of
- * coding conventions designed to improve portability and efficiency. Do not make
- * changes to this file unless you know what you are doing--modify the SWIG
- * interface file instead.
- * ----------------------------------------------------------------------------- */
-
-#define SWIGPYTHON
-#define SWIG_PYTHON_NO_BUILD_NONE
-/* -----------------------------------------------------------------------------
- * This section contains generic SWIG labels for method/variable
- * declarations/attributes, and other compiler dependent labels.
- * ----------------------------------------------------------------------------- */
-
-/* template workaround for compilers that cannot correctly implement the C++ standard */
-#ifndef SWIGTEMPLATEDISAMBIGUATOR
-# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
-# define SWIGTEMPLATEDISAMBIGUATOR template
-# elif defined(__HP_aCC)
-/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
-/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
-# define SWIGTEMPLATEDISAMBIGUATOR template
-# else
-# define SWIGTEMPLATEDISAMBIGUATOR
-# endif
-#endif
-
-/* inline attribute */
-#ifndef SWIGINLINE
-# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
-# define SWIGINLINE inline
-# else
-# define SWIGINLINE
-# endif
-#endif
-
-/* attribute recognised by some compilers to avoid 'unused' warnings */
-#ifndef SWIGUNUSED
-# if defined(__GNUC__)
-# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
-# define SWIGUNUSED __attribute__ ((__unused__))
-# else
-# define SWIGUNUSED
-# endif
-# elif defined(__ICC)
-# define SWIGUNUSED __attribute__ ((__unused__))
-# else
-# define SWIGUNUSED
-# endif
-#endif
-
-#ifndef SWIG_MSC_UNSUPPRESS_4505
-# if defined(_MSC_VER)
-# pragma warning(disable : 4505) /* unreferenced local function has been removed */
-# endif
-#endif
-
-#ifndef SWIGUNUSEDPARM
-# ifdef __cplusplus
-# define SWIGUNUSEDPARM(p)
-# else
-# define SWIGUNUSEDPARM(p) p SWIGUNUSED
-# endif
-#endif
-
-/* internal SWIG method */
-#ifndef SWIGINTERN
-# define SWIGINTERN static SWIGUNUSED
-#endif
-
-/* internal inline SWIG method */
-#ifndef SWIGINTERNINLINE
-# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
-#endif
-
-/* exporting methods */
-#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-# ifndef GCC_HASCLASSVISIBILITY
-# define GCC_HASCLASSVISIBILITY
-# endif
-#endif
-
-#ifndef SWIGEXPORT
-# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-# if defined(STATIC_LINKED)
-# define SWIGEXPORT
-# else
-# define SWIGEXPORT __declspec(dllexport)
-# endif
-# else
-# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
-# define SWIGEXPORT __attribute__ ((visibility("default")))
-# else
-# define SWIGEXPORT
-# endif
-# endif
-#endif
-
-/* calling conventions for Windows */
-#ifndef SWIGSTDCALL
-# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-# define SWIGSTDCALL __stdcall
-# else
-# define SWIGSTDCALL
-# endif
-#endif
-
-/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
-#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
-# define _CRT_SECURE_NO_DEPRECATE
-#endif
-
-/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
-#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
-# define _SCL_SECURE_NO_DEPRECATE
-#endif
-
-
-
-/* Python.h has to appear first */
-#include <Python.h>
-
-/* -----------------------------------------------------------------------------
- * swigrun.swg
- *
- * This file contains generic CAPI SWIG runtime support for pointer
- * type checking.
- * ----------------------------------------------------------------------------- */
-
-/* This should only be incremented when either the layout of swig_type_info changes,
- or for whatever reason, the runtime changes incompatibly */
-#define SWIG_RUNTIME_VERSION "4"
-
-/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
-#ifdef SWIG_TYPE_TABLE
-# define SWIG_QUOTE_STRING(x) #x
-# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
-# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
-#else
-# define SWIG_TYPE_TABLE_NAME
-#endif
-
-/*
- You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
- creating a static or dynamic library from the swig runtime code.
- In 99.9% of the cases, swig just needs to declare them as 'static'.
-
- But only do this if is strictly necessary, ie, if you have problems
- with your compiler or so.
-*/
-
-#ifndef SWIGRUNTIME
-# define SWIGRUNTIME SWIGINTERN
-#endif
-
-#ifndef SWIGRUNTIMEINLINE
-# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
-#endif
-
-/* Generic buffer size */
-#ifndef SWIG_BUFFER_SIZE
-# define SWIG_BUFFER_SIZE 1024
-#endif
-
-/* Flags for pointer conversions */
-#define SWIG_POINTER_DISOWN 0x1
-#define SWIG_CAST_NEW_MEMORY 0x2
-
-/* Flags for new pointer objects */
-#define SWIG_POINTER_OWN 0x1
-
-
-/*
- Flags/methods for returning states.
-
- The swig conversion methods, as ConvertPtr, return and integer
- that tells if the conversion was successful or not. And if not,
- an error code can be returned (see swigerrors.swg for the codes).
-
- Use the following macros/flags to set or process the returning
- states.
-
- In old swig versions, you usually write code as:
-
- if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
- // success code
- } else {
- //fail code
- }
-
- Now you can be more explicit as:
-
- int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
- if (SWIG_IsOK(res)) {
- // success code
- } else {
- // fail code
- }
-
- that seems to be the same, but now you can also do
-
- Type *ptr;
- int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
- if (SWIG_IsOK(res)) {
- // success code
- if (SWIG_IsNewObj(res) {
- ...
- delete *ptr;
- } else {
- ...
- }
- } else {
- // fail code
- }
-
- I.e., now SWIG_ConvertPtr can return new objects and you can
- identify the case and take care of the deallocation. Of course that
- requires also to SWIG_ConvertPtr to return new result values, as
-
- int SWIG_ConvertPtr(obj, ptr,...) {
- if (<obj is ok>) {
- if (<need new object>) {
- *ptr = <ptr to new allocated object>;
- return SWIG_NEWOBJ;
- } else {
- *ptr = <ptr to old object>;
- return SWIG_OLDOBJ;
- }
- } else {
- return SWIG_BADOBJ;
- }
- }
-
- Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
- more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
- swig errors code.
-
- Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
- allows to return the 'cast rank', for example, if you have this
-
- int food(double)
- int fooi(int);
-
- and you call
-
- food(1) // cast rank '1' (1 -> 1.0)
- fooi(1) // cast rank '0'
-
- just use the SWIG_AddCast()/SWIG_CheckState()
-
-
- */
-#define SWIG_OK (0)
-#define SWIG_ERROR (-1)
-#define SWIG_IsOK(r) (r >= 0)
-#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
-
-/* The CastRankLimit says how many bits are used for the cast rank */
-#define SWIG_CASTRANKLIMIT (1 << 8)
-/* The NewMask denotes the object was created (using new/malloc) */
-#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
-/* The TmpMask is for in/out typemaps that use temporal objects */
-#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
-/* Simple returning values */
-#define SWIG_BADOBJ (SWIG_ERROR)
-#define SWIG_OLDOBJ (SWIG_OK)
-#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
-#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
-/* Check, add and del mask methods */
-#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
-#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
-#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
-#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
-#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
-#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
-
-
-/* Cast-Rank Mode */
-#if defined(SWIG_CASTRANK_MODE)
-# ifndef SWIG_TypeRank
-# define SWIG_TypeRank unsigned long
-# endif
-# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
-# define SWIG_MAXCASTRANK (2)
-# endif
-# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
-# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
-SWIGINTERNINLINE int SWIG_AddCast(int r) {
- return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
-}
-SWIGINTERNINLINE int SWIG_CheckState(int r) {
- return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
-}
-#else /* no cast-rank mode */
-# define SWIG_AddCast
-# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
-#endif
-
-
-
-
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void *(*swig_converter_func)(void *, int *);
-typedef struct swig_type_info *(*swig_dycast_func)(void **);
-
-/* Structure to store information on one type */
-typedef struct swig_type_info {
- const char *name; /* mangled name of this type */
- const char *str; /* human readable name of this type */
- swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
- struct swig_cast_info *cast; /* linked list of types that can cast into this type */
- void *clientdata; /* language specific type data */
- int owndata; /* flag if the structure owns the clientdata */
-} swig_type_info;
-
-/* Structure to store a type and conversion function used for casting */
-typedef struct swig_cast_info {
- swig_type_info *type; /* pointer to type that is equivalent to this type */
- swig_converter_func converter; /* function to cast the void pointers */
- struct swig_cast_info *next; /* pointer to next cast in linked list */
- struct swig_cast_info *prev; /* pointer to the previous cast */
-} swig_cast_info;
-
-/* Structure used to store module information
- * Each module generates one structure like this, and the runtime collects
- * all of these structures and stores them in a circularly linked list.*/
-typedef struct swig_module_info {
- swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
- size_t size; /* Number of types in this module */
- struct swig_module_info *next; /* Pointer to next element in circularly linked list */
- swig_type_info **type_initial; /* Array of initially generated type structures */
- swig_cast_info **cast_initial; /* Array of initially generated casting structures */
- void *clientdata; /* Language specific module data */
-} swig_module_info;
-
-/*
- Compare two type names skipping the space characters, therefore
- "char*" == "char *" and "Class<int>" == "Class<int >", etc.
-
- Return 0 when the two name types are equivalent, as in
- strncmp, but skipping ' '.
-*/
-SWIGRUNTIME int
-SWIG_TypeNameComp(const char *f1, const char *l1,
- const char *f2, const char *l2) {
- for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
- while ((*f1 == ' ') && (f1 != l1)) ++f1;
- while ((*f2 == ' ') && (f2 != l2)) ++f2;
- if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
- }
- return (int)((l1 - f1) - (l2 - f2));
-}
-
-/*
- Check type equivalence in a name list like <name1>|<name2>|...
- Return 0 if not equal, 1 if equal
-*/
-SWIGRUNTIME int
-SWIG_TypeEquiv(const char *nb, const char *tb) {
- int equiv = 0;
- const char* te = tb + strlen(tb);
- const char* ne = nb;
- while (!equiv && *ne) {
- for (nb = ne; *ne; ++ne) {
- if (*ne == '|') break;
- }
- equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
- if (*ne) ++ne;
- }
- return equiv;
-}
-
-/*
- Check type equivalence in a name list like <name1>|<name2>|...
- Return 0 if equal, -1 if nb < tb, 1 if nb > tb
-*/
-SWIGRUNTIME int
-SWIG_TypeCompare(const char *nb, const char *tb) {
- int equiv = 0;
- const char* te = tb + strlen(tb);
- const char* ne = nb;
- while (!equiv && *ne) {
- for (nb = ne; *ne; ++ne) {
- if (*ne == '|') break;
- }
- equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
- if (*ne) ++ne;
- }
- return equiv;
-}
-
-
-/* think of this as a c++ template<> or a scheme macro */
-#define SWIG_TypeCheck_Template(comparison, ty) \
- if (ty) { \
- swig_cast_info *iter = ty->cast; \
- while (iter) { \
- if (comparison) { \
- if (iter == ty->cast) return iter; \
- /* Move iter to the top of the linked list */ \
- iter->prev->next = iter->next; \
- if (iter->next) \
- iter->next->prev = iter->prev; \
- iter->next = ty->cast; \
- iter->prev = 0; \
- if (ty->cast) ty->cast->prev = iter; \
- ty->cast = iter; \
- return iter; \
- } \
- iter = iter->next; \
- } \
- } \
- return 0
-
-/*
- Check the typename
-*/
-SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheck(const char *c, swig_type_info *ty) {
- SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty);
-}
-
-/* Same as previous function, except strcmp is replaced with a pointer comparison */
-SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
- SWIG_TypeCheck_Template(iter->type == from, into);
-}
-
-/*
- Cast a pointer up an inheritance hierarchy
-*/
-SWIGRUNTIMEINLINE void *
-SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
- return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
-}
-
-/*
- Dynamic pointer casting. Down an inheritance hierarchy
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
- swig_type_info *lastty = ty;
- if (!ty || !ty->dcast) return ty;
- while (ty && (ty->dcast)) {
- ty = (*ty->dcast)(ptr);
- if (ty) lastty = ty;
- }
- return lastty;
-}
-
-/*
- Return the name associated with this type
-*/
-SWIGRUNTIMEINLINE const char *
-SWIG_TypeName(const swig_type_info *ty) {
- return ty->name;
-}
-
-/*
- Return the pretty name associated with this type,
- that is an unmangled type name in a form presentable to the user.
-*/
-SWIGRUNTIME const char *
-SWIG_TypePrettyName(const swig_type_info *type) {
- /* The "str" field contains the equivalent pretty names of the
- type, separated by vertical-bar characters. We choose
- to print the last name, as it is often (?) the most
- specific. */
- if (!type) return NULL;
- if (type->str != NULL) {
- const char *last_name = type->str;
- const char *s;
- for (s = type->str; *s; s++)
- if (*s == '|') last_name = s+1;
- return last_name;
- }
- else
- return type->name;
-}
-
-/*
- Set the clientdata field for a type
-*/
-SWIGRUNTIME void
-SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
- swig_cast_info *cast = ti->cast;
- /* if (ti->clientdata == clientdata) return; */
- ti->clientdata = clientdata;
-
- while (cast) {
- if (!cast->converter) {
- swig_type_info *tc = cast->type;
- if (!tc->clientdata) {
- SWIG_TypeClientData(tc, clientdata);
- }
- }
- cast = cast->next;
- }
-}
-SWIGRUNTIME void
-SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
- SWIG_TypeClientData(ti, clientdata);
- ti->owndata = 1;
-}
-
-/*
- Search for a swig_type_info structure only by mangled name
- Search is a O(log #types)
-
- We start searching at module start, and finish searching when start == end.
- Note: if start == end at the beginning of the function, we go all the way around
- the circular list.
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_MangledTypeQueryModule(swig_module_info *start,
- swig_module_info *end,
- const char *name) {
- swig_module_info *iter = start;
- do {
- if (iter->size) {
- register size_t l = 0;
- register size_t r = iter->size - 1;
- do {
- /* since l+r >= 0, we can (>> 1) instead (/ 2) */
- register size_t i = (l + r) >> 1;
- const char *iname = iter->types[i]->name;
- if (iname) {
- register int compare = strcmp(name, iname);
- if (compare == 0) {
- return iter->types[i];
- } else if (compare < 0) {
- if (i) {
- r = i - 1;
- } else {
- break;
- }
- } else if (compare > 0) {
- l = i + 1;
- }
- } else {
- break; /* should never happen */
- }
- } while (l <= r);
- }
- iter = iter->next;
- } while (iter != end);
- return 0;
-}
-
-/*
- Search for a swig_type_info structure for either a mangled name or a human readable name.
- It first searches the mangled names of the types, which is a O(log #types)
- If a type is not found it then searches the human readable names, which is O(#types).
-
- We start searching at module start, and finish searching when start == end.
- Note: if start == end at the beginning of the function, we go all the way around
- the circular list.
-*/
-SWIGRUNTIME swig_type_info *
-SWIG_TypeQueryModule(swig_module_info *start,
- swig_module_info *end,
- const char *name) {
- /* STEP 1: Search the name field using binary search */
- swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
- if (ret) {
- return ret;
- } else {
- /* STEP 2: If the type hasn't been found, do a complete search
- of the str field (the human readable name) */
- swig_module_info *iter = start;
- do {
- register size_t i = 0;
- for (; i < iter->size; ++i) {
- if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
- return iter->types[i];
- }
- iter = iter->next;
- } while (iter != end);
- }
-
- /* neither found a match */
- return 0;
-}
-
-/*
- Pack binary data into a string
-*/
-SWIGRUNTIME char *
-SWIG_PackData(char *c, void *ptr, size_t sz) {
- static const char hex[17] = "0123456789abcdef";
- register const unsigned char *u = (unsigned char *) ptr;
- register const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- register unsigned char uu = *u;
- *(c++) = hex[(uu & 0xf0) >> 4];
- *(c++) = hex[uu & 0xf];
- }
- return c;
-}
-
-/*
- Unpack binary data from a string
-*/
-SWIGRUNTIME const char *
-SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
- register unsigned char *u = (unsigned char *) ptr;
- register const unsigned char *eu = u + sz;
- for (; u != eu; ++u) {
- register char d = *(c++);
- register unsigned char uu;
- if ((d >= '0') && (d <= '9'))
- uu = ((d - '0') << 4);
- else if ((d >= 'a') && (d <= 'f'))
- uu = ((d - ('a'-10)) << 4);
- else
- return (char *) 0;
- d = *(c++);
- if ((d >= '0') && (d <= '9'))
- uu |= (d - '0');
- else if ((d >= 'a') && (d <= 'f'))
- uu |= (d - ('a'-10));
- else
- return (char *) 0;
- *u = uu;
- }
- return c;
-}
-
-/*
- Pack 'void *' into a string buffer.
-*/
-SWIGRUNTIME char *
-SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
- char *r = buff;
- if ((2*sizeof(void *) + 2) > bsz) return 0;
- *(r++) = '_';
- r = SWIG_PackData(r,&ptr,sizeof(void *));
- if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
- strcpy(r,name);
- return buff;
-}
-
-SWIGRUNTIME const char *
-SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
- if (*c != '_') {
- if (strcmp(c,"NULL") == 0) {
- *ptr = (void *) 0;
- return name;
- } else {
- return 0;
- }
- }
- return SWIG_UnpackData(++c,ptr,sizeof(void *));
-}
-
-SWIGRUNTIME char *
-SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
- char *r = buff;
- size_t lname = (name ? strlen(name) : 0);
- if ((2*sz + 2 + lname) > bsz) return 0;
- *(r++) = '_';
- r = SWIG_PackData(r,ptr,sz);
- if (lname) {
- strncpy(r,name,lname+1);
- } else {
- *r = 0;
- }
- return buff;
-}
-
-SWIGRUNTIME const char *
-SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
- if (*c != '_') {
- if (strcmp(c,"NULL") == 0) {
- memset(ptr,0,sz);
- return name;
- } else {
- return 0;
- }
- }
- return SWIG_UnpackData(++c,ptr,sz);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-/* Errors in SWIG */
-#define SWIG_UnknownError -1
-#define SWIG_IOError -2
-#define SWIG_RuntimeError -3
-#define SWIG_IndexError -4
-#define SWIG_TypeError -5
-#define SWIG_DivisionByZero -6
-#define SWIG_OverflowError -7
-#define SWIG_SyntaxError -8
-#define SWIG_ValueError -9
-#define SWIG_SystemError -10
-#define SWIG_AttributeError -11
-#define SWIG_MemoryError -12
-#define SWIG_NullReferenceError -13
-
-
-
-
-/* Add PyOS_snprintf for old Pythons */
-#if PY_VERSION_HEX < 0x02020000
-# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
-# define PyOS_snprintf _snprintf
-# else
-# define PyOS_snprintf snprintf
-# endif
-#endif
-
-/* A crude PyString_FromFormat implementation for old Pythons */
-#if PY_VERSION_HEX < 0x02020000
-
-#ifndef SWIG_PYBUFFER_SIZE
-# define SWIG_PYBUFFER_SIZE 1024
-#endif
-
-static PyObject *
-PyString_FromFormat(const char *fmt, ...) {
- va_list ap;
- char buf[SWIG_PYBUFFER_SIZE * 2];
- int res;
- va_start(ap, fmt);
- res = vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
-}
-#endif
-
-/* Add PyObject_Del for old Pythons */
-#if PY_VERSION_HEX < 0x01060000
-# define PyObject_Del(op) PyMem_DEL((op))
-#endif
-#ifndef PyObject_DEL
-# define PyObject_DEL PyObject_Del
-#endif
-
-/* A crude PyExc_StopIteration exception for old Pythons */
-#if PY_VERSION_HEX < 0x02020000
-# ifndef PyExc_StopIteration
-# define PyExc_StopIteration PyExc_RuntimeError
-# endif
-# ifndef PyObject_GenericGetAttr
-# define PyObject_GenericGetAttr 0
-# endif
-#endif
-/* Py_NotImplemented is defined in 2.1 and up. */
-#if PY_VERSION_HEX < 0x02010000
-# ifndef Py_NotImplemented
-# define Py_NotImplemented PyExc_RuntimeError
-# endif
-#endif
-
-
-/* A crude PyString_AsStringAndSize implementation for old Pythons */
-#if PY_VERSION_HEX < 0x02010000
-# ifndef PyString_AsStringAndSize
-# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
-# endif
-#endif
-
-/* PySequence_Size for old Pythons */
-#if PY_VERSION_HEX < 0x02000000
-# ifndef PySequence_Size
-# define PySequence_Size PySequence_Length
-# endif
-#endif
-
-
-/* PyBool_FromLong for old Pythons */
-#if PY_VERSION_HEX < 0x02030000
-static
-PyObject *PyBool_FromLong(long ok)
-{
- PyObject *result = ok ? Py_True : Py_False;
- Py_INCREF(result);
- return result;
-}
-#endif
-
-/* Py_ssize_t for old Pythons */
-/* This code is as recommended by: */
-/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-# define PY_SSIZE_T_MAX INT_MAX
-# define PY_SSIZE_T_MIN INT_MIN
-#endif
-
-/* -----------------------------------------------------------------------------
- * error manipulation
- * ----------------------------------------------------------------------------- */
-
-SWIGRUNTIME PyObject*
-SWIG_Python_ErrorType(int code) {
- PyObject* type = 0;
- switch(code) {
- case SWIG_MemoryError:
- type = PyExc_MemoryError;
- break;
- case SWIG_IOError:
- type = PyExc_IOError;
- break;
- case SWIG_RuntimeError:
- type = PyExc_RuntimeError;
- break;
- case SWIG_IndexError:
- type = PyExc_IndexError;
- break;
- case SWIG_TypeError:
- type = PyExc_TypeError;
- break;
- case SWIG_DivisionByZero:
- type = PyExc_ZeroDivisionError;
- break;
- case SWIG_OverflowError:
- type = PyExc_OverflowError;
- break;
- case SWIG_SyntaxError:
- type = PyExc_SyntaxError;
- break;
- case SWIG_ValueError:
- type = PyExc_ValueError;
- break;
- case SWIG_SystemError:
- type = PyExc_SystemError;
- break;
- case SWIG_AttributeError:
- type = PyExc_AttributeError;
- break;
- default:
- type = PyExc_RuntimeError;
- }
- return type;
-}
-
-
-SWIGRUNTIME void
-SWIG_Python_AddErrorMsg(const char* mesg)
-{
- PyObject *type = 0;
- PyObject *value = 0;
- PyObject *traceback = 0;
-
- if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
- if (value) {
- PyObject *old_str = PyObject_Str(value);
- PyErr_Clear();
- Py_XINCREF(type);
- PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
- Py_DECREF(old_str);
- Py_DECREF(value);
- } else {
- PyErr_SetString(PyExc_RuntimeError, mesg);
- }
-}
-
-
-
-#if defined(SWIG_PYTHON_NO_THREADS)
-# if defined(SWIG_PYTHON_THREADS)
-# undef SWIG_PYTHON_THREADS
-# endif
-#endif
-#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
-# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
-# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
-# define SWIG_PYTHON_USE_GIL
-# endif
-# endif
-# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
-# ifndef SWIG_PYTHON_INITIALIZE_THREADS
-# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
-# endif
-# ifdef __cplusplus /* C++ code */
- class SWIG_Python_Thread_Block {
- bool status;
- PyGILState_STATE state;
- public:
- void end() { if (status) { PyGILState_Release(state); status = false;} }
- SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
- ~SWIG_Python_Thread_Block() { end(); }
- };
- class SWIG_Python_Thread_Allow {
- bool status;
- PyThreadState *save;
- public:
- void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
- SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
- ~SWIG_Python_Thread_Allow() { end(); }
- };
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
-# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
-# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
-# else /* C code */
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
-# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
-# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
-# endif
-# else /* Old thread way, not implemented, user must provide it */
-# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
-# define SWIG_PYTHON_INITIALIZE_THREADS
-# endif
-# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
-# endif
-# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
-# define SWIG_PYTHON_THREAD_END_BLOCK
-# endif
-# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
-# endif
-# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
-# define SWIG_PYTHON_THREAD_END_ALLOW
-# endif
-# endif
-#else /* No thread support */
-# define SWIG_PYTHON_INITIALIZE_THREADS
-# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
-# define SWIG_PYTHON_THREAD_END_BLOCK
-# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
-# define SWIG_PYTHON_THREAD_END_ALLOW
-#endif
-
-/* -----------------------------------------------------------------------------
- * Python API portion that goes into the runtime
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-} /* cc-mode */
-#endif
-#endif
-
-/* -----------------------------------------------------------------------------
- * Constant declarations
- * ----------------------------------------------------------------------------- */
-
-/* Constant Types */
-#define SWIG_PY_POINTER 4
-#define SWIG_PY_BINARY 5
-
-/* Constant information structure */
-typedef struct swig_const_info {
- int type;
- char *name;
- long lvalue;
- double dvalue;
- void *pvalue;
- swig_type_info **ptype;
-} swig_const_info;
-
-#ifdef __cplusplus
-#if 0
-{ /* cc-mode */
-#endif
-}
-#endif
-
-
-/* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
- *
- * pyrun.swg
- *
- * This file contains the runtime support for Python modules
- * and includes code for managing global variables and pointer
- * type checking.
- *
- * ----------------------------------------------------------------------------- */
-
-/* Common SWIG API */
-
-/* for raw pointers */
-#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
-#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
-#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
-#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
-#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
-#define swig_owntype int
-
-/* for raw packed data */
-#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
-#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
-
-/* for class or struct pointers */
-#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
-
-/* for C or C++ function pointers */
-#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
-#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0)
-
-/* for C++ member pointers, ie, member methods */
-#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
-#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
-
-
-/* Runtime API */
-
-#define SWIG_GetModule(clientdata) SWIG_Python_GetModule()
-#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
-#define SWIG_NewClientData(obj) PySwigClientData_New(obj)
-
-#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
-#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
-#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
-#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
-#define SWIG_fail goto fail
-
-
-/* Runtime API implementation */
-
-/* Error manipulation */
-
-SWIGINTERN void
-SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- PyErr_SetObject(errtype, obj);
- Py_DECREF(obj);
- SWIG_PYTHON_THREAD_END_BLOCK;
-}
-
-SWIGINTERN void
-SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
- SWIG_PYTHON_THREAD_BEGIN_BLOCK;
- PyErr_SetString(errtype, (char *) msg);
- SWIG_PYTHON_THREAD_END_BLOCK;
-}
-
-#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
-
-/* Set a constant value */
-
-SWIGINTERN void
-SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
- PyDict_SetItemString(d, (char*) name, obj);
- Py_DECREF(obj);
-}
-
-/* Append a value to the result obj */
-
-SWIGINTERN PyObject*
-SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
-#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
- if (!result) {
- result = obj;
- } else if (result == Py_None) {
- Py_DECREF(result);
- result = obj;
- } else {
- if (!PyList_Check(result)) {
- PyObject *o2 = result;
- result = PyList_New(1);
- PyList_SetItem(result, 0, o2);
- }
- PyList_Append(result,obj);
- Py_DECREF(obj);
- }
- return result;
-#else
- PyObject* o2;
- PyObject* o3;
- if (!result) {
- result = obj;
- } else if (result == Py_None) {
- Py_DECREF(result);
- result = obj;
- } else {
- if (!PyTuple_Check(result)) {
- o2 = result;
- result = PyTuple_New(1);
- PyTuple_SET_ITEM(result, 0, o2);
- }
- o3 = PyTuple_New(1);
- PyTuple_SET_ITEM(o3, 0, obj);
- o2 = result;
- result = PySequence_Concat(o2, o3);
- Py_DECREF(o2);
- Py_DECREF(o3);
- }
- return result;
-#endif
-}
-
-/* Unpack the argument tuple */
-
-SWIGINTERN int
-SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
-{
- if (!args) {
- if (!min && !max) {
- return 1;
- } else {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
- name, (min == max ? "" : "at least "), (int)min);
- return 0;
- }
- }
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
- return 0;
- } else {
- register Py_ssize_t l = PyTuple_GET_SIZE(args);
- if (l < min) {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
- name, (min == max ? "" : "at least "), (int)min, (int)l);
- return 0;
- } else if (l > max) {
- PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
- name, (min == max ? "" : "at most "), (int)max, (int)l);
- return 0;
- } else {
- register int i;
- for (i = 0; i < l; ++i) {
- objs[i] = PyTuple_GET_ITEM(args, i);
- }
- for (; l < max; ++l) {
- objs[l] = 0;
- }
- return i + 1;
- }
- }
-}
-
-/* A functor is a function object with one single object argument */
-#if PY_VERSION_HEX >= 0x02020000
-#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
-#else
-#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj);
-#endif
-
-/*
- Helper for static pointer initialization for both C and C++ code, for example
- static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
-*/
-#ifdef __cplusplus
-#define SWIG_STATIC_POINTER(var) var
-#else
-#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
-#endif
-
-/* -----------------------------------------------------------------------------
- * Pointer declarations
- * ----------------------------------------------------------------------------- */
-
-/* Flags for new pointer objects */
-#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
-#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
-
-#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-} /* cc-mode */
-#endif
-#endif
-
-/* How to access Py_None */
-#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-# ifndef SWIG_PYTHON_NO_BUILD_NONE
-# ifndef SWIG_PYTHON_BUILD_NONE
-# define SWIG_PYTHON_BUILD_NONE
-# endif
-# endif
-#endif
-
-#ifdef SWIG_PYTHON_BUILD_NONE
-# ifdef Py_None
-# undef Py_None
-# define Py_None SWIG_Py_None()
-# endif
-SWIGRUNTIMEINLINE PyObject *
-_SWIG_Py_None(void)
-{
- PyObject *none = Py_BuildValue((char*)"");
- Py_DECREF(none);
- return none;
-}
-SWIGRUNTIME PyObject *
-SWIG_Py_None(void)
-{
- static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
- return none;
-}
-#endif
-
-/* The python void return value */
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Py_Void(void)
-{
- PyObject *none = Py_None;
- Py_INCREF(none);
- return none;
-}
-
-/* PySwigClientData */
-
-typedef struct {
- PyObject *klass;
- PyObject *newraw;
- PyObject *newargs;
- PyObject *destroy;
- int delargs;
- int implicitconv;
-} PySwigClientData;
-
-SWIGRUNTIMEINLINE int
-SWIG_Python_CheckImplicit(swig_type_info *ty)
-{
- PySwigClientData *data = (PySwigClientData *)ty->clientdata;
- return data ? data->implicitconv : 0;
-}
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Python_ExceptionType(swig_type_info *desc) {
- PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0;
- PyObject *klass = data ? data->klass : 0;
- return (klass ? klass : PyExc_RuntimeError);
-}
-
-
-SWIGRUNTIME PySwigClientData *
-PySwigClientData_New(PyObject* obj)
-{
- if (!obj) {
- return 0;
- } else {
- PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData));
- /* the klass element */
- data->klass = obj;
- Py_INCREF(data->klass);
- /* the newraw method and newargs arguments used to create a new raw instance */
- if (PyClass_Check(obj)) {
- data->newraw = 0;
- data->newargs = obj;
- Py_INCREF(obj);
- } else {
-#if (PY_VERSION_HEX < 0x02020000)
- data->newraw = 0;
-#else
- data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
-#endif
- if (data->newraw) {
- Py_INCREF(data->newraw);
- data->newargs = PyTuple_New(1);
- PyTuple_SetItem(data->newargs, 0, obj);
- } else {
- data->newargs = obj;
- }
- Py_INCREF(data->newargs);
- }
- /* the destroy method, aka as the C++ delete method */
- data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
- if (PyErr_Occurred()) {
- PyErr_Clear();
- data->destroy = 0;
- }
- if (data->destroy) {
- int flags;
- Py_INCREF(data->destroy);
- flags = PyCFunction_GET_FLAGS(data->destroy);
-#ifdef METH_O
- data->delargs = !(flags & (METH_O));
-#else
- data->delargs = 0;
-#endif
- } else {
- data->delargs = 0;
- }
- data->implicitconv = 0;
- return data;
- }
-}
-
-SWIGRUNTIME void
-PySwigClientData_Del(PySwigClientData* data)
-{
- Py_XDECREF(data->newraw);
- Py_XDECREF(data->newargs);
- Py_XDECREF(data->destroy);
-}
-
-/* =============== PySwigObject =====================*/
-
-typedef struct {
- PyObject_HEAD
- void *ptr;
- swig_type_info *ty;
- int own;
- PyObject *next;
-} PySwigObject;
-
-SWIGRUNTIME PyObject *
-PySwigObject_long(PySwigObject *v)
-{
- return PyLong_FromVoidPtr(v->ptr);
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_format(const char* fmt, PySwigObject *v)
-{
- PyObject *res = NULL;
- PyObject *args = PyTuple_New(1);
- if (args) {
- if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) {
- PyObject *ofmt = PyString_FromString(fmt);
- if (ofmt) {
- res = PyString_Format(ofmt,args);
- Py_DECREF(ofmt);
- }
- Py_DECREF(args);
- }
- }
- return res;
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_oct(PySwigObject *v)
-{
- return PySwigObject_format("%o",v);
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_hex(PySwigObject *v)
-{
- return PySwigObject_format("%x",v);
-}
-
-SWIGRUNTIME PyObject *
-#ifdef METH_NOARGS
-PySwigObject_repr(PySwigObject *v)
-#else
-PySwigObject_repr(PySwigObject *v, PyObject *args)
-#endif
-{
- const char *name = SWIG_TypePrettyName(v->ty);
- PyObject *hex = PySwigObject_hex(v);
- PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
- Py_DECREF(hex);
- if (v->next) {
-#ifdef METH_NOARGS
- PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next);
-#else
- PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args);
-#endif
- PyString_ConcatAndDel(&repr,nrep);
- }
- return repr;
-}
-
-SWIGRUNTIME int
-PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
-{
-#ifdef METH_NOARGS
- PyObject *repr = PySwigObject_repr(v);
-#else
- PyObject *repr = PySwigObject_repr(v, NULL);
-#endif
- if (repr) {
- fputs(PyString_AsString(repr), fp);
- Py_DECREF(repr);
- return 0;
- } else {
- return 1;
- }
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_str(PySwigObject *v)
-{
- char result[SWIG_BUFFER_SIZE];
- return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
- PyString_FromString(result) : 0;
-}
-
-SWIGRUNTIME int
-PySwigObject_compare(PySwigObject *v, PySwigObject *w)
-{
- void *i = v->ptr;
- void *j = w->ptr;
- return (i < j) ? -1 : ((i > j) ? 1 : 0);
-}
-
-SWIGRUNTIME PyTypeObject* _PySwigObject_type(void);
-
-SWIGRUNTIME PyTypeObject*
-PySwigObject_type(void) {
- static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type();
- return type;
-}
-
-SWIGRUNTIMEINLINE int
-PySwigObject_Check(PyObject *op) {
- return ((op)->ob_type == PySwigObject_type())
- || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_New(void *ptr, swig_type_info *ty, int own);
-
-SWIGRUNTIME void
-PySwigObject_dealloc(PyObject *v)
-{
- PySwigObject *sobj = (PySwigObject *) v;
- PyObject *next = sobj->next;
- if (sobj->own == SWIG_POINTER_OWN) {
- swig_type_info *ty = sobj->ty;
- PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
- PyObject *destroy = data ? data->destroy : 0;
- if (destroy) {
- /* destroy is always a VARARGS method */
- PyObject *res;
- if (data->delargs) {
- /* we need to create a temporal object to carry the destroy operation */
- PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0);
- res = SWIG_Python_CallFunctor(destroy, tmp);
- Py_DECREF(tmp);
- } else {
- PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
- PyObject *mself = PyCFunction_GET_SELF(destroy);
- res = ((*meth)(mself, v));
- }
- Py_XDECREF(res);
- }
-#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
- else {
- const char *name = SWIG_TypePrettyName(ty);
- printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
- }
-#endif
- }
- Py_XDECREF(next);
- PyObject_DEL(v);
-}
-
-SWIGRUNTIME PyObject*
-PySwigObject_append(PyObject* v, PyObject* next)
-{
- PySwigObject *sobj = (PySwigObject *) v;
-#ifndef METH_O
- PyObject *tmp = 0;
- if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
- next = tmp;
-#endif
- if (!PySwigObject_Check(next)) {
- return NULL;
- }
- sobj->next = next;
- Py_INCREF(next);
- return SWIG_Py_Void();
-}
-
-SWIGRUNTIME PyObject*
-#ifdef METH_NOARGS
-PySwigObject_next(PyObject* v)
-#else
-PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-#endif
-{
- PySwigObject *sobj = (PySwigObject *) v;
- if (sobj->next) {
- Py_INCREF(sobj->next);
- return sobj->next;
- } else {
- return SWIG_Py_Void();
- }
-}
-
-SWIGINTERN PyObject*
-#ifdef METH_NOARGS
-PySwigObject_disown(PyObject *v)
-#else
-PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-#endif
-{
- PySwigObject *sobj = (PySwigObject *)v;
- sobj->own = 0;
- return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject*
-#ifdef METH_NOARGS
-PySwigObject_acquire(PyObject *v)
-#else
-PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
-#endif
-{
- PySwigObject *sobj = (PySwigObject *)v;
- sobj->own = SWIG_POINTER_OWN;
- return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject*
-PySwigObject_own(PyObject *v, PyObject *args)
-{
- PyObject *val = 0;
-#if (PY_VERSION_HEX < 0x02020000)
- if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
-#else
- if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
-#endif
- {
- return NULL;
- }
- else
- {
- PySwigObject *sobj = (PySwigObject *)v;
- PyObject *obj = PyBool_FromLong(sobj->own);
- if (val) {
-#ifdef METH_NOARGS
- if (PyObject_IsTrue(val)) {
- PySwigObject_acquire(v);
- } else {
- PySwigObject_disown(v);
- }
-#else
- if (PyObject_IsTrue(val)) {
- PySwigObject_acquire(v,args);
- } else {
- PySwigObject_disown(v,args);
- }
-#endif
- }
- return obj;
- }
-}
-
-#ifdef METH_O
-static PyMethodDef
-swigobject_methods[] = {
- {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"},
- {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"},
- {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
- {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"},
- {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"},
- {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"},
- {0, 0, 0, 0}
-};
-#else
-static PyMethodDef
-swigobject_methods[] = {
- {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"},
- {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"},
- {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
- {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"},
- {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"},
- {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"},
- {0, 0, 0, 0}
-};
-#endif
-
-#if PY_VERSION_HEX < 0x02020000
-SWIGINTERN PyObject *
-PySwigObject_getattr(PySwigObject *sobj,char *name)
-{
- return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
-}
-#endif
-
-SWIGRUNTIME PyTypeObject*
-_PySwigObject_type(void) {
- static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
-
- static PyNumberMethods PySwigObject_as_number = {
- (binaryfunc)0, /*nb_add*/
- (binaryfunc)0, /*nb_subtract*/
- (binaryfunc)0, /*nb_multiply*/
- (binaryfunc)0, /*nb_divide*/
- (binaryfunc)0, /*nb_remainder*/
- (binaryfunc)0, /*nb_divmod*/
- (ternaryfunc)0,/*nb_power*/
- (unaryfunc)0, /*nb_negative*/
- (unaryfunc)0, /*nb_positive*/
- (unaryfunc)0, /*nb_absolute*/
- (inquiry)0, /*nb_nonzero*/
- 0, /*nb_invert*/
- 0, /*nb_lshift*/
- 0, /*nb_rshift*/
- 0, /*nb_and*/
- 0, /*nb_xor*/
- 0, /*nb_or*/
- (coercion)0, /*nb_coerce*/
- (unaryfunc)PySwigObject_long, /*nb_int*/
- (unaryfunc)PySwigObject_long, /*nb_long*/
- (unaryfunc)0, /*nb_float*/
- (unaryfunc)PySwigObject_oct, /*nb_oct*/
- (unaryfunc)PySwigObject_hex, /*nb_hex*/
-#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
-#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
-#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
- 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
-#endif
- };
-
- static PyTypeObject pyswigobject_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp
- = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- (char *)"PySwigObject", /* tp_name */
- sizeof(PySwigObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)PySwigObject_dealloc, /* tp_dealloc */
- (printfunc)PySwigObject_print, /* tp_print */
-#if PY_VERSION_HEX < 0x02020000
- (getattrfunc)PySwigObject_getattr, /* tp_getattr */
-#else
- (getattrfunc)0, /* tp_getattr */
-#endif
- (setattrfunc)0, /* tp_setattr */
- (cmpfunc)PySwigObject_compare, /* tp_compare */
- (reprfunc)PySwigObject_repr, /* tp_repr */
- &PySwigObject_as_number, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)0, /* tp_hash */
- (ternaryfunc)0, /* tp_call */
- (reprfunc)PySwigObject_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- swigobject_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
-#if PY_VERSION_HEX >= 0x02020000
- 0, /* tp_iter */
- 0, /* tp_iternext */
- swigobject_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
-#endif
-#if PY_VERSION_HEX >= 0x02030000
- 0, /* tp_del */
-#endif
-#ifdef COUNT_ALLOCS
- 0,0,0,0 /* tp_alloc -> tp_next */
-#endif
- };
- pyswigobject_type = tmp;
- pyswigobject_type.ob_type = &PyType_Type;
- type_init = 1;
- }
- return &pyswigobject_type;
-}
-
-SWIGRUNTIME PyObject *
-PySwigObject_New(void *ptr, swig_type_info *ty, int own)
-{
- PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type());
- if (sobj) {
- sobj->ptr = ptr;
- sobj->ty = ty;
- sobj->own = own;
- sobj->next = 0;
- }
- return (PyObject *)sobj;
-}
-
-/* -----------------------------------------------------------------------------
- * Implements a simple Swig Packed type, and use it instead of string
- * ----------------------------------------------------------------------------- */
-
-typedef struct {
- PyObject_HEAD
- void *pack;
- swig_type_info *ty;
- size_t size;
-} PySwigPacked;
-
-SWIGRUNTIME int
-PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
-{
- char result[SWIG_BUFFER_SIZE];
- fputs("<Swig Packed ", fp);
- if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
- fputs("at ", fp);
- fputs(result, fp);
- }
- fputs(v->ty->name,fp);
- fputs(">", fp);
- return 0;
-}
-
-SWIGRUNTIME PyObject *
-PySwigPacked_repr(PySwigPacked *v)
-{
- char result[SWIG_BUFFER_SIZE];
- if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
- return PyString_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
- } else {
- return PyString_FromFormat("<Swig Packed %s>", v->ty->name);
- }
-}
-
-SWIGRUNTIME PyObject *
-PySwigPacked_str(PySwigPacked *v)
-{
- char result[SWIG_BUFFER_SIZE];
- if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
- return PyString_FromFormat("%s%s", result, v->ty->name);
- } else {
- return PyString_FromString(v->ty->name);
- }
-}
-
-SWIGRUNTIME int
-PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w)
-{
- size_t i = v->size;
- size_t j = w->size;
- int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
- return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
-}
-
-SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void);
-
-SWIGRUNTIME PyTypeObject*
-PySwigPacked_type(void) {
- static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type();
- return type;
-}
-
-SWIGRUNTIMEINLINE int
-PySwigPacked_Check(PyObject *op) {
- return ((op)->ob_type == _PySwigPacked_type())
- || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0);
-}
-
-SWIGRUNTIME void
-PySwigPacked_dealloc(PyObject *v)
-{
- if (PySwigPacked_Check(v)) {
- PySwigPacked *sobj = (PySwigPacked *) v;
- free(sobj->pack);
- }
- PyObject_DEL(v);
-}
-
-SWIGRUNTIME PyTypeObject*
-_PySwigPacked_type(void) {
- static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
- static PyTypeObject pyswigpacked_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp
- = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- (char *)"PySwigPacked", /* tp_name */
- sizeof(PySwigPacked), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)PySwigPacked_dealloc, /* tp_dealloc */
- (printfunc)PySwigPacked_print, /* tp_print */
- (getattrfunc)0, /* tp_getattr */
- (setattrfunc)0, /* tp_setattr */
- (cmpfunc)PySwigPacked_compare, /* tp_compare */
- (reprfunc)PySwigPacked_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)0, /* tp_hash */
- (ternaryfunc)0, /* tp_call */
- (reprfunc)PySwigPacked_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- swigpacked_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
-#if PY_VERSION_HEX >= 0x02020000
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
-#endif
-#if PY_VERSION_HEX >= 0x02030000
- 0, /* tp_del */
-#endif
-#ifdef COUNT_ALLOCS
- 0,0,0,0 /* tp_alloc -> tp_next */
-#endif
- };
- pyswigpacked_type = tmp;
- pyswigpacked_type.ob_type = &PyType_Type;
- type_init = 1;
- }
- return &pyswigpacked_type;
-}
-
-SWIGRUNTIME PyObject *
-PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
-{
- PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type());
- if (sobj) {
- void *pack = malloc(size);
- if (pack) {
- memcpy(pack, ptr, size);
- sobj->pack = pack;
- sobj->ty = ty;
- sobj->size = size;
- } else {
- PyObject_DEL((PyObject *) sobj);
- sobj = 0;
- }
- }
- return (PyObject *) sobj;
-}
-
-SWIGRUNTIME swig_type_info *
-PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
-{
- if (PySwigPacked_Check(obj)) {
- PySwigPacked *sobj = (PySwigPacked *)obj;
- if (sobj->size != size) return 0;
- memcpy(ptr, sobj->pack, size);
- return sobj->ty;
- } else {
- return 0;
- }
-}
-
-/* -----------------------------------------------------------------------------
- * pointers/data manipulation
- * ----------------------------------------------------------------------------- */
-
-SWIGRUNTIMEINLINE PyObject *
-_SWIG_This(void)
-{
- return PyString_FromString("this");
-}
-
-SWIGRUNTIME PyObject *
-SWIG_This(void)
-{
- static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
- return swig_this;
-}
-
-/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
-
-SWIGRUNTIME PySwigObject *
-SWIG_Python_GetSwigThis(PyObject *pyobj)
-{
- if (PySwigObject_Check(pyobj)) {
- return (PySwigObject *) pyobj;
- } else {
- PyObject *obj = 0;
-#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
- if (PyInstance_Check(pyobj)) {
- obj = _PyInstance_Lookup(pyobj, SWIG_This());
- } else {
- PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
- if (dictptr != NULL) {
- PyObject *dict = *dictptr;
- obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
- } else {
-#ifdef PyWeakref_CheckProxy
- if (PyWeakref_CheckProxy(pyobj)) {
- PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
- return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
- }
-#endif
- obj = PyObject_GetAttr(pyobj,SWIG_This());
- if (obj) {
- Py_DECREF(obj);
- } else {
- if (PyErr_Occurred()) PyErr_Clear();
- return 0;
- }
- }
- }
-#else
- obj = PyObject_GetAttr(pyobj,SWIG_This());
- if (obj) {
- Py_DECREF(obj);
- } else {
- if (PyErr_Occurred()) PyErr_Clear();
- return 0;
- }
-#endif
- if (obj && !PySwigObject_Check(obj)) {
- /* a PyObject is called 'this', try to get the 'real this'
- PySwigObject from it */
- return SWIG_Python_GetSwigThis(obj);
- }
- return (PySwigObject *)obj;
- }
-}
-
-/* Acquire a pointer value */
-
-SWIGRUNTIME int
-SWIG_Python_AcquirePtr(PyObject *obj, int own) {
- if (own == SWIG_POINTER_OWN) {
- PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
- if (sobj) {
- int oldown = sobj->own;
- sobj->own = own;
- return oldown;
- }
- }
- return 0;
-}
-
-/* Convert a pointer value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
- if (!obj) return SWIG_ERROR;
- if (obj == Py_None) {
- if (ptr) *ptr = 0;
- return SWIG_OK;
- } else {
- PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
- if (own)
- *own = 0;
- while (sobj) {
- void *vptr = sobj->ptr;
- if (ty) {
- swig_type_info *to = sobj->ty;
- if (to == ty) {
- /* no type cast needed */
- if (ptr) *ptr = vptr;
- break;
- } else {
- swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
- if (!tc) {
- sobj = (PySwigObject *)sobj->next;
- } else {
- if (ptr) {
- int newmemory = 0;
- *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
- if (newmemory == SWIG_CAST_NEW_MEMORY) {
- assert(own);
- if (own)
- *own = *own | SWIG_CAST_NEW_MEMORY;
- }
- }
- break;
- }
- }
- } else {
- if (ptr) *ptr = vptr;
- break;
- }
- }
- if (sobj) {
- if (own)
- *own = *own | sobj->own;
- if (flags & SWIG_POINTER_DISOWN) {
- sobj->own = 0;
- }
- return SWIG_OK;
- } else {
- int res = SWIG_ERROR;
- if (flags & SWIG_POINTER_IMPLICIT_CONV) {
- PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
- if (data && !data->implicitconv) {
- PyObject *klass = data->klass;
- if (klass) {
- PyObject *impconv;
- data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
- impconv = SWIG_Python_CallFunctor(klass, obj);
- data->implicitconv = 0;
- if (PyErr_Occurred()) {
- PyErr_Clear();
- impconv = 0;
- }
- if (impconv) {
- PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv);
- if (iobj) {
- void *vptr;
- res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
- if (SWIG_IsOK(res)) {
- if (ptr) {
- *ptr = vptr;
- /* transfer the ownership to 'ptr' */
- iobj->own = 0;
- res = SWIG_AddCast(res);
- res = SWIG_AddNewMask(res);
- } else {
- res = SWIG_AddCast(res);
- }
- }
- }
- Py_DECREF(impconv);
- }
- }
- }
- }
- return res;
- }
- }
-}
-
-/* Convert a function ptr value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
- if (!PyCFunction_Check(obj)) {
- return SWIG_ConvertPtr(obj, ptr, ty, 0);
- } else {
- void *vptr = 0;
-
- /* here we get the method pointer for callbacks */
- const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
- const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
- if (desc) {
- desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
- if (!desc) return SWIG_ERROR;
- }
- if (ty) {
- swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
- if (tc) {
- int newmemory = 0;
- *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
- } else {
- return SWIG_ERROR;
- }
- } else {
- *ptr = vptr;
- }
- return SWIG_OK;
- }
-}
-
-/* Convert a packed value value */
-
-SWIGRUNTIME int
-SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
- swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz);
- if (!to) return SWIG_ERROR;
- if (ty) {
- if (to != ty) {
- /* check type cast? */
- swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
- if (!tc) return SWIG_ERROR;
- }
- }
- return SWIG_OK;
-}
-
-/* -----------------------------------------------------------------------------
- * Create a new pointer object
- * ----------------------------------------------------------------------------- */
-
-/*
- Create a new instance object, whitout calling __init__, and set the
- 'this' attribute.
-*/
-
-SWIGRUNTIME PyObject*
-SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
-{
-#if (PY_VERSION_HEX >= 0x02020000)
- PyObject *inst = 0;
- PyObject *newraw = data->newraw;
- if (newraw) {
- inst = PyObject_Call(newraw, data->newargs, NULL);
- if (inst) {
-#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
- PyObject *dict = *dictptr;
- if (dict == NULL) {
- dict = PyDict_New();
- *dictptr = dict;
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- }
- }
-#else
- PyObject *key = SWIG_This();
- PyObject_SetAttr(inst, key, swig_this);
-#endif
- }
- } else {
- PyObject *dict = PyDict_New();
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- inst = PyInstance_NewRaw(data->newargs, dict);
- Py_DECREF(dict);
- }
- return inst;
-#else
-#if (PY_VERSION_HEX >= 0x02010000)
- PyObject *inst;
- PyObject *dict = PyDict_New();
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- inst = PyInstance_NewRaw(data->newargs, dict);
- Py_DECREF(dict);
- return (PyObject *) inst;
-#else
- PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
- if (inst == NULL) {
- return NULL;
- }
- inst->in_class = (PyClassObject *)data->newargs;
- Py_INCREF(inst->in_class);
- inst->in_dict = PyDict_New();
- if (inst->in_dict == NULL) {
- Py_DECREF(inst);
- return NULL;
- }
-#ifdef Py_TPFLAGS_HAVE_WEAKREFS
- inst->in_weakreflist = NULL;
-#endif
-#ifdef Py_TPFLAGS_GC
- PyObject_GC_Init(inst);
-#endif
- PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
- return (PyObject *) inst;
-#endif
-#endif
-}
-
-SWIGRUNTIME void
-SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
-{
- PyObject *dict;
-#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
- dict = *dictptr;
- if (dict == NULL) {
- dict = PyDict_New();
- *dictptr = dict;
- }
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- return;
- }
-#endif
- dict = PyObject_GetAttrString(inst, (char*)"__dict__");
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- Py_DECREF(dict);
-}
-
-
-SWIGINTERN PyObject *
-SWIG_Python_InitShadowInstance(PyObject *args) {
- PyObject *obj[2];
- if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
- return NULL;
- } else {
- PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
- if (sthis) {
- PySwigObject_append((PyObject*) sthis, obj[1]);
- } else {
- SWIG_Python_SetSwigThis(obj[0], obj[1]);
- }
- return SWIG_Py_Void();
- }
-}
-
-/* Create a new pointer object */
-
-SWIGRUNTIME PyObject *
-SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
- if (!ptr) {
- return SWIG_Py_Void();
- } else {
- int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
- PyObject *robj = PySwigObject_New(ptr, type, own);
- PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0;
- if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
- PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
- if (inst) {
- Py_DECREF(robj);
- robj = inst;
- }
- }
- return robj;
- }
-}
-
-/* Create a new packed object */
-
-SWIGRUNTIMEINLINE PyObject *
-SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
- return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
-}
-
-/* -----------------------------------------------------------------------------*
- * Get type list
- * -----------------------------------------------------------------------------*/
-
-#ifdef SWIG_LINK_RUNTIME
-void *SWIG_ReturnGlobalTypeList(void *);
-#endif
-
-SWIGRUNTIME swig_module_info *
-SWIG_Python_GetModule(void) {
- static void *type_pointer = (void *)0;
- /* first check if module already created */
- if (!type_pointer) {
-#ifdef SWIG_LINK_RUNTIME
- type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
-#else
- type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
- (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- type_pointer = (void *)0;
- }
-#endif
- }
- return (swig_module_info *) type_pointer;
-}
-
-#if PY_MAJOR_VERSION < 2
-/* PyModule_AddObject function was introduced in Python 2.0. The following function
- is copied out of Python/modsupport.c in python version 2.3.4 */
-SWIGINTERN int
-PyModule_AddObject(PyObject *m, char *name, PyObject *o)
-{
- PyObject *dict;
- if (!PyModule_Check(m)) {
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs module as first arg");
- return SWIG_ERROR;
- }
- if (!o) {
- PyErr_SetString(PyExc_TypeError,
- "PyModule_AddObject() needs non-NULL value");
- return SWIG_ERROR;
- }
-
- dict = PyModule_GetDict(m);
- if (dict == NULL) {
- /* Internal error -- modules must have a dict! */
- PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
- PyModule_GetName(m));
- return SWIG_ERROR;
- }
- if (PyDict_SetItemString(dict, name, o))
- return SWIG_ERROR;
- Py_DECREF(o);
- return SWIG_OK;
-}
-#endif
-
-SWIGRUNTIME void
-SWIG_Python_DestroyModule(void *vptr)
-{
- swig_module_info *swig_module = (swig_module_info *) vptr;
- swig_type_info **types = swig_module->types;
- size_t i;
- for (i =0; i < swig_module->size; ++i) {
- swig_type_info *ty = types[i];
- if (ty->owndata) {
- PySwigClientData *data = (PySwigClientData *) ty->clientdata;
- if (data) PySwigClientData_Del(data);
- }
- }
- Py_DECREF(SWIG_This());
-}
-
-SWIGRUNTIME void
-SWIG_Python_SetModule(swig_module_info *swig_module) {
- static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */
-
- PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
- swig_empty_runtime_method_table);
- PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
- if (pointer && module) {
- PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
- } else {
- Py_XDECREF(pointer);
- }
-}
-
-/* The python cached type query */
-SWIGRUNTIME PyObject *
-SWIG_Python_TypeCache(void) {
- static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
- return cache;
-}
-
-SWIGRUNTIME swig_type_info *
-SWIG_Python_TypeQuery(const char *type)
-{
- PyObject *cache = SWIG_Python_TypeCache();
- PyObject *key = PyString_FromString(type);
- PyObject *obj = PyDict_GetItem(cache, key);
- swig_type_info *descriptor;
- if (obj) {
- descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
- } else {
- swig_module_info *swig_module = SWIG_Python_GetModule();
- descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
- if (descriptor) {
- obj = PyCObject_FromVoidPtr(descriptor, NULL);
- PyDict_SetItem(cache, key, obj);
- Py_DECREF(obj);
- }
- }
- Py_DECREF(key);
- return descriptor;
-}
-
-/*
- For backward compatibility only
-*/
-#define SWIG_POINTER_EXCEPTION 0
-#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
-#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
-
-SWIGRUNTIME int
-SWIG_Python_AddErrMesg(const char* mesg, int infront)
-{
- if (PyErr_Occurred()) {
- PyObject *type = 0;
- PyObject *value = 0;
- PyObject *traceback = 0;
- PyErr_Fetch(&type, &value, &traceback);
- if (value) {
- PyObject *old_str = PyObject_Str(value);
- Py_XINCREF(type);
- PyErr_Clear();
- if (infront) {
- PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str));
- } else {
- PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
- }
- Py_DECREF(old_str);
- }
- return 1;
- } else {
- return 0;
- }
-}
-
-SWIGRUNTIME int
-SWIG_Python_ArgFail(int argnum)
-{
- if (PyErr_Occurred()) {
- /* add information about failing argument */
- char mesg[256];
- PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
- return SWIG_Python_AddErrMesg(mesg, 1);
- } else {
- return 0;
- }
-}
-
-SWIGRUNTIMEINLINE const char *
-PySwigObject_GetDesc(PyObject *self)
-{
- PySwigObject *v = (PySwigObject *)self;
- swig_type_info *ty = v ? v->ty : 0;
- return ty ? ty->str : (char*)"";
-}
-
-SWIGRUNTIME void
-SWIG_Python_TypeError(const char *type, PyObject *obj)
-{
- if (type) {
-#if defined(SWIG_COBJECT_TYPES)
- if (obj && PySwigObject_Check(obj)) {
- const char *otype = (const char *) PySwigObject_GetDesc(obj);
- if (otype) {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received",
- type, otype);
- return;
- }
- } else
-#endif
- {
- const char *otype = (obj ? obj->ob_type->tp_name : 0);
- if (otype) {
- PyObject *str = PyObject_Str(obj);
- const char *cstr = str ? PyString_AsString(str) : 0;
- if (cstr) {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
- type, otype, cstr);
- } else {
- PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
- type, otype);
- }
- Py_XDECREF(str);
- return;
- }
- }
- PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
- } else {
- PyErr_Format(PyExc_TypeError, "unexpected type is received");
- }
-}
-
-
-/* Convert a pointer value, signal an exception on a type mismatch */
-SWIGRUNTIME void *
-SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) {
- void *result;
- if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
- PyErr_Clear();
- if (flags & SWIG_POINTER_EXCEPTION) {
- SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
- SWIG_Python_ArgFail(argnum);
- }
- }
- return result;
-}
-
-
-#ifdef __cplusplus
-#if 0
-{ /* cc-mode */
-#endif
-}
-#endif
-
-
-
-#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
-
-#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
-
-
-
-/* -------- TYPES TABLE (BEGIN) -------- */
-
-#define SWIGTYPE_p_TALLOC_CTX swig_types[0]
-#define SWIGTYPE_p_char swig_types[1]
-#define SWIGTYPE_p_event_context swig_types[2]
-#define SWIGTYPE_p_p_char swig_types[3]
-static swig_type_info *swig_types[5];
-static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0};
-#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
-#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
-
-/* -------- TYPES TABLE (END) -------- */
-
-#if (PY_VERSION_HEX <= 0x02000000)
-# if !defined(SWIG_PYTHON_CLASSIC)
-# error "This python version requires swig to be run with the '-classic' option"
-# endif
-#endif
-#if (PY_VERSION_HEX <= 0x02020000)
-# error "This python version requires swig to be run with the '-nomodern' option"
-#endif
-#if (PY_VERSION_HEX <= 0x02020000)
-# error "This python version requires swig to be run with the '-nomodernargs' option"
-#endif
-#ifndef METH_O
-# error "This python version requires swig to be run with the '-nofastunpack' option"
-#endif
-#ifdef SWIG_TypeQuery
-# undef SWIG_TypeQuery
-#endif
-#define SWIG_TypeQuery SWIG_Python_TypeQuery
-
-/*-----------------------------------------------
- @(target):= _events.so
- ------------------------------------------------*/
-#define SWIG_init init_events
-
-#define SWIG_name "_events"
-
-#define SWIGVERSION 0x010336
-#define SWIG_VERSION SWIGVERSION
-
-
-#define SWIG_as_voidptr(a) (void *)((const void *)(a))
-#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a))
-
-
-#include "events.h"
-typedef struct event_context event;
-
-SWIGINTERN event *new_event(TALLOC_CTX *mem_ctx){ return event_context_init(mem_ctx); }
-
- #define SWIG_From_long PyInt_FromLong
-
-
-SWIGINTERNINLINE PyObject *
-SWIG_From_int (int value)
-{
- return SWIG_From_long (value);
-}
-
-SWIGINTERN void delete_event(event *self){ talloc_free(self); }
-
-SWIGINTERN swig_type_info*
-SWIG_pchar_descriptor(void)
-{
- static int init = 0;
- static swig_type_info* info = 0;
- if (!init) {
- info = SWIG_TypeQuery("_p_char");
- init = 1;
- }
- return info;
-}
-
-
-SWIGINTERN int
-SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
-{
- if (PyString_Check(obj)) {
- char *cstr; Py_ssize_t len;
- PyString_AsStringAndSize(obj, &cstr, &len);
- if (cptr) {
- if (alloc) {
- /*
- In python the user should not be able to modify the inner
- string representation. To warranty that, if you define
- SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
- buffer is always returned.
-
- The default behavior is just to return the pointer value,
- so, be careful.
- */
-#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
- if (*alloc != SWIG_OLDOBJ)
-#else
- if (*alloc == SWIG_NEWOBJ)
-#endif
- {
- *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
- *alloc = SWIG_NEWOBJ;
- }
- else {
- *cptr = cstr;
- *alloc = SWIG_OLDOBJ;
- }
- } else {
- *cptr = PyString_AsString(obj);
- }
- }
- if (psize) *psize = len + 1;
- return SWIG_OK;
- } else {
- swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
- if (pchar_descriptor) {
- void* vptr = 0;
- if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
- if (cptr) *cptr = (char *) vptr;
- if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
- if (alloc) *alloc = SWIG_OLDOBJ;
- return SWIG_OK;
- }
- }
- }
- return SWIG_TypeError;
-}
-
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-SWIGINTERN PyObject *_wrap_new_event(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ;
- event *result = 0 ;
-
- arg1 = NULL;
- if (!SWIG_Python_UnpackTuple(args,"new_event",0,0,0)) SWIG_fail;
- result = (event *)new_event(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_event_context, SWIG_POINTER_NEW | 0 );
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_event_loop_once(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- event *arg1 = (event *) 0 ;
- void *argp1 = 0 ;
- int res1 = 0 ;
- PyObject *swig_obj[1] ;
- int result;
-
- if (!args) SWIG_fail;
- swig_obj[0] = args;
- res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, 0 | 0 );
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "event_loop_once" "', argument " "1"" of type '" "event *""'");
- }
- arg1 = (event *)(argp1);
- result = (int)event_loop_once(arg1);
- resultobj = SWIG_From_int((int)(result));
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_event_loop_wait(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- event *arg1 = (event *) 0 ;
- void *argp1 = 0 ;
- int res1 = 0 ;
- PyObject *swig_obj[1] ;
- int result;
-
- if (!args) SWIG_fail;
- swig_obj[0] = args;
- res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, 0 | 0 );
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "event_loop_wait" "', argument " "1"" of type '" "event *""'");
- }
- arg1 = (event *)(argp1);
- result = (int)event_loop_wait(arg1);
- resultobj = SWIG_From_int((int)(result));
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_delete_event(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- event *arg1 = (event *) 0 ;
- void *argp1 = 0 ;
- int res1 = 0 ;
- PyObject *swig_obj[1] ;
-
- if (!args) SWIG_fail;
- swig_obj[0] = args;
- res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_event_context, SWIG_POINTER_DISOWN | 0 );
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_event" "', argument " "1"" of type '" "event *""'");
- }
- arg1 = (event *)(argp1);
- delete_event(arg1);
- resultobj = SWIG_Py_Void();
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *event_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *obj;
- if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL;
- SWIG_TypeNewClientData(SWIGTYPE_p_event_context, SWIG_NewClientData(obj));
- return SWIG_Py_Void();
-}
-
-SWIGINTERN PyObject *event_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- return SWIG_Python_InitShadowInstance(args);
-}
-
-SWIGINTERN PyObject *_wrap_event_context_init_byname(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
- PyObject *resultobj = 0;
- TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ;
- char *arg2 = (char *) 0 ;
- int res2 ;
- char *buf2 = 0 ;
- int alloc2 = 0 ;
- PyObject * obj0 = 0 ;
- char * kwnames[] = {
- (char *) "name", NULL
- };
- struct event_context *result = 0 ;
-
- arg1 = NULL;
- if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:event_context_init_byname",kwnames,&obj0)) SWIG_fail;
- res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2);
- if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "event_context_init_byname" "', argument " "2"" of type '" "char const *""'");
- }
- arg2 = (char *)(buf2);
- result = (struct event_context *)event_context_init_byname(arg1,(char const *)arg2);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_event_context, 0 | 0 );
- if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
- return resultobj;
-fail:
- if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_event_backend_list(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ;
- char **result = 0 ;
-
- arg1 = NULL;
- if (!SWIG_Python_UnpackTuple(args,"event_backend_list",0,0,0)) SWIG_fail;
- result = (char **)event_backend_list(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_char, 0 | 0 );
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_set_default_backend(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
- PyObject *resultobj = 0;
- char *arg1 = (char *) 0 ;
- int res1 ;
- char *buf1 = 0 ;
- int alloc1 = 0 ;
- PyObject * obj0 = 0 ;
- char * kwnames[] = {
- (char *) "backend", NULL
- };
-
- if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:set_default_backend",kwnames,&obj0)) SWIG_fail;
- res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "set_default_backend" "', argument " "1"" of type '" "char const *""'");
- }
- arg1 = (char *)(buf1);
- event_set_default_backend((char const *)arg1);
- resultobj = SWIG_Py_Void();
- if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
- return resultobj;
-fail:
- if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
- return NULL;
-}
-
-
-static PyMethodDef SwigMethods[] = {
- { (char *)"new_event", (PyCFunction)_wrap_new_event, METH_NOARGS, (char *)"S.__init__()"},
- { (char *)"event_loop_once", (PyCFunction)_wrap_event_loop_once, METH_O, (char *)"S.loop_once() -> int"},
- { (char *)"event_loop_wait", (PyCFunction)_wrap_event_loop_wait, METH_O, (char *)"S.loop_wait() -> int"},
- { (char *)"delete_event", (PyCFunction)_wrap_delete_event, METH_O, NULL},
- { (char *)"event_swigregister", event_swigregister, METH_VARARGS, NULL},
- { (char *)"event_swiginit", event_swiginit, METH_VARARGS, NULL},
- { (char *)"event_context_init_byname", (PyCFunction) _wrap_event_context_init_byname, METH_VARARGS | METH_KEYWORDS, NULL},
- { (char *)"event_backend_list", (PyCFunction)_wrap_event_backend_list, METH_NOARGS, (char *)"event_backend_list() -> list"},
- { (char *)"set_default_backend", (PyCFunction) _wrap_set_default_backend, METH_VARARGS | METH_KEYWORDS, (char *)"event_set_default_backend(name) -> None"},
- { NULL, NULL, 0, NULL }
-};
-
-
-/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
-
-static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_event_context = {"_p_event_context", "struct event_context *|event *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
-
-static swig_type_info *swig_type_initial[] = {
- &_swigt__p_TALLOC_CTX,
- &_swigt__p_char,
- &_swigt__p_event_context,
- &_swigt__p_p_char,
-};
-
-static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_event_context[] = { {&_swigt__p_event_context, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
-
-static swig_cast_info *swig_cast_initial[] = {
- _swigc__p_TALLOC_CTX,
- _swigc__p_char,
- _swigc__p_event_context,
- _swigc__p_p_char,
-};
-
-
-/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
-
-static swig_const_info swig_const_table[] = {
-{0, 0, 0, 0.0, 0, 0}};
-
-#ifdef __cplusplus
-}
-#endif
-/* -----------------------------------------------------------------------------
- * Type initialization:
- * This problem is tough by the requirement that no dynamic
- * memory is used. Also, since swig_type_info structures store pointers to
- * swig_cast_info structures and swig_cast_info structures store pointers back
- * to swig_type_info structures, we need some lookup code at initialization.
- * The idea is that swig generates all the structures that are needed.
- * The runtime then collects these partially filled structures.
- * The SWIG_InitializeModule function takes these initial arrays out of
- * swig_module, and does all the lookup, filling in the swig_module.types
- * array with the correct data and linking the correct swig_cast_info
- * structures together.
- *
- * The generated swig_type_info structures are assigned staticly to an initial
- * array. We just loop through that array, and handle each type individually.
- * First we lookup if this type has been already loaded, and if so, use the
- * loaded structure instead of the generated one. Then we have to fill in the
- * cast linked list. The cast data is initially stored in something like a
- * two-dimensional array. Each row corresponds to a type (there are the same
- * number of rows as there are in the swig_type_initial array). Each entry in
- * a column is one of the swig_cast_info structures for that type.
- * The cast_initial array is actually an array of arrays, because each row has
- * a variable number of columns. So to actually build the cast linked list,
- * we find the array of casts associated with the type, and loop through it
- * adding the casts to the list. The one last trick we need to do is making
- * sure the type pointer in the swig_cast_info struct is correct.
- *
- * First off, we lookup the cast->type name to see if it is already loaded.
- * There are three cases to handle:
- * 1) If the cast->type has already been loaded AND the type we are adding
- * casting info to has not been loaded (it is in this module), THEN we
- * replace the cast->type pointer with the type pointer that has already
- * been loaded.
- * 2) If BOTH types (the one we are adding casting info to, and the
- * cast->type) are loaded, THEN the cast info has already been loaded by
- * the previous module so we just ignore it.
- * 3) Finally, if cast->type has not already been loaded, then we add that
- * swig_cast_info to the linked list (because the cast->type) pointer will
- * be correct.
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-} /* c-mode */
-#endif
-#endif
-
-#if 0
-#define SWIGRUNTIME_DEBUG
-#endif
-
-
-SWIGRUNTIME void
-SWIG_InitializeModule(void *clientdata) {
- size_t i;
- swig_module_info *module_head, *iter;
- int found, init;
-
- clientdata = clientdata;
-
- /* check to see if the circular list has been setup, if not, set it up */
- if (swig_module.next==0) {
- /* Initialize the swig_module */
- swig_module.type_initial = swig_type_initial;
- swig_module.cast_initial = swig_cast_initial;
- swig_module.next = &swig_module;
- init = 1;
- } else {
- init = 0;
- }
-
- /* Try and load any already created modules */
- module_head = SWIG_GetModule(clientdata);
- if (!module_head) {
- /* This is the first module loaded for this interpreter */
- /* so set the swig module into the interpreter */
- SWIG_SetModule(clientdata, &swig_module);
- module_head = &swig_module;
- } else {
- /* the interpreter has loaded a SWIG module, but has it loaded this one? */
- found=0;
- iter=module_head;
- do {
- if (iter==&swig_module) {
- found=1;
- break;
- }
- iter=iter->next;
- } while (iter!= module_head);
-
- /* if the is found in the list, then all is done and we may leave */
- if (found) return;
- /* otherwise we must add out module into the list */
- swig_module.next = module_head->next;
- module_head->next = &swig_module;
- }
-
- /* When multiple interpeters are used, a module could have already been initialized in
- a different interpreter, but not yet have a pointer in this interpreter.
- In this case, we do not want to continue adding types... everything should be
- set up already */
- if (init == 0) return;
-
- /* Now work on filling in swig_module.types */
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: size %d\n", swig_module.size);
-#endif
- for (i = 0; i < swig_module.size; ++i) {
- swig_type_info *type = 0;
- swig_type_info *ret;
- swig_cast_info *cast;
-
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
-#endif
-
- /* if there is another module already loaded */
- if (swig_module.next != &swig_module) {
- type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
- }
- if (type) {
- /* Overwrite clientdata field */
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: found type %s\n", type->name);
-#endif
- if (swig_module.type_initial[i]->clientdata) {
- type->clientdata = swig_module.type_initial[i]->clientdata;
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
-#endif
- }
- } else {
- type = swig_module.type_initial[i];
- }
-
- /* Insert casting types */
- cast = swig_module.cast_initial[i];
- while (cast->type) {
- /* Don't need to add information already in the list */
- ret = 0;
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
-#endif
- if (swig_module.next != &swig_module) {
- ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
-#ifdef SWIGRUNTIME_DEBUG
- if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
-#endif
- }
- if (ret) {
- if (type == swig_module.type_initial[i]) {
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
-#endif
- cast->type = ret;
- ret = 0;
- } else {
- /* Check for casting already in the list */
- swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
-#ifdef SWIGRUNTIME_DEBUG
- if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
-#endif
- if (!ocast) ret = 0;
- }
- }
-
- if (!ret) {
-#ifdef SWIGRUNTIME_DEBUG
- printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
-#endif
- if (type->cast) {
- type->cast->prev = cast;
- cast->next = type->cast;
- }
- type->cast = cast;
- }
- cast++;
- }
- /* Set entry in modules->types array equal to the type */
- swig_module.types[i] = type;
- }
- swig_module.types[i] = 0;
-
-#ifdef SWIGRUNTIME_DEBUG
- printf("**** SWIG_InitializeModule: Cast List ******\n");
- for (i = 0; i < swig_module.size; ++i) {
- int j = 0;
- swig_cast_info *cast = swig_module.cast_initial[i];
- printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
- while (cast->type) {
- printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
- cast++;
- ++j;
- }
- printf("---- Total casts: %d\n",j);
- }
- printf("**** SWIG_InitializeModule: Cast List ******\n");
-#endif
-}
-
-/* This function will propagate the clientdata field of type to
-* any new swig_type_info structures that have been added into the list
-* of equivalent types. It is like calling
-* SWIG_TypeClientData(type, clientdata) a second time.
-*/
-SWIGRUNTIME void
-SWIG_PropagateClientData(void) {
- size_t i;
- swig_cast_info *equiv;
- static int init_run = 0;
-
- if (init_run) return;
- init_run = 1;
-
- for (i = 0; i < swig_module.size; i++) {
- if (swig_module.types[i]->clientdata) {
- equiv = swig_module.types[i]->cast;
- while (equiv) {
- if (!equiv->converter) {
- if (equiv->type && !equiv->type->clientdata)
- SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
- }
- equiv = equiv->next;
- }
- }
- }
-}
-
-#ifdef __cplusplus
-#if 0
-{
- /* c-mode */
-#endif
-}
-#endif
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /* Python-specific SWIG API */
-#define SWIG_newvarlink() SWIG_Python_newvarlink()
-#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
-#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
-
- /* -----------------------------------------------------------------------------
- * global variable support code.
- * ----------------------------------------------------------------------------- */
-
- typedef struct swig_globalvar {
- char *name; /* Name of global variable */
- PyObject *(*get_attr)(void); /* Return the current value */
- int (*set_attr)(PyObject *); /* Set the value */
- struct swig_globalvar *next;
- } swig_globalvar;
-
- typedef struct swig_varlinkobject {
- PyObject_HEAD
- swig_globalvar *vars;
- } swig_varlinkobject;
-
- SWIGINTERN PyObject *
- swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
- return PyString_FromString("<Swig global variables>");
- }
-
- SWIGINTERN PyObject *
- swig_varlink_str(swig_varlinkobject *v) {
- PyObject *str = PyString_FromString("(");
- swig_globalvar *var;
- for (var = v->vars; var; var=var->next) {
- PyString_ConcatAndDel(&str,PyString_FromString(var->name));
- if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
- }
- PyString_ConcatAndDel(&str,PyString_FromString(")"));
- return str;
- }
-
- SWIGINTERN int
- swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
- PyObject *str = swig_varlink_str(v);
- fprintf(fp,"Swig global variables ");
- fprintf(fp,"%s\n", PyString_AsString(str));
- Py_DECREF(str);
- return 0;
- }
-
- SWIGINTERN void
- swig_varlink_dealloc(swig_varlinkobject *v) {
- swig_globalvar *var = v->vars;
- while (var) {
- swig_globalvar *n = var->next;
- free(var->name);
- free(var);
- var = n;
- }
- }
-
- SWIGINTERN PyObject *
- swig_varlink_getattr(swig_varlinkobject *v, char *n) {
- PyObject *res = NULL;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->get_attr)();
- break;
- }
- var = var->next;
- }
- if (res == NULL && !PyErr_Occurred()) {
- PyErr_SetString(PyExc_NameError,"Unknown C global variable");
- }
- return res;
- }
-
- SWIGINTERN int
- swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
- int res = 1;
- swig_globalvar *var = v->vars;
- while (var) {
- if (strcmp(var->name,n) == 0) {
- res = (*var->set_attr)(p);
- break;
- }
- var = var->next;
- }
- if (res == 1 && !PyErr_Occurred()) {
- PyErr_SetString(PyExc_NameError,"Unknown C global variable");
- }
- return res;
- }
-
- SWIGINTERN PyTypeObject*
- swig_varlink_type(void) {
- static char varlink__doc__[] = "Swig var link object";
- static PyTypeObject varlink_type;
- static int type_init = 0;
- if (!type_init) {
- const PyTypeObject tmp
- = {
- PyObject_HEAD_INIT(NULL)
- 0, /* Number of items in variable part (ob_size) */
- (char *)"swigvarlink", /* Type name (tp_name) */
- sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
- 0, /* Itemsize (tp_itemsize) */
- (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */
- (printfunc) swig_varlink_print, /* Print (tp_print) */
- (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
- (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
- 0, /* tp_compare */
- (reprfunc) swig_varlink_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)swig_varlink_str, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- 0, /* tp_flags */
- varlink__doc__, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
-#if PY_VERSION_HEX >= 0x02020000
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
-#endif
-#if PY_VERSION_HEX >= 0x02030000
- 0, /* tp_del */
-#endif
-#ifdef COUNT_ALLOCS
- 0,0,0,0 /* tp_alloc -> tp_next */
-#endif
- };
- varlink_type = tmp;
- varlink_type.ob_type = &PyType_Type;
- type_init = 1;
- }
- return &varlink_type;
- }
-
- /* Create a variable linking object for use later */
- SWIGINTERN PyObject *
- SWIG_Python_newvarlink(void) {
- swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
- if (result) {
- result->vars = 0;
- }
- return ((PyObject*) result);
- }
-
- SWIGINTERN void
- SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
- swig_varlinkobject *v = (swig_varlinkobject *) p;
- swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
- if (gv) {
- size_t size = strlen(name)+1;
- gv->name = (char *)malloc(size);
- if (gv->name) {
- strncpy(gv->name,name,size);
- gv->get_attr = get_attr;
- gv->set_attr = set_attr;
- gv->next = v->vars;
- }
- }
- v->vars = gv;
- }
-
- SWIGINTERN PyObject *
- SWIG_globals(void) {
- static PyObject *_SWIG_globals = 0;
- if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();
- return _SWIG_globals;
- }
-
- /* -----------------------------------------------------------------------------
- * constants/methods manipulation
- * ----------------------------------------------------------------------------- */
-
- /* Install Constants */
- SWIGINTERN void
- SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
- PyObject *obj = 0;
- size_t i;
- for (i = 0; constants[i].type; ++i) {
- switch(constants[i].type) {
- case SWIG_PY_POINTER:
- obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
- break;
- case SWIG_PY_BINARY:
- obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
- break;
- default:
- obj = 0;
- break;
- }
- if (obj) {
- PyDict_SetItemString(d, constants[i].name, obj);
- Py_DECREF(obj);
- }
- }
- }
-
- /* -----------------------------------------------------------------------------*/
- /* Fix SwigMethods to carry the callback ptrs when needed */
- /* -----------------------------------------------------------------------------*/
-
- SWIGINTERN void
- SWIG_Python_FixMethods(PyMethodDef *methods,
- swig_const_info *const_table,
- swig_type_info **types,
- swig_type_info **types_initial) {
- size_t i;
- for (i = 0; methods[i].ml_name; ++i) {
- const char *c = methods[i].ml_doc;
- if (c && (c = strstr(c, "swig_ptr: "))) {
- int j;
- swig_const_info *ci = 0;
- const char *name = c + 10;
- for (j = 0; const_table[j].type; ++j) {
- if (strncmp(const_table[j].name, name,
- strlen(const_table[j].name)) == 0) {
- ci = &(const_table[j]);
- break;
- }
- }
- if (ci) {
- size_t shift = (ci->ptype) - types;
- swig_type_info *ty = types_initial[shift];
- size_t ldoc = (c - methods[i].ml_doc);
- size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
- char *ndoc = (char*)malloc(ldoc + lptr + 10);
- if (ndoc) {
- char *buff = ndoc;
- void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
- if (ptr) {
- strncpy(buff, methods[i].ml_doc, ldoc);
- buff += ldoc;
- strncpy(buff, "swig_ptr: ", 10);
- buff += 10;
- SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
- methods[i].ml_doc = ndoc;
- }
- }
- }
- }
- }
- }
-
-#ifdef __cplusplus
-}
-#endif
-
-/* -----------------------------------------------------------------------------*
- * Partial Init method
- * -----------------------------------------------------------------------------*/
-
-#ifdef __cplusplus
-extern "C"
-#endif
-SWIGEXPORT void SWIG_init(void) {
- PyObject *m, *d;
-
- /* Fix SwigMethods to carry the callback ptrs when needed */
- SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
-
- m = Py_InitModule((char *) SWIG_name, SwigMethods);
- d = PyModule_GetDict(m);
-
- SWIG_InitializeModule(0);
- SWIG_InstallConstants(d,swig_const_table);
-
-
-}
-
diff --git a/source4/lib/events/libevents.m4 b/source4/lib/events/libevents.m4
deleted file mode 100644
index ed76b03d4f..0000000000
--- a/source4/lib/events/libevents.m4
+++ /dev/null
@@ -1,49 +0,0 @@
-dnl find the events sources. This is meant to work both for
-dnl standalone builds, and builds of packages using libevents
-if test x"$eventsdir" = "x"; then
- eventsdir=""
- eventspaths="$srcdir $srcdir/../samba4/source/lib/events $srcdir/lib/events $srcdir/events $srcdir/../events"
- for d in $eventspaths; do
- if test -f "$d/events.c"; then
- eventsdir="$d"
- AC_SUBST(eventsdir)
- break;
- fi
- done
- if test x"$eventsdir" = "x"; then
- AC_MSG_ERROR([cannot find libevents source in $eventspaths])
- fi
-fi
-
-EVENTS_OBJ="events.o events_select.o events_signal.o events_timed.o events_standard.o events_debug.o events_util.o"
-AC_LIBREPLACE_NETWORK_CHECKS
-
-SMB_ENABLE(EVENTS_EPOLL, NO)
-SMB_ENABLE(EVENTS_AIO, NO)
-AC_CHECK_HEADERS(sys/epoll.h)
-AC_CHECK_FUNCS(epoll_create)
-if test x"$ac_cv_header_sys_epoll_h" = x"yes" -a x"$ac_cv_func_epoll_create" = x"yes"; then
- EVENTS_OBJ="$EVENTS_OBJ events_epoll.o"
- SMB_ENABLE(EVENTS_EPOLL,YES)
- AC_DEFINE(HAVE_EVENTS_EPOLL, 1, [Whether epoll available])
-
- # check for native Linux AIO interface
- AC_CHECK_HEADERS(libaio.h)
- AC_CHECK_LIB_EXT(aio, AIO_LIBS, io_getevents)
- if test x"$ac_cv_header_libaio_h" = x"yes" -a x"$ac_cv_lib_ext_aio_io_getevents" = x"yes";then
- EVENTS_OBJ="$EVENTS_OBJ events_aio.o"
- SMB_ENABLE(EVENTS_AIO,YES)
- AC_DEFINE(HAVE_LINUX_AIO, 1, [Whether Linux AIO is available])
- fi
-fi
-
-AC_SUBST(EVENTS_OBJ)
-SMB_EXT_LIB(LIBAIO_LINUX, $AIO_LIBS)
-
-EVENTS_CFLAGS="-I$eventsdir"
-AC_SUBST(EVENTS_CFLAGS)
-
-EVENTS_LIBS="$AIO_LIBS"
-AC_SUBST(EVENTS_LIBS)
-
-
diff --git a/source4/lib/events/libtalloc.m4 b/source4/lib/events/libtalloc.m4
deleted file mode 100644
index a4c5b8a9d9..0000000000
--- a/source4/lib/events/libtalloc.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-AC_SUBST(TALLOC_OBJ)
-AC_SUBST(TALLOC_CFLAGS)
-AC_SUBST(TALLOC_LIBS)
-
-AC_CHECK_HEADER(talloc.h,
- [AC_CHECK_LIB(talloc, talloc_init, [TALLOC_LIBS="-ltalloc"]) ],
- [PKG_CHECK_MODULES(TALLOC, talloc)])
diff --git a/source4/lib/events/pkg.m4 b/source4/lib/events/pkg.m4
deleted file mode 100644
index a8b3d06c81..0000000000
--- a/source4/lib/events/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/events/rules.mk b/source4/lib/events/rules.mk
deleted file mode 100644
index cfe548039b..0000000000
--- a/source4/lib/events/rules.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-.SUFFIXES: .i _wrap.c
-
-.i_wrap.c:
- $(SWIG) -O -Wall -python -keyword $<
-
-showflags::
- @echo 'libevents will be compiled with flags:'
- @echo ' CFLAGS = $(CFLAGS)'
- @echo ' CPPFLAGS = $(CPPFLAGS)'
- @echo ' LDFLAGS = $(LDFLAGS)'
- @echo ' LIBS = $(LIBS)'
-
-.SUFFIXES: .c .o
-
-.c.o:
- @echo Compiling $*.c
- @mkdir -p `dirname $@`
- @$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@
-
-distclean::
- rm -f *~ */*~
diff --git a/source4/lib/events/tests.py b/source4/lib/events/tests.py
deleted file mode 100644
index 006426207e..0000000000
--- a/source4/lib/events/tests.py
+++ /dev/null
@@ -1,31 +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/>.
-#
-
-from samba import events
-import unittest
-
-# Just test the bindings are there and that calling them doesn't crash
-# anything.
-
-class EventTestCase(unittest.TestCase):
- def test_create(self):
- self.assertTrue(events.event() is not None)
-
- def test_loop_wait(self):
- self.assertEquals(0, events.event().loop_wait())
diff --git a/source4/lib/events/testsuite.c b/source4/lib/events/testsuite.c
deleted file mode 100644
index 7f2729ceff..0000000000
--- a/source4/lib/events/testsuite.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- testing of the events subsystem
-
- Copyright (C) Stefan Metzmacher
-
- 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/events/events.h"
-#include "system/filesys.h"
-#include "torture/torture.h"
-
-static int fde_count;
-
-static void fde_handler(struct event_context *ev_ctx, struct fd_event *f,
- uint16_t flags, void *private)
-{
- int *fd = (int *)private;
- char c;
-#ifdef SA_SIGINFO
- kill(getpid(), SIGUSR1);
-#endif
- kill(getpid(), SIGALRM);
- read(fd[0], &c, 1);
- write(fd[1], &c, 1);
- fde_count++;
-}
-
-static void finished_handler(struct event_context *ev_ctx, struct timed_event *te,
- struct timeval tval, void *private)
-{
- int *finished = (int *)private;
- (*finished) = 1;
-}
-
-static void count_handler(struct event_context *ev_ctx, struct signal_event *te,
- int signum, int count, void *info, void *private)
-{
- int *countp = (int *)private;
- (*countp) += count;
-}
-
-static bool test_event_context(struct torture_context *test,
- const void *test_data)
-{
- struct event_context *ev_ctx;
- int fd[2] = { -1, -1 };
- const char *backend = (const char *)test_data;
- int alarm_count=0, info_count=0;
- struct fd_event *fde;
- struct signal_event *se1, *se2, *se3;
- int finished=0;
- struct timeval t;
- char c = 0;
-
- ev_ctx = event_context_init_byname(test, backend);
- if (ev_ctx == NULL) {
- torture_comment(test, "event backend '%s' not supported\n", backend);
- return true;
- }
-
- torture_comment(test, "Testing event backend '%s'\n", backend);
-
- /* reset globals */
- fde_count = 0;
-
- /* create a pipe */
- pipe(fd);
-
- fde = event_add_fd(ev_ctx, ev_ctx, fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
- fde_handler, fd);
-
- event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0),
- finished_handler, &finished);
-
- se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count);
- se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count);
-#ifdef SA_SIGINFO
- se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count);
-#endif
-
- write(fd[1], &c, 1);
-
- t = timeval_current();
- while (!finished) {
- errno = 0;
- if (event_loop_once(ev_ctx) == -1) {
- talloc_free(ev_ctx);
- torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno)));
- }
- }
-
- talloc_free(fde);
- close(fd[1]);
-
- while (alarm_count < fde_count+1) {
- if (event_loop_once(ev_ctx) == -1) {
- break;
- }
- }
-
- torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
-
- talloc_free(se1);
-
- torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
-
-#ifdef SA_SIGINFO
- talloc_free(se3);
- torture_assert_int_equal(test, info_count, fde_count, "info count mismatch");
-#endif
-
- talloc_free(ev_ctx);
-
- return true;
-}
-
-struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
-{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT");
- const char **list = event_backend_list(suite);
- int i;
-
- for (i=0;list && list[i];i++) {
- torture_suite_add_simple_tcase_const(suite, list[i],
- test_event_context,
- (const void *)list[i]);
- }
-
- return suite;
-}
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c
index a16582d294..5ab31d771b 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -64,8 +64,8 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
if (sid == NULL) {
return -1;
}
- ndr_err = ndr_pull_struct_blob(in, sid, NULL, sid,
- (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ ndr_err = ndr_pull_struct_blob_all(in, sid, NULL, sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(sid);
return -1;
@@ -139,6 +139,36 @@ static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx,
return ldb_handler_copy(ldb, mem_ctx, in, out);
}
+static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ struct dom_sid sid;
+ enum ndr_err_code ndr_err;
+ if (ldb_comparision_objectSid_isString(in)) {
+ if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) {
+ return 0;
+ }
+ }
+
+ /* Perhaps not a string after all */
+ *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
+
+ if (!out->data) {
+ return -1;
+ }
+
+ (*out).length = strhex_to_str((char *)out->data, out->length,
+ (const char *)in->data, in->length);
+
+ /* Check it looks like a SID */
+ ndr_err = ndr_pull_struct_blob_all(out, mem_ctx, NULL, &sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return -1;
+ }
+ return 0;
+}
+
/*
convert a ldif formatted objectGUID to a NDR formatted blob
*/
@@ -146,16 +176,10 @@ static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx,
const struct ldb_val *in, struct ldb_val *out)
{
struct GUID guid;
- char *guid_string;
NTSTATUS status;
enum ndr_err_code ndr_err;
- guid_string = talloc_strndup(mem_ctx, (const char *)in->data, in->length);
- if (!guid_string) {
- return -1;
- }
- status = GUID_from_string(guid_string, &guid);
- talloc_free(guid_string);
+ status = GUID_from_data_blob(in, &guid);
if (!NT_STATUS_IS_OK(status)) {
return -1;
}
@@ -176,8 +200,8 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx,
{
struct GUID guid;
enum ndr_err_code ndr_err;
- ndr_err = ndr_pull_struct_blob(in, mem_ctx, NULL, &guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ 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)) {
return -1;
}
@@ -191,20 +215,42 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx,
static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v)
{
- struct GUID guid;
- NTSTATUS status;
-
- if (v->length < 33) return false;
+ if (v->length != 36 && v->length != 38) return false;
- /* see if the input if null-terninated (safety check for the below) */
- if (v->data[v->length] != '\0') return false;
+ /* Might be a GUID string, can't be a binary GUID (fixed 16 bytes) */
+ return true;
+}
- status = GUID_from_string((const char *)v->data, &guid);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
+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;
+ if (in->length == 36 && ldif_read_objectGUID(ldb, mem_ctx, in, out) == 0) {
+ return 0;
}
- return true;
+ /* Try as 'hex' form */
+ if (in->length != 32) {
+ return -1;
+ }
+
+ *out = data_blob_talloc(mem_ctx, NULL, in->length/2+1);
+
+ if (!out->data) {
+ return -1;
+ }
+
+ (*out).length = strhex_to_str((char *)out->data, out->length,
+ (const char *)in->data, in->length);
+
+ /* Check it looks like a GUID */
+ 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)) {
+ return -1;
+ }
+ return 0;
}
/*
@@ -293,8 +339,9 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct
if (sd == NULL) {
return -1;
}
+ /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
ndr_err = ndr_pull_struct_blob(in, sd, NULL, sd,
- (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(sd);
return -1;
@@ -494,10 +541,10 @@ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
if (blob == NULL) {
return -1;
}
- ndr_err = ndr_pull_struct_blob(in, blob,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
- blob,
- (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
+ 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;
@@ -578,41 +625,71 @@ static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx,
return ret;
}
+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));
+ if (!out->data) {
+ return -1;
+ }
+ return 0;
+}
+
+
#define LDB_SYNTAX_SAMBA_GUID "LDB_SYNTAX_SAMBA_GUID"
#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY"
#define LDB_SYNTAX_SAMBA_PREFIX_MAP "LDB_SYNTAX_SAMBA_PREFIX_MAP"
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= ldb_canonicalise_objectSid,
- .comparison_fn = ldb_comparison_objectSid
+ .name = LDB_SYNTAX_SAMBA_SID,
+ .ldif_read_fn = ldif_read_objectSid,
+ .ldif_write_fn = ldif_write_objectSid,
+ .canonicalise_fn = ldb_canonicalise_objectSid,
+ .comparison_fn = ldb_comparison_objectSid
+ },{
+ .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
+ },{
+ .name = LDB_SYNTAX_SAMBA_GUID,
+ .ldif_read_fn = ldif_read_objectGUID,
+ .ldif_write_fn = ldif_write_objectGUID,
+ .canonicalise_fn = ldb_canonicalise_objectGUID,
+ .comparison_fn = ldb_comparison_objectGUID
},{
- .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
+ .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
},{
- .name = LDB_SYNTAX_SAMBA_GUID,
- .ldif_read_fn = ldif_read_objectGUID,
- .ldif_write_fn = ldif_write_objectGUID,
- .canonicalise_fn= ldb_canonicalise_objectGUID,
- .comparison_fn = ldb_comparison_objectGUID
+ .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
+ }
+};
+
+static const struct ldb_dn_extended_syntax samba_dn_syntax[] = {
+ {
+ .name = "SID",
+ .read_fn = extended_dn_read_SID,
+ .write_clear_fn = ldif_write_objectSid,
+ .write_hex_fn = extended_dn_write_hex
},{
- .name = 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
+ .name = "GUID",
+ .read_fn = extended_dn_read_GUID,
+ .write_clear_fn = ldif_write_objectGUID,
+ .write_hex_fn = extended_dn_write_hex
},{
- .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
+ .name = "WKGUID",
+ .read_fn = ldb_handler_copy,
+ .write_clear_fn = ldb_handler_copy,
+ .write_hex_fn = ldb_handler_copy
}
};
@@ -679,5 +756,15 @@ 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;
+ }
+
+
+ }
+
return LDB_SUCCESS;
}
diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c
index 747f241781..48f9e11caf 100644
--- a/source4/lib/ldb/common/ldb_attributes.c
+++ b/source4/lib/ldb/common/ldb_attributes.c
@@ -225,3 +225,50 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
return LDB_SUCCESS;
}
+
+/*
+ add a extended dn syntax to the ldb_schema
+*/
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
+ unsigned flags,
+ const struct ldb_dn_extended_syntax *syntax)
+{
+ int n;
+ struct ldb_dn_extended_syntax *a;
+
+ if (!syntax) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ n = ldb->schema.num_dn_extended_syntax + 1;
+
+ a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
+ struct ldb_dn_extended_syntax, n);
+
+ if (!a) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ a[ldb->schema.num_dn_extended_syntax] = *syntax;
+ ldb->schema.dn_extended_syntax = a;
+
+ ldb->schema.num_dn_extended_syntax = n;
+
+ return 0;
+}
+
+/*
+ return the extended dn syntax for a given name
+*/
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+ const char *name)
+{
+ int i;
+ for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
+ if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
+ return &ldb->schema.dn_extended_syntax[i];
+ }
+ }
+ return NULL;
+}
+
diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index e3f8551407..6fad5012b6 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/ldb/common/ldb_controls.c
@@ -53,6 +53,26 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char
return NULL;
}
+/* check if a control with the specified "oid" exist and return it */
+/* returns NULL if not found */
+struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
+{
+ int i;
+
+ /* check if there's a paged request control */
+ if (rep->controls != NULL) {
+ for (i = 0; rep->controls[i]; i++) {
+ if (strcmp(oid, rep->controls[i]->oid) == 0) {
+ break;
+ }
+ }
+
+ return rep->controls[i];
+ }
+
+ 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 False on error */
diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c
index e36aea4e69..13c01f4e70 100644
--- a/source4/lib/ldb/common/ldb_dn.c
+++ b/source4/lib/ldb/common/ldb_dn.c
@@ -52,6 +52,12 @@ struct ldb_dn_component {
struct ldb_val cf_value;
};
+struct ldb_dn_extended_component {
+
+ char *name;
+ struct ldb_val value;
+};
+
struct ldb_dn {
struct ldb_context *ldb;
@@ -63,11 +69,14 @@ struct ldb_dn {
bool valid_case;
char *linearized;
+ char *extended_linearized;
char *casefold;
unsigned int comp_num;
struct ldb_dn_component *components;
+ unsigned int extended_comp_num;
+ struct ldb_dn_extended_component *extended_components;
};
/* strdn may be NULL */
@@ -85,28 +94,34 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const
if (strdn->data && strdn->length) {
if (strdn->data[0] == '@') {
dn->special = true;
+ }
+ dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
+ LDB_DN_NULL_FAILED(dn->extended_linearized);
+
+ if (strdn->data[0] == '<') {
+ const char *p_save, *p = dn->extended_linearized;
+ do {
+ p_save = p;
+ p = strstr(p, ">;");
+ if (p) {
+ p = p + 2;
+ }
+ } while (p);
+
+ if (p_save == dn->extended_linearized) {
+ dn->linearized = talloc_strdup(dn, "");
+ } else {
+ dn->linearized = talloc_strdup(dn, p_save);
+ }
+ LDB_DN_NULL_FAILED(dn->linearized);
+ } else {
+ dn->linearized = dn->extended_linearized;
+ dn->extended_linearized = NULL;
}
- if (strdn->length >= 6 && strncasecmp((const char *)strdn->data, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strdn->length >= 5 && strncasecmp((const char *)strdn->data, "<SID=", 5) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
} else {
dn->linearized = talloc_strdup(dn, "");
+ LDB_DN_NULL_FAILED(dn->linearized);
}
- LDB_DN_NULL_FAILED(dn->linearized);
return dn;
@@ -126,47 +141,21 @@ struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *st
struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
{
- struct ldb_dn *dn;
char *strdn;
va_list ap;
if ( (! mem_ctx) || (! ldb)) return NULL;
- dn = talloc_zero(mem_ctx, struct ldb_dn);
- LDB_DN_NULL_FAILED(dn);
-
- dn->ldb = ldb;
-
va_start(ap, new_fmt);
- strdn = talloc_vasprintf(dn, new_fmt, ap);
+ strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
va_end(ap);
- LDB_DN_NULL_FAILED(strdn);
-
- if (strdn[0] == '@') {
- dn->special = true;
- }
- if (strncasecmp(strdn, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<SID=", 5) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = strdn;
- return dn;
-
-failed:
- talloc_free(dn);
+ if (strdn) {
+ struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
+ talloc_free(strdn);
+ return dn;
+ }
+
return NULL;
}
@@ -235,15 +224,19 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
*/
static bool ldb_dn_explode(struct ldb_dn *dn)
{
- char *p, *data, *d, *dt, *t;
+ char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
bool trim = false;
+ bool in_extended = false;
+ bool in_ex_name = false;
+ bool in_ex_value = false;
bool in_attr = false;
bool in_value = false;
bool in_quote = false;
bool is_oid = false;
bool escape = false;
unsigned x;
- int l;
+ int l, ret;
+ char *parse_dn;
if ( ! dn || dn->invalid) return false;
@@ -251,12 +244,18 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
return true;
}
- if ( ! dn->linearized) {
+ if (dn->extended_linearized) {
+ parse_dn = dn->extended_linearized;
+ } else {
+ parse_dn = dn->linearized;
+ }
+
+ if ( ! parse_dn ) {
return false;
}
/* Empty DNs */
- if (dn->linearized[0] == '\0') {
+ if (parse_dn[0] == '\0') {
return true;
}
@@ -268,6 +267,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
/* make sure we free this if alloced previously before replacing */
talloc_free(dn->components);
+ talloc_free(dn->extended_components);
+ dn->extended_components = NULL;
+
/* in the common case we have 3 or more components */
/* make sure all components are zeroed, other functions depend on this */
dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
@@ -277,19 +279,109 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
dn->comp_num = 0;
/* Components data space is allocated here once */
- data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
+ data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
if (!data) {
return false;
}
- p = dn->linearized;
- in_attr = true;
+ p = parse_dn;
+ in_extended = true;
+ in_ex_name = false;
+ in_ex_value = false;
trim = true;
t = NULL;
d = dt = data;
while (*p) {
+ if (in_extended) {
+
+ if (!in_ex_name && !in_ex_value) {
+
+ if (p[0] == '<') {
+ p++;
+ ex_name = d;
+ in_ex_name = true;
+ continue;
+ } else if (p[0] == '\0') {
+ p++;
+ continue;
+ } else {
+ in_extended = false;
+ in_attr = true;
+ dt = d;
+
+ continue;
+ }
+ }
+
+ if (in_ex_name && *p == '=') {
+ *d++ = '\0';
+ p++;
+ ex_value = d;
+ in_ex_name = false;
+ in_ex_value = true;
+ continue;
+ }
+
+ if (in_ex_value && *p == '>') {
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ struct ldb_val ex_val = {
+ .data = ex_value,
+ .length = d - ex_value
+ };
+
+ *d++ = '\0';
+ p++;
+ in_ex_value = false;
+
+ /* Process name and ex_value */
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if ( ! dn->extended_components) {
+ /* ouch ! */
+ goto failed;
+ }
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
+ if (!extended_syntax) {
+ /* We don't know about this type of extended DN */
+ goto failed;
+ }
+
+ dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
+ if (!dn->extended_components[dn->extended_comp_num].name) {
+ /* ouch */
+ goto failed;
+ }
+ ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
+ &ex_val, &dn->extended_components[dn->extended_comp_num].value);
+ if (ret != LDB_SUCCESS) {
+ dn->invalid = true;
+ goto failed;
+ }
+
+ dn->extended_comp_num++;
+ if (*p == '\0') {
+ /* We have reached the end (extended component only)! */
+ talloc_free(data);
+ return true;
+
+ } else if (*p == ';') {
+ p++;
+ continue;
+ } else {
+ dn->invalid = true;
+ goto failed;
+ }
+ }
+
+ *d++ = *p++;
+ continue;
+ }
if (in_attr) {
if (trim) {
if (*p == ' ') {
@@ -315,6 +407,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
goto failed;
}
+ /* Copy this character across from parse_dn, now we have trimmed out spaces */
*d++ = *p++;
continue;
}
@@ -339,6 +432,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
trim = true;
l = 0;
+ /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
*d++ = '\0';
dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
if ( ! dn->components[dn->comp_num].name) {
@@ -614,6 +708,74 @@ 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)
+{
+ const char *linearized = ldb_dn_get_linearized(dn);
+ char *p;
+ int i;
+
+ if (!linearized) {
+ return NULL;
+ }
+
+ if (!ldb_dn_has_extended(dn)) {
+ return talloc_strdup(mem_ctx, linearized);
+ }
+
+ if (!ldb_dn_validate(dn)) {
+ return NULL;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ struct ldb_val val;
+ int ret;
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ const char *name = dn->extended_components[i].name;
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
+
+ if (mode == 1) {
+ ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else if (mode == 0) {
+ ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else {
+ ret = -1;
+ }
+
+ if (ret != LDB_SUCCESS) {
+ return NULL;
+ }
+
+ if (i == 0) {
+ p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
+ } else {
+ p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
+ }
+
+ talloc_free(val.data);
+
+ if (!p) {
+ return NULL;
+ }
+ }
+
+ if (dn->extended_comp_num && *linearized) {
+ p = talloc_asprintf_append(p, ";%s", linearized);
+ }
+
+ if (!p) {
+ return NULL;
+ }
+
+ return p;
+}
+
+
+
char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
{
return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
@@ -909,6 +1071,30 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d
return dst;
}
+static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
+{
+ struct ldb_dn_extended_component dst;
+
+ memset(&dst, 0, sizeof(dst));
+
+ if (src == NULL) {
+ return dst;
+ }
+
+ dst.value = ldb_val_dup(mem_ctx, &(src->value));
+ if (dst.value.data == NULL) {
+ return dst;
+ }
+
+ dst.name = talloc_strdup(mem_ctx, src->name);
+ if (dst.name == NULL) {
+ LDB_FREE(dst.value.data);
+ return dst;
+ }
+
+ return dst;
+}
+
struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
{
struct ldb_dn *new_dn;
@@ -942,6 +1128,24 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
}
}
+ if (dn->extended_components) {
+ int i;
+
+ new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
+ if ( ! new_dn->extended_components) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+
+ for (i = 0; i < dn->extended_comp_num; i++) {
+ new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
+ if ( ! new_dn->extended_components[i].value.data) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+ }
+
if (dn->casefold) {
new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
if ( ! new_dn->casefold) {
@@ -958,6 +1162,14 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
}
}
+ if (dn->extended_linearized) {
+ new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
+ if ( ! new_dn->extended_linearized) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+
return new_dn;
}
@@ -1037,6 +1249,13 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ if (dn->extended_linearized) {
+ LDB_FREE(dn->extended_linearized);
+ }
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
@@ -1149,6 +1368,12 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
@@ -1218,6 +1443,12 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
@@ -1256,6 +1487,11 @@ bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
@@ -1273,6 +1509,11 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
return NULL;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return new_dn;
}
@@ -1434,9 +1675,97 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
return LDB_SUCCESS;
}
+const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
+{
+ int i;
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ return &dn->extended_components[i].value;
+ }
+ }
+ return NULL;
+}
+
+int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
+{
+ struct ldb_dn_extended_component *p;
+ int i;
+
+ if ( ! ldb_dn_validate(dn)) {
+ return LDB_ERR_OTHER;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ if (val) {
+ dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
+
+ dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ } else {
+ if (i != (dn->extended_comp_num - 1)) {
+ memmove(&dn->extended_components[i], &dn->extended_components[i+1],
+ ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
+ }
+ dn->extended_comp_num--;
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ return 0;
+ }
+ }
+ }
+
+ p = dn->extended_components
+ = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
+ p[dn->extended_comp_num].name = talloc_strdup(p, name);
+
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dn->extended_components = p;
+ dn->extended_comp_num++;
+
+ return 0;
+}
+
+void ldb_dn_remove_extended_components(struct ldb_dn *dn)
+{
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
+}
+
bool ldb_dn_is_valid(struct ldb_dn *dn)
{
if ( ! dn) return false;
@@ -1449,6 +1778,13 @@ bool ldb_dn_is_special(struct ldb_dn *dn)
return dn->special;
}
+bool ldb_dn_has_extended(struct ldb_dn *dn)
+{
+ if ( ! dn || dn->invalid) return false;
+ if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
+ return dn->extended_comp_num != 0;
+}
+
bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
{
if ( ! dn || dn->invalid) return false;
@@ -1458,6 +1794,7 @@ bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
bool ldb_dn_is_null(struct ldb_dn *dn)
{
if ( ! dn || dn->invalid) return false;
+ if (ldb_dn_has_extended(dn)) return false;
if (dn->linearized && (dn->linearized[0] == '\0')) return true;
return false;
}
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index 69490e670b..619c10e11e 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -278,13 +278,15 @@ int ldb_ldif_write(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx;
unsigned int i, j;
int total=0, ret;
+ char *p;
const struct ldb_message *msg;
mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write");
msg = ldif->msg;
-
- ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_get_linearized(msg->dn));
+ p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1);
+ ret = fprintf_fn(private_data, "dn: %s\n", p);
+ talloc_free(p);
CHECK_RET;
if (ldif->changetype != LDB_CHANGETYPE_NONE) {
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index ab0f4c51cc..8db28d262c 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -587,10 +587,13 @@ struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb)
* req: the original request passed to your module
* msg: reply message (must be a talloc pointer, and it will be stolen
* on the ldb_reply that is sent to the callback)
+ * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen
+ * on the ldb_reply that is sent to the callback)
*/
int ldb_module_send_entry(struct ldb_request *req,
- struct ldb_message *msg)
+ struct ldb_message *msg,
+ struct ldb_control **ctrls)
{
struct ldb_reply *ares;
@@ -602,6 +605,7 @@ int ldb_module_send_entry(struct ldb_request *req,
}
ares->type = LDB_REPLY_ENTRY;
ares->message = talloc_steal(ares, msg);
+ ares->controls = talloc_steal(ares, ctrls);
ares->error = LDB_SUCCESS;
return req->callback(req, ares);
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 9bc5c183d8..e2ec869872 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -326,7 +326,6 @@ typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx,
attribute handler structure
attr -> The attribute name
- flags -> LDB_ATTR_FLAG_*
ldif_read_fn -> convert from ldif to binary format
ldif_write_fn -> convert from binary to ldif format
canonicalise_fn -> canonicalise a value, for use by indexing and dn construction
@@ -350,6 +349,16 @@ struct ldb_schema_attribute {
const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb,
const char *name);
+struct ldb_dn_extended_syntax {
+ const char *name;
+ ldb_attr_handler_t read_fn;
+ ldb_attr_handler_t write_clear_fn;
+ ldb_attr_handler_t write_hex_fn;
+};
+
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+ const char *name);
+
/**
The attribute is not returned by default
*/
@@ -1066,6 +1075,15 @@ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool criti
struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid);
/**
+ check if a control with the specified "oid" exist and return it
+ \param rep the reply struct where to add the control
+ \param oid the object identifier of the control as string
+
+ \return the control, NULL if not found
+*/
+struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid);
+
+/**
Search the database
This function searches the database, and returns
@@ -1421,15 +1439,82 @@ int ldb_base64_decode(char *s);
/* The following definitions come from lib/ldb/common/ldb_dn.c */
+/**
+ Get the linear form of a DN (without any extended components)
+
+ \param dn The DN to linearize
+*/
+
+const char *ldb_dn_get_linearized(struct ldb_dn *dn);
+
+/**
+ Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context
+
+ \param dn The DN to linearize
+ \param mem_ctx TALLOC context to return result on
+*/
+
+char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
+
+/**
+ Get the linear form of a DN (with any extended components)
+
+ \param mem_ctx TALLOC context to return result on
+ \param dn The DN to linearize
+ \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form)
+*/
+char *ldb_dn_get_extended_linearized(void *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_remove_extended_components(struct ldb_dn *dn);
+bool ldb_dn_has_extended(struct ldb_dn *dn);
+
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
+ unsigned flags,
+ const struct ldb_dn_extended_syntax *syntax);
+
+/**
+ Allocate a new DN from a string
+
+ \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+ \param dn The new DN
+
+ \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn);
+/**
+ Allocate a new DN from a printf style format string and arguments
+
+ \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+ \param new_fms The new DN as a format string (plus arguments)
+
+ \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4);
+/**
+ Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun)
+
+ \param mem_ctx TALLOC context to return resulting ldb_dn structure on
+ \param dn The new DN
+
+ \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct
+*/
+
struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn);
+
+/**
+ Determine if this DN is syntactically valid
+
+ \param dn The DN to validate
+*/
+
bool ldb_dn_validate(struct ldb_dn *dn);
char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value);
-const char *ldb_dn_get_linearized(struct ldb_dn *dn);
const char *ldb_dn_get_casefold(struct ldb_dn *dn);
-char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn);
int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn);
diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h
index 90c4980017..c065288279 100644
--- a/source4/lib/ldb/include/ldb_private.h
+++ b/source4/lib/ldb/include/ldb_private.h
@@ -84,6 +84,9 @@ struct ldb_schema {
/* attribute handling table */
unsigned num_attributes;
struct ldb_schema_attribute *attributes;
+
+ unsigned num_dn_extended_syntax;
+ struct ldb_dn_extended_syntax *dn_extended_syntax;
};
/*
@@ -262,7 +265,8 @@ int ldb_register_backend(const char *url_prefix, ldb_connect_fn);
struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb);
int ldb_module_send_entry(struct ldb_request *req,
- struct ldb_message *msg);
+ struct ldb_message *msg,
+ struct ldb_control **ctrls);
int ldb_module_send_referral(struct ldb_request *req,
char *ref);
diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i
index 0f05c1fbab..7831d6da60 100644
--- a/source4/lib/ldb/ldb.i
+++ b/source4/lib/ldb/ldb.i
@@ -575,6 +575,8 @@ static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *
if (ldif == NULL) {
return Py_None;
} else {
+ /* We don't want this attached to the 'ldb' any more */
+ talloc_steal(NULL, ldif);
return Py_BuildValue((char *)"(iO)", ldif->changetype,
SWIG_NewPointerObj(ldif->msg, SWIGTYPE_p_ldb_message, 0));
}
diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
index 93e81d4244..b17d063c0c 100644
--- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c
+++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
@@ -311,7 +311,9 @@ static void ildb_callback(struct ldap_request *req)
ldbmsg->num_elements = search->num_attributes;
ldbmsg->elements = talloc_move(ldbmsg, &search->attributes);
- ret = ldb_module_send_entry(ac->req, ldbmsg);
+ controls = talloc_steal(ac, msg->controls);
+
+ ret = ldb_module_send_entry(ac->req, ldbmsg, controls);
if (ret != LDB_SUCCESS) {
callback_failed = true;
}
@@ -428,7 +430,7 @@ static int ildb_search(struct ildb_context *ac)
if (req->op.search.base == NULL) {
msg->r.SearchRequest.basedn = talloc_strdup(msg, "");
} else {
- msg->r.SearchRequest.basedn = ldb_dn_alloc_linearized(msg, req->op.search.base);
+ msg->r.SearchRequest.basedn = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0);
}
if (msg->r.SearchRequest.basedn == NULL) {
ldb_set_errstring(ac->module->ldb, "Unable to determine baseDN");
@@ -473,7 +475,7 @@ static int ildb_add(struct ildb_context *ac)
msg->type = LDAP_TAG_AddRequest;
- msg->r.AddRequest.dn = ldb_dn_alloc_linearized(msg, req->op.add.message->dn);
+ msg->r.AddRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.add.message->dn, 0);
if (msg->r.AddRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
@@ -516,7 +518,7 @@ static int ildb_modify(struct ildb_context *ac)
msg->type = LDAP_TAG_ModifyRequest;
- msg->r.ModifyRequest.dn = ldb_dn_alloc_linearized(msg, req->op.mod.message->dn);
+ msg->r.ModifyRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.mod.message->dn, 0);
if (msg->r.ModifyRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
@@ -557,7 +559,7 @@ static int ildb_delete(struct ildb_context *ac)
msg->type = LDAP_TAG_DelRequest;
- msg->r.DelRequest.dn = ldb_dn_alloc_linearized(msg, req->op.del.dn);
+ msg->r.DelRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.del.dn, 0);
if (msg->r.DelRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
@@ -580,7 +582,7 @@ static int ildb_rename(struct ildb_context *ac)
}
msg->type = LDAP_TAG_ModifyDNRequest;
- msg->r.ModifyDNRequest.dn = ldb_dn_alloc_linearized(msg, req->op.rename.olddn);
+ msg->r.ModifyDNRequest.dn = ldb_dn_get_extended_linearized(msg, req->op.rename.olddn, 0);
if (msg->r.ModifyDNRequest.dn == NULL) {
talloc_free(msg);
return LDB_ERR_INVALID_DN_SYNTAX;
diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
index 7caee10b47..9f8b3e9f35 100644
--- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c
+++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
@@ -515,7 +515,7 @@ static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result)
}
if (berptr) ber_free(berptr, 0);
- ret = ldb_module_send_entry(ac->req, ldbmsg);
+ ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */);
if (ret != LDB_SUCCESS) {
callback_failed = true;
diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
index 5f524a8be3..5588eaaf46 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c
+++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
@@ -1077,7 +1077,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares)
}
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
}
/* Search a record. */
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index eedbda4170..0a10307e65 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -36,6 +36,328 @@
#include "ldb_tdb.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 ltdb_idxptr {
+ int num_dns;
+ const char **dn_list;
+ bool repack;
+};
+
+/*
+ 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)
+{
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_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++;
+ return LDB_SUCCESS;
+}
+
+/* free an idxptr record */
+static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_element *el)
+{
+ struct ldb_val val;
+ struct ldb_index_pointer *ptr;
+
+ if (el->num_values != 1) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ val = el->values[0];
+ if (val.length != sizeof(void *)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ 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);
+ }
+
+ return 0;
+}
+
+
+/* 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)
+{
+ struct ldb_val val;
+ struct ldb_index_pointer *ptr, *tmp;
+ int i;
+ struct ldb_val *val2;
+
+ if (el->num_values != 1) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ val = el->values[0];
+ if (val.length != sizeof(void *)) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ptr = *(struct ldb_index_pointer **)val.data;
+ if (talloc_get_type(ptr, struct ldb_index_pointer) != ptr) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* count the length of the list */
+ for (i=0, tmp = ptr; tmp; tmp=tmp->next) {
+ i++;
+ }
+
+ /* allocate the new values array */
+ val2 = talloc_realloc(NULL, el->values, struct ldb_val, i);
+ if (val2 == 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;
+ }
+
+ /* update the name */
+ el->name = LTDB_IDX;
+
+ 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)
+{
+ struct ldb_index_pointer *ptr, *tmp;
+ int i;
+ struct ldb_val *val2;
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_data, struct ltdb_private);
+
+ ptr = NULL;
+
+ 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;
+ }
+ DLIST_ADD(ptr, tmp);
+ }
+
+ /* allocate the new values array */
+ val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1);
+ if (val2 == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ 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;
+
+ return LDB_SUCCESS;
+}
+
+
+/* enable the idxptr mode when transactions start */
+int ltdb_index_transaction_start(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_data, struct ltdb_private);
+ ltdb->idxptr = talloc_zero(module, struct ltdb_idxptr);
+ return 0;
+}
+
+/*
+ a wrapper around ltdb_search_dn1() which translates pointer based index records
+ and maps them into normal ldb message structures
+ */
+static int ltdb_search_dn1_index(struct ldb_module *module,
+ struct ldb_dn *dn, struct ldb_message *msg)
+{
+ int ret, i;
+ ret = ltdb_search_dn1(module, dn, msg);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ /* 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;
+ }
+
+ 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;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+/*
+ fixup the idxptr for one DN
+ */
+static int ltdb_idxptr_fix_dn(struct ldb_module *module, const char *strdn)
+{
+ struct ldb_dn *dn;
+ struct ldb_message *msg = ldb_msg_new(module);
+ int ret;
+
+ dn = ldb_dn_new(msg, module->ldb, strdn);
+ if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) {
+ ret = ltdb_store(module, msg, TDB_REPLACE);
+ }
+ talloc_free(msg);
+ return ret;
+}
+
+/* cleanup the idxptr mode when transaction commits */
+int ltdb_index_transaction_commit(struct ldb_module *module)
+{
+ int i;
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_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]);
+ }
+
+ if (ltdb->idxptr->repack) {
+ tdb_repack(ltdb->tdb);
+ }
+ }
+
+ talloc_free(ltdb->idxptr);
+ ltdb->idxptr = NULL;
+ return 0;
+}
+
+/* cleanup the idxptr mode when transaction cancels */
+int ltdb_index_transaction_cancel(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_data, struct ltdb_private);
+ talloc_free(ltdb->idxptr);
+ ltdb->idxptr = NULL;
+ return 0;
+}
+
+
+
+/* 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)
+{
+ struct ltdb_private *ltdb =
+ talloc_get_type(module->private_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
@@ -213,7 +535,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1(module, dn, msg);
+ ret = ltdb_search_dn1_index(module, dn, msg);
talloc_free(dn);
if (ret != LDB_SUCCESS) {
return ret;
@@ -559,7 +881,7 @@ static int ltdb_index_dn_one(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1(module, key, msg);
+ ret = ltdb_search_dn1_index(module, key, msg);
talloc_free(key);
if (ret != LDB_SUCCESS) {
return ret;
@@ -715,7 +1037,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list,
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ldb_module_send_entry(ac->req, msg);
+ ret = ldb_module_send_entry(ac->req, msg, NULL);
if (ret != LDB_SUCCESS) {
ac->callback_failed = true;
return ret;
@@ -895,7 +1217,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn,
}
talloc_steal(msg, dn_key);
- ret = ltdb_search_dn1(module, dn_key, msg);
+ ret = ltdb_search_dn1_index(module, dn_key, msg);
if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) {
talloc_free(msg);
return ret;
@@ -920,7 +1242,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn,
}
if (ret == LDB_SUCCESS) {
- ret = ltdb_store(module, msg, TDB_REPLACE);
+ ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
}
talloc_free(msg);
@@ -1007,7 +1329,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = ltdb_search_dn1(module, dn_key, msg);
+ 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;
@@ -1022,9 +1344,15 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX);
if (i == -1) {
+ struct ldb_ldif ldif;
+
ldb_debug(ldb, LDB_DEBUG_ERROR,
"ERROR: dn %s not found in %s\n", dn,
ldb_dn_get_linearized(dn_key));
+ ldif.changetype = LDB_CHANGETYPE_NONE;
+ ldif.msg = msg;
+ ldb_ldif_write_file(module->ldb, stdout, &ldif);
+ sleep(100);
/* it ain't there. hmmm */
talloc_free(dn_key);
return LDB_SUCCESS;
@@ -1041,7 +1369,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
if (msg->elements[i].num_values == 0) {
ret = ltdb_delete_noindex(module, dn_key);
} else {
- ret = ltdb_store(module, msg, TDB_REPLACE);
+ ret = ltdb_store_idxptr(module, msg, TDB_REPLACE);
}
talloc_free(dn_key);
@@ -1250,8 +1578,8 @@ int ltdb_reindex(struct ldb_module *module)
return LDB_ERR_OPERATIONS_ERROR;
}
- if (tdb_repack(ltdb->tdb) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
+ if (ltdb->idxptr) {
+ ltdb->idxptr->repack = true;
}
return LDB_SUCCESS;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c
index 6ab06c4e48..35149c4b77 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_search.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_search.c
@@ -418,7 +418,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
return -1;
}
- ret = ldb_module_send_entry(ac->req, msg);
+ ret = ldb_module_send_entry(ac->req, msg, NULL);
if (ret != LDB_SUCCESS) {
ac->callback_failed = true;
/* the callback failed, abort the operation */
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 9e3ad80705..ea460def65 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -850,6 +850,8 @@ static int ltdb_start_trans(struct ldb_module *module)
ltdb->in_transaction++;
+ ltdb_index_transaction_start(module);
+
return LDB_SUCCESS;
}
@@ -860,6 +862,10 @@ static int ltdb_end_trans(struct ldb_module *module)
ltdb->in_transaction--;
+ if (ltdb_index_transaction_commit(module) != 0) {
+ return ltdb_err_map(tdb_error(ltdb->tdb));
+ }
+
if (tdb_transaction_commit(ltdb->tdb) != 0) {
return ltdb_err_map(tdb_error(ltdb->tdb));
}
@@ -874,6 +880,10 @@ static int ltdb_del_trans(struct ldb_module *module)
ltdb->in_transaction--;
+ if (ltdb_index_transaction_cancel(module) != 0) {
+ return ltdb_err_map(tdb_error(ltdb->tdb));
+ }
+
if (tdb_transaction_cancel(ltdb->tdb) != 0) {
return ltdb_err_map(tdb_error(ltdb->tdb));
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index c78a8172c7..7b9a76501f 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -33,6 +33,7 @@ struct ltdb_private {
int in_transaction;
bool check_base;
+ struct ltdb_idxptr *idxptr;
};
/*
@@ -57,6 +58,7 @@ struct ltdb_context {
#define LTDB_INDEX "@INDEX"
#define LTDB_INDEXLIST "@INDEXLIST"
#define LTDB_IDX "@IDX"
+#define LTDB_IDXPTR "@IDXPTR"
#define LTDB_IDXATTR "@IDXATTR"
#define LTDB_IDXONE "@IDXONE"
#define LTDB_BASEINFO "@BASEINFO"
@@ -85,6 +87,9 @@ 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_reindex(struct ldb_module *module);
+int ltdb_index_transaction_start(struct ldb_module *module);
+int ltdb_index_transaction_commit(struct ldb_module *module);
+int ltdb_index_transaction_cancel(struct ldb_module *module);
/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c
index 835715e7dc..c650970af4 100644
--- a/source4/lib/ldb/modules/asq.c
+++ b/source4/lib/ldb/modules/asq.c
@@ -178,7 +178,7 @@ static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares)
case LDB_REPLY_ENTRY:
/* pass the message up to the original callback as we
* do not have to elaborate on it any further */
- ret = ldb_module_send_entry(ac->req, ares->message);
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c
index abb1d4ca1a..345441b5e1 100644
--- a/source4/lib/ldb/modules/operational.c
+++ b/source4/lib/ldb/modules/operational.c
@@ -206,7 +206,7 @@ static int operational_callback(struct ldb_request *req, struct ldb_reply *ares)
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- return ldb_module_send_entry(ac->req, ares->message);
+ return ldb_module_send_entry(ac->req, ares->message, ares->controls);
case LDB_REPLY_REFERRAL:
/* ignore referrals */
diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c
index 1a242f1be0..dfc565fef8 100644
--- a/source4/lib/ldb/modules/paged_results.c
+++ b/source4/lib/ldb/modules/paged_results.c
@@ -147,7 +147,7 @@ static int paged_results(struct paged_context *ac)
while (ac->store->num_entries > 0 && ac->size > 0) {
msg = ac->store->first;
- ret = ldb_module_send_entry(ac->req, msg->r->message);
+ ret = ldb_module_send_entry(ac->req, msg->r->message, msg->r->controls);
if (ret != LDB_SUCCESS) {
return ret;
}
diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c
index 7a728e3bb0..56f9b1cac3 100644
--- a/source4/lib/ldb/modules/paged_searches.c
+++ b/source4/lib/ldb/modules/paged_searches.c
@@ -161,7 +161,7 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
switch (ares->type) {
case LDB_REPLY_ENTRY:
- ret = ldb_module_send_entry(ac->req, ares->message);
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c
index 64d60f370c..25e56b24c8 100644
--- a/source4/lib/ldb/modules/sort.c
+++ b/source4/lib/ldb/modules/sort.c
@@ -152,7 +152,7 @@ static int server_sort_results(struct sort_context *ac)
ares->type = LDB_REPLY_ENTRY;
ares->message = talloc_move(ares, &ac->msgs[i]);
- ret = ldb_module_send_entry(ac->req, ares->message);
+ ret = ldb_module_send_entry(ac->req, ares->message, ares->controls);
if (ret != LDB_SUCCESS) {
return ret;
}
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index 71fd98876e..c64d85a0e5 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -74,7 +74,11 @@ class BasicTests(unittest.TestCase):
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)
+
def test_group_add_invalid_member(self):
"""Testing group add with invalid member"""
try:
@@ -436,7 +440,13 @@ member: cn=ldaptestuser3,cn=users,""" + self.base_dn + """
print "Testing Renames"
- ldb.rename("cn=ldaptestuser2,cn=users," + self.base_dn, "cn=ldaptestuser3,cn=users," + self.base_dn)
+ 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)
@@ -585,7 +595,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
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 conistant with subtree renames?")
+ 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:
@@ -737,8 +747,8 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
self.assertEquals(len(res6), 1, "Could not find (&(cn=*daptestcomputer)(objectCategory=compuTER))")
self.assertEquals(res[0].dn, res6[0].dn)
-
- ldb.delete(res[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))")
@@ -754,25 +764,29 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369)
self.assertEquals(int(res[0]["userAccountControl"][0]), 4096)
- ldb.delete(res[0].dn)
+ ldb.delete("<SID=" + ldb.schema_format_value("objectSID", res[0]["objectSID"][0]) + ">")
- attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
+ attrs = ["cn", "name", "objectClass", "objectGUID", "objectSID", "whenCreated", "nTSecurityDescriptor", "memberOf", "allowedAttributes", "allowedAttributesEffective"]
print "Testing ldb.search for (&(cn=ldaptestUSer2)(objectClass=user))"
- res = ldb.search(self.base_dn, expression="(&(cn=ldaptestUSer2)(objectClass=user))", scope=SCOPE_SUBTREE, attrs=attrs)
- self.assertEquals(len(res), 1, "Could not find (&(cn=ldaptestUSer2)(objectClass=user))")
-
- self.assertEquals(res[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn))
- self.assertEquals(res[0]["cn"], "ldaptestuser2")
- self.assertEquals(res[0]["name"], "ldaptestuser2")
- self.assertEquals(res[0]["objectClass"], ["top", "person", "organizationalPerson", "user"])
- self.assertTrue("objectGUID" 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])
- self.assertEquals(res[0]["memberOf"][0].upper(), ("CN=ldaptestgroup2,CN=Users," + self.base_dn).upper())
-
- attrs = ["cn", "name", "objectClass", "objectGUID", "whenCreated", "nTSecurityDescriptor", "member", "allowedAttributes", "allowedAttributesEffective"]
+ 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(res_user[0].dn, ("CN=ldaptestuser2,CN=Users," + self.base_dn))
+ self.assertEquals(res_user[0]["cn"], "ldaptestuser2")
+ self.assertEquals(res_user[0]["name"], "ldaptestuser2")
+ self.assertEquals(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))")
@@ -781,7 +795,8 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
self.assertEquals(res[0]["cn"], "ldaptestgroup2")
self.assertEquals(res[0]["name"], "ldaptestgroup2")
self.assertEquals(res[0]["objectClass"], ["top", "group"])
- self.assertTrue("objectGuid" not in res[0])
+ 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])
@@ -791,6 +806,18 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
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
@@ -799,9 +826,15 @@ member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
""")
- print "Testing Linked attribute behaviours"
ldb.modify_ldif("""
-dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
+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
""")
@@ -810,7 +843,7 @@ delete: member
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
add: member
-member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
+member: <GUID=""" + ldb.schema_format_value("objectGUID", res[0]["objectGUID"][0]) + """>
member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
""")
@@ -824,7 +857,7 @@ replace: member
dn: cn=ldaptestgroup2,cn=users,""" + self.base_dn + """
changetype: modify
add: member
-member: CN=ldaptestuser2,CN=Users,""" + self.base_dn + """
+member: <SID=""" + ldb.schema_format_value("objectSid", res_user[0]["objectSid"][0]) + """>
member: CN=ldaptestutf8user èùéìòà,CN=Users,""" + self.base_dn + """
""")
diff --git a/source4/lib/ldb/tools/ldbadd.c b/source4/lib/ldb/tools/ldbadd.c
index 3749aec629..f32a4fa9bc 100644
--- a/source4/lib/ldb/tools/ldbadd.c
+++ b/source4/lib/ldb/tools/ldbadd.c
@@ -93,7 +93,7 @@ int main(int argc, const char **argv)
options = ldb_cmdline_process(ldb, argc, argv, usage);
if (ldb_transaction_start(ldb) != 0) {
- printf("Failed to start transaction\n");
+ printf("Failed to start transaction: %s\n", ldb_errstring(ldb));
exit(1);
}
@@ -114,7 +114,7 @@ int main(int argc, const char **argv)
}
if (count != 0 && ldb_transaction_commit(ldb) != 0) {
- printf("Failed to commit transaction\n");
+ printf("Failed to commit transaction: %s\n", ldb_errstring(ldb));
exit(1);
}
diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c
index b18aea1b10..1a684c5c2d 100644
--- a/source4/lib/ldb/tools/ldbedit.c
+++ b/source4/lib/ldb/tools/ldbedit.c
@@ -113,7 +113,7 @@ static int merge_edits(struct ldb_context *ldb,
int adds=0, modifies=0, deletes=0;
if (ldb_transaction_start(ldb) != 0) {
- fprintf(stderr, "Failed to start transaction\n");
+ fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb));
return -1;
}
@@ -156,7 +156,7 @@ static int merge_edits(struct ldb_context *ldb,
}
if (ldb_transaction_commit(ldb) != 0) {
- fprintf(stderr, "Failed to commit transaction\n");
+ fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb));
return -1;
}
diff --git a/source4/lib/ldb/tools/ldbmodify.c b/source4/lib/ldb/tools/ldbmodify.c
index 8b6309e016..d73937cea4 100644
--- a/source4/lib/ldb/tools/ldbmodify.c
+++ b/source4/lib/ldb/tools/ldbmodify.c
@@ -91,13 +91,13 @@ int main(int argc, const char **argv)
ldb = ldb_init(NULL, NULL);
+ options = ldb_cmdline_process(ldb, argc, argv, usage);
+
if (ldb_transaction_start(ldb) != 0) {
- printf("Failed to start transaction\n");
+ printf("Failed to start transaction: %s\n", ldb_errstring(ldb));
exit(1);
}
- options = ldb_cmdline_process(ldb, argc, argv, usage);
-
if (options->argc == 0) {
ret = process_file(ldb, stdin, &count);
} else {
@@ -114,7 +114,7 @@ int main(int argc, const char **argv)
}
if (count != 0 && ldb_transaction_commit(ldb) != 0) {
- printf("Failed to commit transaction\n");
+ printf("Failed to commit transaction: %s\n", ldb_errstring(ldb));
exit(1);
}
diff --git a/source4/lib/socket/connect.c b/source4/lib/socket/connect.c
index 2b64668b9b..d74a7b4833 100644
--- a/source4/lib/socket/connect.c
+++ b/source4/lib/socket/connect.c
@@ -25,7 +25,6 @@
#include "lib/socket/socket.h"
#include "lib/events/events.h"
#include "libcli/composite/composite.h"
-#include "libcli/resolve/resolve.h"
struct connect_state {
@@ -38,26 +37,16 @@ struct connect_state {
static void socket_connect_handler(struct event_context *ev,
struct fd_event *fde,
uint16_t flags, void *private);
-static void continue_resolve_name(struct composite_context *ctx);
-static void continue_socket_connect(struct composite_context *creq);
/*
call the real socket_connect() call, and setup event handler
*/
static void socket_send_connect(struct composite_context *result)
{
- struct composite_context *creq;
struct fd_event *fde;
struct connect_state *state = talloc_get_type(result->private_data,
struct connect_state);
- creq = talloc_zero(state, struct composite_context);
- if (composite_nomem(creq, result)) return;
- creq->state = COMPOSITE_STATE_IN_PROGRESS;
- creq->event_ctx = result->event_ctx;
- creq->async.fn = continue_socket_connect;
- creq->async.private_data = result;
-
result->status = socket_connect(state->sock,
state->my_address,
state->server_address,
@@ -84,16 +73,13 @@ struct composite_context *socket_connect_send(struct socket_context *sock,
struct socket_address *my_address,
struct socket_address *server_address,
uint32_t flags,
- struct resolve_context *resolve_ctx,
struct event_context *event_ctx)
{
struct composite_context *result;
struct connect_state *state;
- result = talloc_zero(sock, struct composite_context);
+ result = composite_create(sock, event_ctx);
if (result == NULL) return NULL;
- result->state = COMPOSITE_STATE_IN_PROGRESS;
- result->event_ctx = event_ctx;
state = talloc_zero(result, struct connect_state);
if (composite_nomem(state, result)) return result;
@@ -122,16 +108,6 @@ struct composite_context *socket_connect_send(struct socket_context *sock,
set_blocking(socket_get_fd(sock), false);
- if (resolve_ctx != NULL && server_address->addr && strcmp(sock->backend_name, "ipv4") == 0) {
- struct nbt_name name;
- struct composite_context *creq;
- make_nbt_name_client(&name, server_address->addr);
- creq = resolve_name_send(resolve_ctx, &name, result->event_ctx);
- if (composite_nomem(creq, result)) return result;
- composite_continue(result, creq, continue_resolve_name, result);
- return result;
- }
-
socket_send_connect(result);
return result;
@@ -156,39 +132,6 @@ static void socket_connect_handler(struct event_context *ev,
}
/*
- recv name resolution reply then send the connect
-*/
-static void continue_resolve_name(struct composite_context *creq)
-{
- struct composite_context *result = talloc_get_type(creq->async.private_data,
- struct composite_context);
- struct connect_state *state = talloc_get_type(result->private_data, struct connect_state);
- const char *addr;
-
- result->status = resolve_name_recv(creq, state, &addr);
- if (!composite_is_ok(result)) return;
-
- state->server_address = socket_address_from_strings(state, state->sock->backend_name,
- addr, state->server_address->port);
- if (composite_nomem(state->server_address, result)) return;
-
- socket_send_connect(result);
-}
-
-/*
- called when a connect has finished. Complete the top level composite context
-*/
-static void continue_socket_connect(struct composite_context *creq)
-{
- struct composite_context *result = talloc_get_type(creq->async.private_data,
- struct composite_context);
- result->status = creq->status;
- if (!composite_is_ok(result)) return;
- composite_done(result);
-}
-
-
-/*
wait for a socket_connect_send() to finish
*/
NTSTATUS socket_connect_recv(struct composite_context *result)
@@ -205,11 +148,11 @@ NTSTATUS socket_connect_recv(struct composite_context *result)
NTSTATUS socket_connect_ev(struct socket_context *sock,
struct socket_address *my_address,
struct socket_address *server_address,
- uint32_t flags, struct resolve_context *resolve_ctx,
+ uint32_t flags,
struct event_context *ev)
{
struct composite_context *ctx;
ctx = socket_connect_send(sock, my_address,
- server_address, flags, resolve_ctx, ev);
+ server_address, flags, ev);
return socket_connect_recv(ctx);
}
diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c
index 98b4d405b3..14c475d0c3 100644
--- a/source4/lib/socket/connect_multi.c
+++ b/source4/lib/socket/connect_multi.c
@@ -37,8 +37,6 @@ struct connect_multi_state {
int num_ports;
uint16_t *ports;
- struct resolve_context *resolve_ctx;
-
struct socket_context *sock;
uint16_t result_port;
@@ -89,7 +87,6 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(
if (composite_nomem(multi->server_address, result)) goto failed;
multi->num_ports = num_server_ports;
- multi->resolve_ctx = talloc_reference(multi, resolve_ctx);
multi->ports = talloc_array(multi, uint16_t, multi->num_ports);
if (composite_nomem(multi->ports, result)) goto failed;
@@ -105,7 +102,7 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(
*/
struct nbt_name name;
struct composite_context *creq;
- make_nbt_name_client(&name, server_address);
+ make_nbt_name_server(&name, server_address);
creq = resolve_name_send(resolve_ctx, &name, result->event_ctx);
if (composite_nomem(creq, result)) goto failed;
composite_continue(result, creq, continue_resolve_name, result);
@@ -159,7 +156,7 @@ static void connect_multi_next_socket(struct composite_context *result)
talloc_steal(state, state->sock);
creq = socket_connect_send(state->sock, NULL,
- state->addr, 0, multi->resolve_ctx,
+ state->addr, 0,
result->event_ctx);
if (composite_nomem(creq, result)) return;
talloc_steal(state, creq);
diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h
index ec3afe8f7f..4741a67990 100644
--- a/source4/lib/socket/socket.h
+++ b/source4/lib/socket/socket.h
@@ -20,8 +20,7 @@
#ifndef _SAMBA_SOCKET_H
#define _SAMBA_SOCKET_H
-#include "lib/events/events.h"
-
+struct event_context;
struct socket_context;
enum socket_type {
@@ -179,14 +178,12 @@ struct composite_context *socket_connect_send(struct socket_context *sock,
struct socket_address *my_address,
struct socket_address *server_address,
uint32_t flags,
- struct resolve_context *resolve_ctx,
struct event_context *event_ctx);
NTSTATUS socket_connect_recv(struct composite_context *ctx);
NTSTATUS socket_connect_ev(struct socket_context *sock,
struct socket_address *my_address,
struct socket_address *server_address,
uint32_t flags,
- struct resolve_context *resolve_ctx,
struct event_context *ev);
struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx,
diff --git a/source4/lib/socket/testsuite.c b/source4/lib/socket/testsuite.c
index 2c25d8f491..0fae880ca0 100644
--- a/source4/lib/socket/testsuite.c
+++ b/source4/lib/socket/testsuite.c
@@ -152,7 +152,7 @@ static bool test_tcp(struct torture_context *tctx)
torture_comment(tctx, "server port is %d\n", srv_addr->port);
- status = socket_connect_ev(sock2, NULL, srv_addr, 0, NULL, ev);
+ status = socket_connect_ev(sock2, NULL, srv_addr, 0, ev);
torture_assert_ntstatus_ok(tctx, status, "connect() on socket 2");
status = socket_accept(sock1, &sock3);
diff --git a/source4/lib/stream/packet.h b/source4/lib/stream/packet.h
index 45826c5f14..f7b10cd878 100644
--- a/source4/lib/stream/packet.h
+++ b/source4/lib/stream/packet.h
@@ -20,6 +20,10 @@
*/
+struct packet_context;
+struct event_context;
+struct fd_event;
+
typedef NTSTATUS (*packet_full_request_fn_t)(void *private,
DATA_BLOB blob, size_t *packet_size);
typedef NTSTATUS (*packet_callback_fn_t)(void *private, DATA_BLOB blob);
diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h
index 28cd6a88dc..25799d6a94 100644
--- a/source4/libcli/composite/composite.h
+++ b/source4/libcli/composite/composite.h
@@ -24,6 +24,8 @@
#include "libcli/raw/interfaces.h"
+struct event_context;
+
/*
this defines the structures associated with "composite"
requests. Composite requests are libcli requests that are internally
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index 8c31077d8c..85cba421e2 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -117,8 +117,7 @@ LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o
# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h
[SUBSYSTEM::LIBCLI_WREPL]
-PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \
- LIBPACKET LIBNDR
+PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBEVENTS LIBPACKET
LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o
@@ -136,6 +135,7 @@ PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF
LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \
bcast.o nbtlist.o wins.o \
+ dns_ex.o \
host.o resolve_lp.o)
$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index 87c89daf9f..7a65cc5c27 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -504,9 +504,9 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
return result;
}
-static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
- struct asn1_data *data,
- const char **result)
+bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
+ struct asn1_data *data,
+ const char **result)
{
DATA_BLOB string;
if (!asn1_read_OctetString(data, mem_ctx, &string))
@@ -894,7 +894,7 @@ failed:
return NULL;
}
-
+/* Decode a single LDAP attribute, possibly containing multiple values */
static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element *attrib)
{
@@ -911,11 +911,11 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
}
-static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
- struct ldb_message_element **attributes,
- int *num_attributes)
+/* Decode a set of LDAP attributes, as found in the dereference control */
+void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
{
- asn1_start_tag(data, ASN1_SEQUENCE(0));
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
struct ldb_message_element attrib;
ZERO_STRUCT(attrib);
@@ -923,6 +923,16 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
add_attrib_to_array_talloc(mem_ctx, &attrib,
attributes, num_attributes);
}
+}
+
+/* Decode a set of LDAP attributes, as found in a search entry */
+void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
+{
+ asn1_start_tag(data, ASN1_SEQUENCE(0));
+ ldap_decode_attribs_bare(mem_ctx, data,
+ attributes, num_attributes);
asn1_end_tag(data);
}
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 7f43e16c95..082f6fa3e4 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -358,7 +358,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
}
ctx = socket_connect_send(conn->sock, NULL, unix_addr,
- 0, lp_resolve_context(conn->lp_ctx), conn->event.event_ctx);
+ 0, conn->event.event_ctx);
ctx->async.fn = ldap_connect_recv_unix_conn;
ctx->async.private_data = state;
return result;
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 930d97c40d..109837c2bf 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -24,6 +24,7 @@
#include "libcli/ldap/ldap.h"
#include "lib/ldb/include/ldb.h"
#include "libcli/ldap/ldap_proto.h"
+#include "dsdb/samdb/samdb.h"
struct control_handler {
const char *oid;
@@ -1087,6 +1088,119 @@ static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
return true;
}
+static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
+{
+ struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
+ int i,j;
+ struct asn1_data *data = asn1_init(mem_ctx);
+
+ if (!data) return false;
+
+ if (!control) return false;
+
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ for (i=0; control->dereference && control->dereference[i]; i++) {
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) {
+ return false;
+ }
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) {
+ if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j],
+ strlen(control->dereference[i]->dereference_attribute[j]))) {
+ return false;
+ }
+ }
+
+ asn1_pop_tag(data);
+ asn1_pop_tag(data);
+ }
+ asn1_pop_tag(data);
+
+ *out = data_blob_talloc(mem_ctx, data->data, data->length);
+ if (out->data == NULL) {
+ return false;
+ }
+ talloc_free(data);
+ return true;
+}
+
+static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ struct asn1_data *data = asn1_init(mem_ctx);
+ struct dsdb_openldap_dereference_result_control *control;
+ struct dsdb_openldap_dereference_result **r = NULL;
+ int i = 0;
+ if (!data) return false;
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) return false;
+
+ if (!asn1_load(data, in)) {
+ return false;
+ }
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) {
+ return false;
+ }
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ while (asn1_tag_remaining(data) > 0) {
+ r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2);
+ if (!r) {
+ return false;
+ }
+ r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result);
+ if (!r[i]) {
+ return false;
+ }
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
+ if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
+ return false;
+ }
+
+ ldap_decode_attribs_bare(r, data, &r[i]->attributes,
+ &r[i]->num_attributes);
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+ }
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+ i++;
+ r[i] = NULL;
+ }
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+
+ control->attributes = r;
+ *out = control;
+
+ return true;
+}
+
struct control_handler ldap_known_controls[] = {
{ "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
{ "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
@@ -1107,6 +1221,7 @@ struct control_handler ldap_known_controls[] = {
{ "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
{ "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
+ { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
{ NULL, NULL, NULL }
};
diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c
index 5e938ea148..f0a11ba41f 100644
--- a/source4/libcli/ldap/ldap_ndr.c
+++ b/source4/libcli/ldap/ldap_ndr.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "libcli/ldap/ldap.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c
index 0a71ebed99..866ce7a152 100644
--- a/source4/libcli/resolve/bcast.c
+++ b/source4/libcli/resolve/bcast.c
@@ -37,7 +37,8 @@ struct resolve_bcast_data {
*/
struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- void *userdata,
+ void *userdata, uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
int num_interfaces;
@@ -63,7 +64,9 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
}
address_list[count] = NULL;
- c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, data->nbt_timeout, true, false);
+ c = resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
+ address_list, data->ifaces, data->nbt_port,
+ data->nbt_timeout, true, false);
talloc_free(address_list);
return c;
@@ -74,9 +77,10 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs);
+ NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs, names);
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
/* this makes much more sense for a bcast name resolution
timeout */
@@ -85,26 +89,6 @@ NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
return status;
}
-/*
- broadcast name resolution method - sync call
- */
-NTSTATUS resolve_name_bcast(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- struct socket_address ***addrs)
-{
- struct resolve_bcast_data *data = talloc(mem_ctx, struct resolve_bcast_data);
- struct composite_context *c;
- data->ifaces = talloc_reference(data, ifaces);
- data->nbt_port = nbt_port;
- data->nbt_timeout = nbt_timeout;
-
- c = resolve_name_bcast_send(mem_ctx, NULL, data, name);
- return resolve_name_bcast_recv(c, mem_ctx, addrs);
-}
-
bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
{
struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data);
diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c
new file mode 100644
index 0000000000..948ad9f134
--- /dev/null
+++ b/source4/libcli/resolve/dns_ex.c
@@ -0,0 +1,532 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ async getaddrinfo()/dns_lookup() name resolution module
+
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Stefan Metzmacher 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/>.
+*/
+
+/*
+ this module uses a fork() per getaddrinfo() or dns_looup() call.
+ At first that might seem crazy, but it is actually very fast,
+ and solves many of the tricky problems of keeping a child
+ hanging around in a librar (like what happens when the parent forks).
+ We use a talloc destructor to ensure that the child is cleaned up
+ when we have finished with this name resolution.
+*/
+
+#include "includes.h"
+#include "lib/events/events.h"
+#include "system/network.h"
+#include "system/filesys.h"
+#include "lib/socket/socket.h"
+#include "libcli/composite/composite.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "libcli/resolve/resolve.h"
+#include "heimdal/lib/roken/resolve.h"
+
+struct dns_ex_state {
+ bool do_fallback;
+ uint32_t flags;
+ uint16_t port;
+ struct nbt_name name;
+ struct socket_address **addrs;
+ char **names;
+ pid_t child;
+ int child_fd;
+ struct fd_event *fde;
+ struct event_context *event_ctx;
+};
+
+/*
+ kill off a wayward child if needed. This allows us to stop an async
+ name resolution without leaving a potentially blocking call running
+ in a child
+*/
+static int dns_ex_destructor(struct dns_ex_state *state)
+{
+ int status;
+
+ kill(state->child, SIGTERM);
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
+
+ return 0;
+}
+
+/*
+ the blocking child
+*/
+static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
+{
+ struct dns_reply *reply;
+ struct resource_record *rr;
+ uint32_t count = 0;
+ uint32_t srv_valid = 0;
+ struct resource_record **srv_rr;
+ uint32_t addrs_valid = 0;
+ struct resource_record **addrs_rr;
+ char *addrs;
+ bool first;
+ uint32_t i;
+ bool do_srv = (state->flags & RESOLVE_NAME_FLAG_DNS_SRV);
+
+ /* this is the blocking call we are going to lots of trouble
+ to avoid in the parent */
+ reply = dns_lookup(state->name.name, do_srv?"SRV":"A");
+ if (!reply) {
+ goto done;
+ }
+
+ if (do_srv) {
+ dns_srv_order(reply);
+ }
+
+ /* Loop over all returned records and pick the "srv" records */
+ for (rr=reply->head; rr; rr=rr->next) {
+ /* we are only interested in the IN class */
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ if (do_srv) {
+ /* we are only interested in SRV records */
+ if (rr->type != T_SRV) {
+ continue;
+ }
+
+ /* verify we actually have a SRV record here */
+ if (!rr->u.srv) {
+ continue;
+ }
+
+ /* Verify we got a port */
+ if (rr->u.srv->port == 0) {
+ continue;
+ }
+ } else {
+ /* we are only interested in A records */
+ /* TODO: add AAAA support */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a A record here */
+ if (!rr->u.a) {
+ continue;
+ }
+ }
+ count++;
+ }
+
+ if (count == 0) {
+ goto done;
+ }
+
+ srv_rr = talloc_zero_array(state,
+ struct resource_record *,
+ count);
+ if (!srv_rr) {
+ goto done;
+ }
+
+ addrs_rr = talloc_zero_array(state,
+ struct resource_record *,
+ count);
+ if (!addrs_rr) {
+ goto done;
+ }
+
+ /* Loop over all returned records and pick the records */
+ for (rr=reply->head;rr;rr=rr->next) {
+ /* we are only interested in the IN class */
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ if (do_srv) {
+ /* we are only interested in SRV records */
+ if (rr->type != T_SRV) {
+ continue;
+ }
+
+ /* verify we actually have a srv record here */
+ if (!rr->u.srv) {
+ continue;
+ }
+
+ /* Verify we got a port */
+ if (rr->u.srv->port == 0) {
+ continue;
+ }
+
+ srv_rr[srv_valid] = rr;
+ srv_valid++;
+ } else {
+ /* we are only interested in A records */
+ /* TODO: add AAAA support */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a A record here */
+ if (!rr->u.a) {
+ continue;
+ }
+
+ addrs_rr[addrs_valid] = rr;
+ addrs_valid++;
+ }
+ }
+
+ for (i=0; i < srv_valid; i++) {
+ for (rr=reply->head;rr;rr=rr->next) {
+
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ /* we are only interested in SRV records */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a srv record here */
+ if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) {
+ continue;
+ }
+
+ addrs_rr[i] = rr;
+ addrs_valid++;
+ break;
+ }
+ }
+
+ if (addrs_valid == 0) {
+ goto done;
+ }
+
+ addrs = talloc_strdup(state, "");
+ if (!addrs) {
+ goto done;
+ }
+ first = true;
+ for (i=0; i < count; i++) {
+ uint16_t port;
+ if (!addrs_rr[i]) {
+ continue;
+ }
+
+ if (srv_rr[i] &&
+ (state->flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) {
+ port = srv_rr[i]->u.srv->port;
+ } else {
+ port = state->port;
+ }
+
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
+ first?"":",",
+ inet_ntoa(*addrs_rr[i]->u.a),
+ port,
+ addrs_rr[i]->domain);
+ if (!addrs) {
+ goto done;
+ }
+ first = false;
+ }
+
+ if (addrs) {
+ write(fd, addrs, talloc_get_size(addrs));
+ }
+
+done:
+ close(fd);
+}
+
+/*
+ the blocking child
+*/
+static void run_child_getaddrinfo(struct dns_ex_state *state, int fd)
+{
+ int ret;
+ struct addrinfo hints;
+ struct addrinfo *res;
+ struct addrinfo *res_list = NULL;
+ char *addrs;
+ bool first;
+
+ ZERO_STRUCT(hints);
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+
+ ret = getaddrinfo(state->name.name, "0", &hints, &res_list);
+ if (ret == EAI_NODATA && state->do_fallback) {
+ /* getaddrinfo() doesn't handle CNAME records */
+ run_child_dns_lookup(state, fd);
+ return;
+ }
+ if (ret != 0) {
+ goto done;
+ }
+
+ addrs = talloc_strdup(state, "");
+ if (!addrs) {
+ goto done;
+ }
+ first = true;
+ for (res = res_list; res; res = res->ai_next) {
+ struct sockaddr_in *in;
+
+ if (res->ai_family != AF_INET) {
+ continue;
+ }
+ in = (struct sockaddr_in *)res->ai_addr;
+
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
+ first?"":",",
+ inet_ntoa(in->sin_addr),
+ state->port,
+ state->name.name);
+ if (!addrs) {
+ goto done;
+ }
+ first = false;
+ }
+
+ if (addrs) {
+ write(fd, addrs, talloc_get_size(addrs));
+ }
+done:
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
+ close(fd);
+}
+
+/*
+ handle a read event on the pipe
+*/
+static void pipe_handler(struct event_context *ev, struct fd_event *fde,
+ uint16_t flags, void *private_data)
+{
+ struct composite_context *c = talloc_get_type(private_data, struct composite_context);
+ struct dns_ex_state *state = talloc_get_type(c->private_data,
+ struct dns_ex_state);
+ char *address;
+ uint32_t num_addrs, i;
+ char **addrs;
+ int ret;
+ int status;
+ int value = 0;
+
+ /* if we get any event from the child then we know that we
+ won't need to kill it off */
+ talloc_set_destructor(state, NULL);
+
+ if (ioctl(state->child_fd, FIONREAD, &value) != 0) {
+ value = 8192;
+ }
+
+ address = talloc_array(state, char, value+1);
+ if (address) {
+ /* yes, we don't care about EAGAIN or other niceities
+ here. They just can't happen with this parent/child
+ relationship, and even if they did then giving an error is
+ the right thing to do */
+ ret = read(state->child_fd, address, value);
+ } else {
+ ret = -1;
+ }
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
+
+ if (ret <= 0) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ /* enusre the address looks good */
+ address[ret] = 0;
+
+ addrs = str_list_make(state, address, ",");
+ if (composite_nomem(addrs, c)) return;
+
+ num_addrs = str_list_length((const char * const *)addrs);
+
+ state->addrs = talloc_array(state, struct socket_address *,
+ num_addrs+1);
+ if (composite_nomem(state->addrs, c)) return;
+
+ state->names = talloc_array(state, char *, num_addrs+1);
+ if (composite_nomem(state->names, c)) return;
+
+ for (i=0; i < num_addrs; i++) {
+ uint32_t port = 0;
+ char *p = strrchr(addrs[i], ':');
+ char *n;
+
+ if (!p) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ *p = '\0';
+ p++;
+
+ n = strrchr(p, '/');
+ if (!n) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ *n = '\0';
+ n++;
+
+ if (strcmp(addrs[i], "0.0.0.0") == 0 ||
+ inet_addr(addrs[i]) == INADDR_NONE) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+ port = strtoul(p, NULL, 10);
+ if (port > UINT16_MAX) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+ state->addrs[i] = socket_address_from_strings(state->addrs,
+ "ipv4",
+ addrs[i],
+ port);
+ if (composite_nomem(state->addrs[i], c)) return;
+
+ state->names[i] = talloc_strdup(state->names, n);
+ if (composite_nomem(state->names[i], c)) return;
+ }
+ state->addrs[i] = NULL;
+ state->names[i] = NULL;
+
+ composite_done(c);
+}
+
+/*
+ getaddrinfo() or dns_lookup() name resolution method - async send
+ */
+struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx,
+ struct event_context *event_ctx,
+ void *privdata,
+ uint32_t flags,
+ uint16_t port,
+ struct nbt_name *name,
+ bool do_fallback)
+{
+ struct composite_context *c;
+ struct dns_ex_state *state;
+ int fd[2] = { -1, -1 };
+ int ret;
+
+ c = composite_create(mem_ctx, event_ctx);
+ if (c == NULL) return NULL;
+
+ if (flags & RESOLVE_NAME_FLAG_FORCE_NBT) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
+
+ state = talloc_zero(c, struct dns_ex_state);
+ if (composite_nomem(state, c)) return c;
+ c->private_data = state;
+
+ c->status = nbt_name_dup(state, name, &state->name);
+ if (!composite_is_ok(c)) return c;
+
+ /* setup a pipe to chat to our child */
+ ret = pipe(fd);
+ if (ret == -1) {
+ composite_error(c, map_nt_error_from_unix(errno));
+ return c;
+ }
+
+ state->do_fallback = do_fallback;
+ state->flags = flags;
+ state->port = port;
+
+ state->child_fd = fd[0];
+ state->event_ctx = c->event_ctx;
+
+ /* we need to put the child in our event context so
+ we know when the dns_lookup() has finished */
+ state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,
+ pipe_handler, c);
+ if (composite_nomem(state->fde, c)) {
+ close(fd[0]);
+ close(fd[1]);
+ return c;
+ }
+
+ state->child = fork();
+ if (state->child == (pid_t)-1) {
+ composite_error(c, map_nt_error_from_unix(errno));
+ return c;
+ }
+
+ if (state->child == 0) {
+ close(fd[0]);
+ if (state->flags & RESOLVE_NAME_FLAG_FORCE_DNS) {
+ run_child_dns_lookup(state, fd[1]);
+ } else {
+ run_child_getaddrinfo(state, fd[1]);
+ }
+ _exit(0);
+ }
+ close(fd[1]);
+
+ /* cleanup wayward children */
+ talloc_set_destructor(state, dns_ex_destructor);
+
+ return c;
+}
+
+/*
+ getaddrinfo() or dns_lookup() name resolution method - recv side
+*/
+NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
+ TALLOC_CTX *mem_ctx,
+ struct socket_address ***addrs,
+ char ***names)
+{
+ NTSTATUS status;
+
+ status = composite_wait(c);
+
+ if (NT_STATUS_IS_OK(status)) {
+ struct dns_ex_state *state = talloc_get_type(c->private_data,
+ struct dns_ex_state);
+ *addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
+ }
+
+ talloc_free(c);
+ return status;
+}
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 7b1aef803e..b7eaf4bef5 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -1,33 +1,25 @@
/*
Unix SMB/CIFS implementation.
- async gethostbyname() name resolution module
+ async "host" name resolution module
Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Stefan Metzmacher 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/>.
*/
-/*
- this module uses a fork() per gethostbyname() call. At first that
- might seem crazy, but it is actually very fast, and solves many of
- the tricky problems of keeping a child hanging around in a library
- (like what happens when the parent forks). We use a talloc
- destructor to ensure that the child is cleaned up when we have
- finished with this name resolution.
-*/
-
#include "includes.h"
#include "lib/events/events.h"
#include "system/network.h"
@@ -37,201 +29,28 @@
#include "librpc/gen_ndr/ndr_nbt.h"
#include "libcli/resolve/resolve.h"
-struct host_state {
- struct nbt_name name;
- struct socket_address **addrs;
- pid_t child;
- int child_fd;
- struct fd_event *fde;
- struct event_context *event_ctx;
-};
-
-
/*
- kill off a wayward child if needed. This allows us to stop an async
- name resolution without leaving a potentially blocking call running
- in a child
-*/
-static int host_destructor(struct host_state *state)
-{
- int status;
-
- kill(state->child, SIGTERM);
- close(state->child_fd);
- if (waitpid(state->child, &status, WNOHANG) == 0) {
- kill(state->child, SIGKILL);
- waitpid(state->child, &status, 0);
- }
-
- return 0;
-}
-
-/*
- the blocking child
-*/
-static void run_child(struct composite_context *c, int fd)
-{
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- struct in_addr ip;
- const char *address;
-
- /* this is the blocking call we are going to lots of trouble
- to avoid in the parent */
- ip = interpret_addr2(state->name.name);
-
- address = inet_ntoa(ip);
- if (address != NULL) {
- write(fd, address, strlen(address)+1);
- }
- close(fd);
-}
-
-/*
- handle a read event on the pipe
-*/
-static void pipe_handler(struct event_context *ev, struct fd_event *fde,
- uint16_t flags, void *private_data)
-{
- struct composite_context *c = talloc_get_type(private_data, struct composite_context);
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- char address[128];
- int ret;
- int status;
-
- /* if we get any event from the child then we know that we
- won't need to kill it off */
- talloc_set_destructor(state, NULL);
-
- /* yes, we don't care about EAGAIN or other niceities
- here. They just can't happen with this parent/child
- relationship, and even if they did then giving an error is
- the right thing to do */
- ret = read(state->child_fd, address, sizeof(address)-1);
- close(state->child_fd);
- if (waitpid(state->child, &status, WNOHANG) == 0) {
- kill(state->child, SIGKILL);
- waitpid(state->child, &status, 0);
- }
- if (ret <= 0) {
- composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return;
- }
-
- /* enusre the address looks good */
- address[ret] = 0;
- if (strcmp(address, "0.0.0.0") == 0 ||
- inet_addr(address) == INADDR_NONE) {
- composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return;
- }
-
- state->addrs = talloc_array(state, struct socket_address *, 2);
- if (composite_nomem(state->addrs, c)) return;
-
- state->addrs[0] = socket_address_from_strings(state->addrs,
- "ipv4",
- address,
- 0);
- if (composite_nomem(state->addrs[0], c)) return;
- state->addrs[1] = NULL;
-
- composite_done(c);
-}
-
-/*
- gethostbyname name resolution method - async send
+ getaddrinfo() (with fallback to dns_lookup()) name resolution method - async send
*/
struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- void *privdata,
+ void *privdata, uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
- struct composite_context *c;
- struct host_state *state;
- int fd[2] = { -1, -1 };
- int ret;
-
- c = composite_create(mem_ctx, event_ctx);
- if (c == NULL) return NULL;
-
- if (composite_nomem(c->event_ctx, c)) return c;
-
- state = talloc(c, struct host_state);
- if (composite_nomem(state, c)) return c;
- c->private_data = state;
-
- c->status = nbt_name_dup(state, name, &state->name);
- if (!composite_is_ok(c)) return c;
-
- /* setup a pipe to chat to our child */
- ret = pipe(fd);
- if (ret == -1) {
- composite_error(c, map_nt_error_from_unix(errno));
- return c;
- }
-
- state->child_fd = fd[0];
- state->event_ctx = c->event_ctx;
-
- /* we need to put the child in our event context so
- we know when the gethostbyname() has finished */
- state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,
- pipe_handler, c);
- if (composite_nomem(state->fde, c)) {
- close(fd[0]);
- close(fd[1]);
- return c;
- }
-
- state->child = fork();
- if (state->child == (pid_t)-1) {
- composite_error(c, map_nt_error_from_unix(errno));
- return c;
- }
-
-
- if (state->child == 0) {
- close(fd[0]);
- run_child(c, fd[1]);
- _exit(0);
- }
- close(fd[1]);
-
- /* cleanup wayward children */
- talloc_set_destructor(state, host_destructor);
-
- return c;
+ return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, flags,
+ port, name, true);
}
/*
- gethostbyname name resolution method - recv side
+ getaddrinfo() (with fallback to dns_lookup()) name resolution method - recv side
*/
NTSTATUS resolve_name_host_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- *addrs = talloc_steal(mem_ctx, state->addrs);
- }
-
- talloc_free(c);
- return status;
-}
-
-/*
- gethostbyname name resolution method - sync call
- */
-NTSTATUS resolve_name_host(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, NULL, name);
- return resolve_name_host_recv(c, mem_ctx, addrs);
+ return resolve_name_dns_ex_recv(c, mem_ctx, addrs, names);
}
bool resolve_context_add_host_method(struct resolve_context *ctx)
diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c
index 9c53fcb7ec..734fd5a5bc 100644
--- a/source4/libcli/resolve/nbtlist.c
+++ b/source4/libcli/resolve/nbtlist.c
@@ -34,12 +34,15 @@
#include "libcli/resolve/resolve.h"
struct nbtlist_state {
+ uint16_t flags;
+ uint16_t port;
struct nbt_name name;
struct nbt_name_socket *nbtsock;
int num_queries;
struct nbt_name_request **queries;
struct nbt_name_query *io_queries;
struct socket_address **addrs;
+ char **names;
struct interface *ifaces;
};
@@ -81,14 +84,21 @@ static void nbtlist_handler(struct nbt_name_request *req)
q->out.num_addrs + 1);
if (composite_nomem(state->addrs, c)) return;
+ state->names = talloc_array(state, char *, q->out.num_addrs + 1);
+ if (composite_nomem(state->names, c)) return;
+
for (i=0;i<q->out.num_addrs;i++) {
state->addrs[i] = socket_address_from_strings(state->addrs,
"ipv4",
q->out.reply_addrs[i],
- 0);
+ state->port);
if (composite_nomem(state->addrs[i], c)) return;
+
+ state->names[i] = talloc_strdup(state->names, state->name.name);
+ if (composite_nomem(state->names[i], c)) return;
}
state->addrs[i] = NULL;
+ state->names[i] = NULL;
composite_done(c);
}
@@ -98,6 +108,8 @@ static void nbtlist_handler(struct nbt_name_request *req)
*/
struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name,
const char **address_list,
struct interface *ifaces,
@@ -113,12 +125,23 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
c = composite_create(mem_ctx, event_ctx);
if (c == NULL) return NULL;
- if (composite_nomem(c->event_ctx, c)) return c;
+ if (flags & RESOLVE_NAME_FLAG_FORCE_DNS) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
+
+ if (strlen(name->name) > 15) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
state = talloc(c, struct nbtlist_state);
if (composite_nomem(state, c)) return c;
c->private_data = state;
+ state->flags = flags;
+ state->port = port;
+
c->status = nbt_name_dup(state, name, &state->name);
if (!composite_is_ok(c)) return c;
@@ -180,7 +203,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -189,29 +213,12 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c,
if (NT_STATUS_IS_OK(status)) {
struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state);
*addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
}
talloc_free(c);
return status;
}
-/*
- nbt list of addresses name resolution method - sync call
- */
-NTSTATUS resolve_name_nbtlist(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- const char **address_list,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- bool broadcast, bool wins_lookup,
- struct socket_address ***addrs)
-{
- struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL,
- name, address_list,
- ifaces, nbt_port,
- nbt_timeout,
- broadcast, wins_lookup);
- return resolve_name_nbtlist_recv(c, mem_ctx, addrs);
-}
-
diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c
index 7d1c48cbee..752678abb8 100644
--- a/source4/libcli/resolve/resolve.c
+++ b/source4/libcli/resolve/resolve.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "libcli/composite/composite.h"
#include "libcli/resolve/resolve.h"
#include "librpc/gen_ndr/ndr_nbt.h"
@@ -32,9 +31,12 @@
struct resolve_state {
struct resolve_context *ctx;
struct resolve_method *method;
+ uint32_t flags;
+ uint16_t port;
struct nbt_name name;
struct composite_context *creq;
struct socket_address **addrs;
+ char **names;
};
static struct composite_context *setup_next_method(struct composite_context *c);
@@ -84,7 +86,7 @@ static void resolve_handler(struct composite_context *creq)
struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state);
const struct resolve_method *method = state->method;
- c->status = method->recv_fn(creq, state, &state->addrs);
+ c->status = method->recv_fn(creq, state, &state->addrs, &state->names);
if (!NT_STATUS_IS_OK(c->status)) {
state->method = state->method->next;
@@ -112,7 +114,11 @@ static struct composite_context *setup_next_method(struct composite_context *c)
do {
if (state->method) {
- creq = state->method->send_fn(c, c->event_ctx, state->method->privdata, &state->name);
+ creq = state->method->send_fn(c, c->event_ctx,
+ state->method->privdata,
+ state->flags,
+ state->port,
+ &state->name);
}
if (creq == NULL && state->method) state->method = state->method->next;
@@ -130,6 +136,8 @@ static struct composite_context *setup_next_method(struct composite_context *c)
general name resolution - async send
*/
struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name,
struct event_context *event_ctx)
{
@@ -149,6 +157,9 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
if (composite_nomem(state, c)) return c;
c->private_data = state;
+ state->flags = flags;
+ state->port = port;
+
c->status = nbt_name_dup(state, name, &state->name);
if (!composite_is_ok(c)) return c;
@@ -165,6 +176,11 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
inet_ntoa(ip), 0);
if (composite_nomem(state->addrs[0], c)) return c;
state->addrs[1] = NULL;
+ state->names = talloc_array(state, char *, 2);
+ if (composite_nomem(state->names, c)) return c;
+ state->names[0] = talloc_strdup(state->names, state->name.name);
+ if (composite_nomem(state->names[0], c)) return c;
+ state->names[1] = NULL;
composite_done(c);
return c;
}
@@ -185,7 +201,8 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
*/
NTSTATUS resolve_name_all_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -194,30 +211,20 @@ NTSTATUS resolve_name_all_recv(struct composite_context *c,
if (NT_STATUS_IS_OK(status)) {
struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state);
*addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
}
talloc_free(c);
return status;
}
-/*
- general name resolution - sync call
- */
-NTSTATUS resolve_all_name(struct resolve_context *ctx,
- struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs,
- struct event_context *ev)
-{
- struct composite_context *c = resolve_name_all_send(ctx, name, ev);
- return resolve_name_all_recv(c, mem_ctx, addrs);
-}
-
struct composite_context *resolve_name_send(struct resolve_context *ctx,
struct nbt_name *name,
struct event_context *event_ctx)
{
- return resolve_name_all_send(ctx, name, event_ctx);
+ return resolve_name_all_send(ctx, 0, 0, name, event_ctx);
}
NTSTATUS resolve_name_recv(struct composite_context *c,
@@ -227,7 +234,7 @@ NTSTATUS resolve_name_recv(struct composite_context *c,
NTSTATUS status;
struct socket_address **addrs = NULL;
- status = resolve_name_all_recv(c, mem_ctx, &addrs);
+ status = resolve_name_all_recv(c, mem_ctx, &addrs, NULL);
if (NT_STATUS_IS_OK(status)) {
*reply_addr = talloc_steal(mem_ctx, addrs[0]->addr);
diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h
index 01fc930fce..b55ab83f2a 100644
--- a/source4/libcli/resolve/resolve.h
+++ b/source4/libcli/resolve/resolve.h
@@ -19,21 +19,35 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __RESOLVE_H__
-#define __RESOLVE_H__
+#ifndef __LIBCLI_RESOLVE_H__
+#define __LIBCLI_RESOLVE_H__
struct socket_address;
+struct event_context;
#include "../libcli/nbt/libnbt.h"
+
+/* force that only NBT name resolution is used */
+#define RESOLVE_NAME_FLAG_FORCE_NBT 0x00000001
+/* force that only DNS name resolution is used */
+#define RESOLVE_NAME_FLAG_FORCE_DNS 0x00000002
+/* tell the dns resolver to do a DNS SRV lookup */
+#define RESOLVE_NAME_FLAG_DNS_SRV 0x00000004
+/* allow the resolver to overwrite the given port, e.g. for DNS SRV */
+#define RESOLVE_NAME_FLAG_OVERWRITE_PORT 0x00000008
+
typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx,
struct event_context *,
void *privdata,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *);
typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *creq,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs);
+ struct socket_address ***addrs,
+ char ***names);
#include "libcli/resolve/proto.h"
struct interface;
#include "libcli/resolve/lp_proto.h"
-#endif /* __RESOLVE_H__ */
+#endif /* __LIBCLI_RESOLVE_H__ */
diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c
index 34de1158a5..f1d1fbc85c 100644
--- a/source4/libcli/resolve/testsuite.c
+++ b/source4/libcli/resolve/testsuite.c
@@ -44,9 +44,9 @@ static bool test_async_resolve(struct torture_context *tctx)
host, timelimit);
while (timeval_elapsed(&tv) < timelimit) {
struct socket_address **s;
- struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, &n);
+ struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, 0, 0, &n);
torture_assert(tctx, c != NULL, "resolve_name_host_send");
- torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s),
+ torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s, NULL),
"async resolve failed");
count++;
}
diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c
index ae142f7054..1940688ecb 100644
--- a/source4/libcli/resolve/wins.c
+++ b/source4/libcli/resolve/wins.c
@@ -40,11 +40,16 @@ struct composite_context *resolve_name_wins_send(
TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
void *userdata,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
struct resolve_wins_data *wins_data = talloc_get_type(userdata, struct resolve_wins_data);
if (wins_data->address_list == NULL) return NULL;
- return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, wins_data->ifaces, wins_data->nbt_port, wins_data->nbt_timeout, false, true);
+ return resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
+ wins_data->address_list, wins_data->ifaces,
+ wins_data->nbt_port, wins_data->nbt_timeout,
+ false, true);
}
/*
@@ -52,30 +57,10 @@ struct composite_context *resolve_name_wins_send(
*/
NTSTATUS resolve_name_wins_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- return resolve_name_nbtlist_recv(c, mem_ctx, addrs);
-}
-
-/*
- wins name resolution method - sync call
- */
-NTSTATUS resolve_name_wins(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- const char **address_list,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- struct socket_address ***addrs)
-{
- struct composite_context *c;
- struct resolve_wins_data *wins_data = talloc(mem_ctx, struct resolve_wins_data);
- wins_data->address_list = address_list;
- wins_data->ifaces = ifaces;
- wins_data->nbt_port = nbt_port;
- wins_data->nbt_timeout = nbt_timeout;
- c = resolve_name_wins_send(mem_ctx, NULL, wins_data, name);
- return resolve_name_wins_recv(c, mem_ctx, addrs);
+ return resolve_name_nbtlist_recv(c, mem_ctx, addrs, names);
}
bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c
index 84bda8c858..930616d211 100644
--- a/source4/libcli/wrepl/winsrepl.c
+++ b/source4/libcli/wrepl/winsrepl.c
@@ -30,7 +30,6 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
-#include "libcli/resolve/resolve.h"
static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status);
@@ -319,7 +318,6 @@ const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip)
connect a wrepl_socket to a WINS server
*/
struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
- struct resolve_context *resolve_ctx,
const char *our_ip, const char *peer_ip)
{
struct composite_context *result;
@@ -347,8 +345,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
if (composite_nomem(peer, result)) return result;
state->creq = socket_connect_send(wrepl_socket->sock, us, peer,
- 0, resolve_ctx,
- wrepl_socket->event.ctx);
+ 0, wrepl_socket->event.ctx);
composite_continue(result, state->creq, wrepl_connect_handler, state);
return result;
}
@@ -374,10 +371,10 @@ NTSTATUS wrepl_connect_recv(struct composite_context *result)
/*
connect a wrepl_socket to a WINS server - sync API
*/
-NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, struct resolve_context *resolve_ctx,
+NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket,
const char *our_ip, const char *peer_ip)
{
- struct composite_context *c_req = wrepl_connect_send(wrepl_socket, resolve_ctx, our_ip, peer_ip);
+ struct composite_context *c_req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip);
return wrepl_connect_recv(c_req);
}
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 475d14ec4d..7871a93604 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -56,8 +56,8 @@ NDR_SECURITY_OBJ_FILES = ../librpc/gen_ndr/ndr_security.o \
../librpc/ndr/ndr_sec_helper.o \
$(gen_ndrsrcdir)/ndr_server_id.o
-PUBLIC_HEADERS += ../librpc/gen_ndr/security.h)
-
+PUBLIC_HEADERS += ../librpc/gen_ndr/security.h
+PUBLIC_HEADERS += $(gen_ndrsrcdir)/server_id.h
[SUBSYSTEM::NDR_AUDIOSRV]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -166,7 +166,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o
-PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/ndr_samr_c.h)
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h ndr_samr_c.h)
[SUBSYSTEM::NDR_NFS4ACL]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
@@ -199,14 +199,14 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl.o
-PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/ndr_svcctl.h gen_ndr/svcctl.h)
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, ndr_svcctl.h svcctl.h)
[SUBSYSTEM::NDR_ATSVC]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr, atsvc.h ndr_atsvc.h)
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h)
[SUBSYSTEM::NDR_EVENTLOG]
PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
@@ -626,9 +626,9 @@ dcerpc_OBJ_FILES = $(addprefix $(dcerpcsrcdir)/, dcerpc.o dcerpc_auth.o dcerpc_s
$(eval $(call proto_header_template,$(dcerpcsrcdir)/dcerpc_proto.h,$(dcerpc_OBJ_FILES:.o=.c)))
-PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, rpc/dcerpc.h \
- gen_ndr/mgmt.h gen_ndr/ndr_mgmt.h gen_ndr/ndr_mgmt_c.h \
- gen_ndr/epmapper.h gen_ndr/ndr_epmapper.h gen_ndr/ndr_epmapper_c.h)
+PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, rpc/dcerpc.h) \
+ $(addprefix ../librpc/gen_ndr/, mgmt.h ndr_mgmt.h ndr_mgmt_c.h \
+ epmapper.h ndr_epmapper.h ndr_epmapper_c.h)
[PYTHON::python_dcerpc]
diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c
index 8ac235c67c..1d76c65f40 100644
--- a/source4/librpc/rpc/dcerpc_secondary.c
+++ b/source4/librpc/rpc/dcerpc_secondary.c
@@ -31,13 +31,14 @@
#include "auth/credentials/credentials.h"
#include "param/param.h"
#include "libcli/resolve/resolve.h"
-
+#include "lib/socket/socket.h"
struct sec_conn_state {
struct dcerpc_pipe *pipe;
struct dcerpc_pipe *pipe2;
struct dcerpc_binding *binding;
struct smbcli_tree *tree;
+ struct socket_address *peer_addr;
};
@@ -94,11 +95,17 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp
return c;
case NCACN_IP_TCP:
+ s->peer_addr = dcerpc_socket_peer_addr(s->pipe->conn, s);
+ if (!s->peer_addr) {
+ composite_error(c, NT_STATUS_INVALID_PARAMETER);
+ return c;
+ }
+
pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn,
- s->binding->host,
+ s->peer_addr->addr,
s->binding->target_hostname,
atoi(s->binding->endpoint),
- dcerpc_resolve_ctx(s->pipe->conn));
+ resolve_context_init(s));
composite_continue(c, pipe_tcp_req, continue_open_tcp, c);
return c;
diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c
index 548f270cc0..3cc8421339 100644
--- a/source4/librpc/rpc/dcerpc_sock.c
+++ b/source4/librpc/rpc/dcerpc_sock.c
@@ -39,7 +39,6 @@ struct sock_private {
struct packet_context *packet;
uint32_t pending_reads;
- struct resolve_context *resolve_ctx;
const char *path; /* For ncacn_unix_sock and ncalrpc */
};
@@ -306,7 +305,6 @@ static void continue_socket_connect(struct composite_context *ctx)
static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx,
struct dcerpc_connection *cn,
- struct resolve_context *resolve_context,
struct socket_address *server,
const char *target_hostname,
const char *full_path,
@@ -337,11 +335,9 @@ static struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ct
talloc_steal(s->sock, s->socket_ctx);
- s->sock->resolve_ctx = resolve_context;
s->sock->path = talloc_reference(s->sock, full_path);
conn_req = socket_connect_send(s->socket_ctx, NULL, s->server, 0,
- resolve_context,
c->event_ctx);
composite_continue(c, conn_req, continue_socket_connect, c);
return c;
@@ -390,7 +386,6 @@ static void continue_ip_resolve_name(struct composite_context *ctx)
/* resolve_nbt_name gives only ipv4 ... - send socket open request */
sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn,
- s->resolve_ctx,
s->srvaddr, s->target_hostname,
NULL,
NCACN_IP_TCP);
@@ -566,7 +561,6 @@ struct composite_context *dcerpc_pipe_open_unix_stream_send(struct dcerpc_connec
/* send socket open request */
sock_unix_req = dcerpc_pipe_open_socket_send(c, s->conn,
- NULL,
s->srvaddr, NULL,
s->path,
NCALRPC);
@@ -637,7 +631,7 @@ struct composite_context* dcerpc_pipe_open_pipe_send(struct dcerpc_connection *c
if (composite_nomem(s->srvaddr, c)) return c;
/* send socket open request */
- sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, NULL, s->srvaddr, NULL, s->path, NCALRPC);
+ sock_np_req = dcerpc_pipe_open_socket_send(c, s->conn, s->srvaddr, NULL, s->path, NCALRPC);
composite_continue(c, sock_np_req, continue_np_open_socket, c);
return c;
}
@@ -670,8 +664,9 @@ const char *dcerpc_unix_socket_path(struct dcerpc_connection *p)
return sock->path;
}
-struct resolve_context *dcerpc_resolve_ctx(struct dcerpc_connection *p)
+struct socket_address *dcerpc_socket_peer_addr(struct dcerpc_connection *p, TALLOC_CTX *mem_ctx)
{
struct sock_private *sock = (struct sock_private *)p->transport.private_data;
- return sock->resolve_ctx;
+ return socket_get_peer_addr(sock->sock, mem_ctx);
}
+
diff --git a/source4/main.mk b/source4/main.mk
index 1d4ffc5d44..e54196a2f9 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -14,6 +14,7 @@ mkinclude lib/ldb-samba/config.mk
mkinclude lib/tls/config.mk
mkinclude lib/registry/config.mk
mkinclude lib/messaging/config.mk
+mkinclude ../lib/tevent/config.mk
mkinclude lib/events/config.mk
mkinclude lib/cmdline/config.mk
mkinclude ../lib/socket_wrapper/config.mk
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index 554d5c5aef..b03d57166b 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -281,6 +281,8 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode,
uint16_t open_func, const char *fname,
union smb_open *io2)
{
+ io2->generic.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
+
if (flags & OPENX_FLAGS_REQUEST_OPLOCK) {
io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK;
}
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 1ea4e8f97d..b38efba79b 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -29,7 +29,7 @@ pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o
################################################
[SUBSYSTEM::pvfs_aio]
-PRIVATE_DEPENDENCIES = LIBAIO_LINUX
+PRIVATE_DEPENDENCIES = LIBEVENTS LIBAIO_LINUX
################################################
pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o
diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk
index 1122d5c39d..49ad70b95e 100644
--- a/source4/ntvfs/sysdep/config.mk
+++ b/source4/ntvfs/sysdep/config.mk
@@ -3,6 +3,7 @@
[MODULE::sys_notify_inotify]
SUBSYSTEM = sys_notify
INIT_FUNCTION = sys_notify_inotify_init
+PRIVATE_DEPENDENCIES = LIBEVENTS
# End MODULE sys_notify_inotify
################################################
@@ -17,6 +18,7 @@ sys_notify_inotify_OBJ_FILES = $(ntvfssrcdir)/sysdep/inotify.o
sys_notify_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_notify.o
[SUBSYSTEM::sys_lease_linux]
+PRIVATE_DEPENDENCIES = LIBEVENTS
sys_lease_linux_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease_linux.o
diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c
index 6e28b46550..64e993f395 100644
--- a/source4/ntvfs/sysdep/sys_lease.c
+++ b/source4/ntvfs/sysdep/sys_lease.c
@@ -25,7 +25,6 @@
#include "includes.h"
#include "system/filesys.h"
#include "ntvfs/sysdep/sys_lease.h"
-#include "lib/events/events.h"
#include "../lib/util/dlinklist.h"
#include "param/param.h"
diff --git a/source4/ntvfs/sysdep/sys_lease.h b/source4/ntvfs/sysdep/sys_lease.h
index e53760fb1e..6cda6398b2 100644
--- a/source4/ntvfs/sysdep/sys_lease.h
+++ b/source4/ntvfs/sysdep/sys_lease.h
@@ -22,6 +22,7 @@
struct sys_lease_context;
struct opendb_entry;
struct messaging_context;
+struct event_context;
typedef NTSTATUS (*sys_lease_send_break_fn)(struct messaging_context *,
struct opendb_entry *,
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index 76aa6b938a..f7b3812b06 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -18,7 +18,7 @@ PUBLIC_HEADERS += $(rpc_serversrcdir)/common/common.h
[MODULE::dcerpc_rpcecho]
INIT_FUNCTION = dcerpc_server_rpcecho_init
SUBSYSTEM = dcerpc_server
-PRIVATE_DEPENDENCIES = NDR_ECHO
+PRIVATE_DEPENDENCIES = NDR_ECHO LIBEVENTS
# End MODULE dcerpc_rpcecho
################################################
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 823d5e6ff6..95bff74e75 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -432,17 +432,18 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
"""
assert session_info is not None
- samdb = SamDB(samdb_path, session_info=session_info,
- credentials=credentials, lp=lp)
-
- # Wipes the database
try:
+ samdb = SamDB(samdb_path, session_info=session_info,
+ credentials=credentials, lp=lp)
+ # Wipes the database
samdb.erase()
except:
os.unlink(samdb_path)
-
- samdb = SamDB(samdb_path, session_info=session_info,
- credentials=credentials, lp=lp)
+ samdb = SamDB(samdb_path, session_info=session_info,
+ credentials=credentials, lp=lp)
+ # Wipes the database
+ samdb.erase()
+
#Add modules to the list to activate them by default
#beware often order is important
@@ -459,8 +460,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
"ranged_results",
"anr",
"server_sort",
- "extended_dn",
"asq",
+ "extended_dn_store",
+ "extended_dn_in",
"rdn_name",
"objectclass",
"samldb",
@@ -470,7 +472,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
tdb_modules_list = [
"subtree_rename",
"subtree_delete",
- "linked_attributes"]
+ "linked_attributes",
+ "extended_dn_out_ldb"]
modules_list2 = ["show_deleted",
"partition"]
@@ -488,11 +491,11 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
if ldap_backend_type == "fedora-ds":
backend_modules = ["nsuniqueid", "paged_searches"]
# We can handle linked attributes here, as we don't have directory-side subtree operations
- tdb_modules_list = ["linked_attributes"]
+ tdb_modules_list = ["linked_attributes", "extended_dn_out_dereference"]
elif ldap_backend_type == "openldap":
- backend_modules = ["normalise", "entryuuid", "paged_searches"]
+ backend_modules = ["entryuuid", "paged_searches"]
# OpenLDAP handles subtree renames, so we don't want to do any of these things
- tdb_modules_list = None
+ tdb_modules_list = ["extended_dn_out_dereference"]
elif ldap_backend is not None:
raise "LDAP Backend specified, but LDAP Backend Type not specified"
elif serverrole == "domain controller":
diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail
index b05cc1e39d..4484dbb8d9 100644
--- a/source4/selftest/knownfail
+++ b/source4/selftest/knownfail
@@ -8,7 +8,6 @@ local.iconv.*.next_codepoint()
base.delete.*.deltest17
base.delete.*.deltest20a
base.delete.*.deltest20b
-base.delete.*.deltest21
rpc.winreg.*security
samba4.local.registry.(dir|ldb).check hive security
samba4.local.registry.local.security
diff --git a/source4/setup/provision_basedn_modify.ldif b/source4/setup/provision_basedn_modify.ldif
index a7b501e8a8..7b13a193cb 100644
--- a/source4/setup/provision_basedn_modify.ldif
+++ b/source4/setup/provision_basedn_modify.ldif
@@ -61,9 +61,6 @@ uASCompat: 1
replace: modifiedCount
modifiedCount: 1
-
-replace: objectCategory
-objectCategory: CN=Domain-DNS,${SCHEMADN}
--
replace: fSMORoleOwner
fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-
diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif
index c27157d713..d42795b94d 100644
--- a/source4/setup/schema_samba4.ldif
+++ b/source4/setup/schema_samba4.ldif
@@ -244,7 +244,7 @@ systemAuxiliaryClass: samDomain
defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)
systemFlags: 16
defaultHidingValue: TRUE
-defaultObjectCategory: CN=Builtin-Domain,${SCHEMADN}
+defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN}
dn: CN=Samba4Top,${SCHEMADN}
diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf
index b64d581e0d..506dc504b4 100644
--- a/source4/setup/slapd.conf
+++ b/source4/setup/slapd.conf
@@ -51,6 +51,8 @@ defaultsearchbase ${DOMAINDN}
rootdn cn=Manager
+overlay deref
+
${REFINT_CONFIG}
${MEMBEROF_CONFIG}
diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h
index 227c298008..d66286da2e 100644
--- a/source4/smb_server/smb_server.h
+++ b/source4/smb_server/smb_server.h
@@ -21,10 +21,11 @@
#include "libcli/raw/request.h"
#include "libcli/raw/interfaces.h"
-#include "lib/events/events.h"
#include "lib/socket/socket.h"
#include "../lib/util/dlinklist.h"
+struct event_context;
+
/*
this header declares the core context structures associated with smb
sockets, tree connects, requests etc
diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk
index 63105d368c..a5f5aab65e 100644
--- a/source4/smbd/config.mk
+++ b/source4/smbd/config.mk
@@ -2,7 +2,7 @@
[SUBSYSTEM::service]
PRIVATE_DEPENDENCIES = \
- MESSAGING samba-socket NDR_NAMED_PIPE_AUTH
+ LIBEVENTS MESSAGING samba-socket NDR_NAMED_PIPE_AUTH
service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \
service.o \
diff --git a/source4/smbd/process_model.mk b/source4/smbd/process_model.mk
index 5ed8471a9d..d2ef048f40 100644
--- a/source4/smbd/process_model.mk
+++ b/source4/smbd/process_model.mk
@@ -15,7 +15,7 @@ process_model_single_OBJ_FILES = $(smbdsrcdir)/process_single.o
[MODULE::process_model_standard]
INIT_FUNCTION = process_model_standard_init
SUBSYSTEM = process_model
-PRIVATE_DEPENDENCIES = SETPROCTITLE
+PRIVATE_DEPENDENCIES = LIBEVENTS SETPROCTITLE
# End MODULE process_model_standard
################################################
@@ -37,6 +37,7 @@ process_model_thread_OBJ_FILES = $(smbdsrcdir)/process_thread.o
[MODULE::process_model_prefork]
INIT_FUNCTION = process_model_prefork_init
SUBSYSTEM = process_model
+PRIVATE_DEPENDENCIES = LIBEVENTS SETPROCTITLE
# End MODULE process_model_thread
################################################
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
index b2b102c01f..ad7ba76b0d 100644
--- a/source4/smbd/service_named_pipe.c
+++ b/source4/smbd/service_named_pipe.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
+#include "lib/events/events.h"
#include "lib/socket/socket.h"
#include "smbd/service.h"
#include "param/param.h"
diff --git a/source4/torture/basic/locking.c b/source4/torture/basic/locking.c
index 3f399c97ef..fcac52ca6a 100644
--- a/source4/torture/basic/locking.c
+++ b/source4/torture/basic/locking.c
@@ -624,10 +624,18 @@ ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
torture_comment(tctx, "a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
- smbcli_close(cli1->tree, fnum1);
- smbcli_close(cli2->tree, fnum2);
- smbcli_unlink(cli1->tree, fname);
-
+ torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
+ talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));
+
+ torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
+ talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));
+
+ torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum3),
+ talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));
+
+ torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),
+ talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));
+
return correct;
}
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index eaff5d5fda..71fa391003 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -107,7 +107,7 @@ PRIVATE_DEPENDENCIES = \
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \
- LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP \
+ LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_LDB TORTURE_UTIL TORTURE_RAP \
dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER
torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
@@ -191,6 +191,20 @@ TORTURE_LDAP_OBJ_FILES = $(addprefix $(torturesrcdir)/ldap/, common.o basic.o sc
$(eval $(call proto_header_template,$(torturesrcdir)/ldap/proto.h,$(TORTURE_LDAP_OBJ_FILES:.o=.c)))
#################################
+# Start SUBSYSTEM TORTURE_LDB
+[MODULE::TORTURE_LDB]
+SUBSYSTEM = smbtorture
+INIT_FUNCTION = torture_ldb_init
+PRIVATE_DEPENDENCIES = \
+ LDB_WRAP
+# End SUBSYSTEM TORTURE_LDB
+#################################
+
+TORTURE_LDB_OBJ_FILES = $(addprefix $(torturesrcdir)/ldb/, ldb.o)
+
+$(eval $(call proto_header_template,$(torturesrcdir)/ldb/proto.h,$(TORTURE_LDB_OBJ_FILES:.o=.c)))
+
+#################################
# Start SUBSYSTEM TORTURE_NBT
[MODULE::TORTURE_NBT]
SUBSYSTEM = smbtorture
diff --git a/source4/torture/ldb/ldb.c b/source4/torture/ldb/ldb.c
new file mode 100644
index 0000000000..c2977bcb70
--- /dev/null
+++ b/source4/torture/ldb/ldb.c
@@ -0,0 +1,735 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Test LDB attribute functions
+
+ Copyright (C) Andrew Bartlet <abartlet@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/>.
+*/
+
+#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"
+#include "torture/smbtorture.h"
+#include "torture/ldb/proto.h"
+
+static const char *sid = "S-1-5-21-4177067393-1453636373-93818737";
+static const char *hex_sid = "01040000000000051500000081FDF8F815BBA456718F9705";
+static const char *guid = "975ac5fa-35d9-431d-b86a-845bcd34fff9";
+static const char *guid2 = "{975ac5fa-35d9-431d-b86a-845bcd34fff9}";
+static const char *hex_guid = "FAC55A97D9351D43B86A845BCD34FFF9";
+
+static bool torture_ldb_attrs(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ const struct ldb_schema_attribute *attr;
+ struct ldb_val string_sid_blob, binary_sid_blob;
+ struct ldb_val string_guid_blob, string_guid_blob2, binary_guid_blob;
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Test SID behaviour */
+ torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectSid"),
+ "Failed to get objectSid schema attribute");
+
+ string_sid_blob = data_blob_string_const(sid);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse string SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &sid_blob, &binary_sid_blob), -1,
+ "Should have failed to parse binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ string_sid_blob, data_blob_string_const(sid),
+ "Write SID into string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
+ "Failed to compare binary and string SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to compare string and binary binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &string_sid_blob), 0,
+ "Failed to compare string and string SID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &binary_sid_blob), 0,
+ "Failed to compare binary and binary SID");
+
+ torture_assert(torture, attr->syntax->comparison_fn(ldb, mem_ctx, &guid_blob, &binary_sid_blob) != 0,
+ "Failed to distinguish binary GUID and binary SID");
+
+
+ /* Test GUID behaviour */
+ torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectGUID"),
+ "Failed to get objectGUID schema attribute");
+
+ string_guid_blob = data_blob_string_const(guid);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ string_guid_blob2 = data_blob_string_const(guid2);
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &string_guid_blob2, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_read_fn(ldb, mem_ctx,
+ &guid_blob, &binary_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
+ "Failed to print binary GUID as string");
+
+ torture_assert_data_blob_equal(torture, string_sid_blob, data_blob_string_const(sid),
+ "Write SID into string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
+ "Failed to compare binary and string GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to compare string and binary binary GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &string_guid_blob), 0,
+ "Failed to compare string and string GUID");
+
+ torture_assert_int_equal(torture,
+ attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &binary_guid_blob), 0,
+ "Failed to compare binary and binary GUID");
+
+
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_attrs(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ const struct ldb_dn_extended_syntax *attr;
+ struct ldb_val string_sid_blob, binary_sid_blob;
+ struct ldb_val string_guid_blob, binary_guid_blob;
+ struct ldb_val hex_sid_blob, hex_guid_blob;
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Test SID behaviour */
+ torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "SID"),
+ "Failed to get SID DN syntax");
+
+ string_sid_blob = data_blob_string_const(sid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &string_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse string SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ hex_sid_blob = data_blob_string_const(hex_sid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &hex_sid_blob, &binary_sid_blob), 0,
+ "Failed to parse HEX SID");
+
+ torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
+ "Read SID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &sid_blob, &binary_sid_blob), -1,
+ "Should have failed to parse binary SID");
+
+ torture_assert_int_equal(torture,
+ attr->write_hex_fn(ldb, mem_ctx, &sid_blob, &hex_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ hex_sid_blob, data_blob_string_const(hex_sid),
+ "Write SID into HEX string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->write_clear_fn(ldb, mem_ctx, &sid_blob, &string_sid_blob), 0,
+ "Failed to parse binary SID");
+
+ torture_assert_data_blob_equal(torture,
+ string_sid_blob, data_blob_string_const(sid),
+ "Write SID into clear string form failed");
+
+
+ /* Test GUID behaviour */
+ torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "GUID"),
+ "Failed to get GUID DN syntax");
+
+ string_guid_blob = data_blob_string_const(guid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &string_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse string GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ hex_guid_blob = data_blob_string_const(hex_guid);
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &hex_guid_blob, &binary_guid_blob), 0,
+ "Failed to parse HEX GUID");
+
+ torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
+ "Read GUID into blob form failed");
+
+ torture_assert_int_equal(torture,
+ attr->read_fn(ldb, mem_ctx,
+ &guid_blob, &binary_guid_blob), -1,
+ "Should have failed to parse binary GUID");
+
+ torture_assert_int_equal(torture,
+ attr->write_hex_fn(ldb, mem_ctx, &guid_blob, &hex_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture,
+ hex_guid_blob, data_blob_string_const(hex_guid),
+ "Write GUID into HEX string form failed");
+
+ torture_assert_int_equal(torture,
+ attr->write_clear_fn(ldb, mem_ctx, &guid_blob, &string_guid_blob), 0,
+ "Failed to parse binary GUID");
+
+ torture_assert_data_blob_equal(torture,
+ string_guid_blob, data_blob_string_const(guid),
+ "Write GUID into clear string form failed");
+
+
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_extended(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn, *dn2;
+
+ DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
+ DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);
+
+ const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, dn_str),
+ "Failed to create a 'normal' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'normal' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == false,
+ "Should not find plain DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on plain DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an GUID on plain DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL,
+ "Should not find an WKGUID on plain DN");
+
+ /* Now make an extended DN */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, dn_str),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ dn2 = ldb_dn_copy(mem_ctx, dn),
+ "Failed to copy the 'extended' DN");
+ talloc_free(dn);
+ dn = dn2;
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on extended DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on extended DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str,
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str),
+ "casefolded DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn",
+ "componet zero incorrect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"),
+ "componet zero incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, dn_str),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ hex_guid, hex_sid, dn_str),
+ "HEX extended linearized DN incorrect");
+
+ torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true,
+ "Failed to remove DN child");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == false,
+ "Extended DN flag should be cleared after child element removal");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an GUID on DN");
+
+
+ /* TODO: test setting these in the other order, and ensure it still comes out 'GUID first' */
+ torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0,
+ "Failed to set a GUID on DN");
+
+ torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0,
+ "Failed to set a SID on DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ guid, sid, "cn=users,dc=samba,dc=org"),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
+ hex_guid, hex_sid, "cn=users,dc=samba,dc=org"),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just GUID' DN (clear format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
+ guid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0,
+ "Should not find an 'normal' componet on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<GUID=%s>",
+ guid),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<GUID=%s>",
+ hex_guid),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just GUID' DN (HEX format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
+ hex_guid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
+ "Should find an GUID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
+ "Extended DN GUID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ /* Now check a 'just SID' DN (clear format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
+ sid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
+ talloc_asprintf(mem_ctx, "<SID=%s>",
+ sid),
+ "Clear extended linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
+ talloc_asprintf(mem_ctx, "<SID=%s>",
+ hex_sid),
+ "HEX extended linearized DN incorrect");
+
+ /* Now check a 'just SID' DN (HEX format) */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
+ hex_sid),
+ "Failed to create an 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate 'extended' DN");
+
+ torture_assert(torture, ldb_dn_has_extended(dn) == true,
+ "Should find extended DN to be 'extended'");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
+ "Should not find an SID on this DN");
+
+ torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
+ "Should find an SID on this DN");
+
+ torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
+ "Extended DN SID incorect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
+ "linearized DN incorrect");
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+
+static bool torture_ldb_dn(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn;
+ struct ldb_dn *child_dn;
+ struct ldb_dn *typo_dn;
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, NULL),
+ "Failed to create a NULL DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn),
+ "Failed to validate NULL DN");
+
+ torture_assert(torture,
+ ldb_dn_add_base_fmt(dn, "dc=org"),
+ "Failed to add base DN");
+
+ torture_assert(torture,
+ ldb_dn_add_child_fmt(dn, "dc=samba"),
+ "Failed to add base DN");
+
+ torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org",
+ "linearized DN incorrect");
+
+ torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org",
+ "extended linearized DN incorrect");
+
+ /* Check child DN comparisons */
+ torture_assert(torture,
+ child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"),
+ "Failed to create child DN");
+
+ torture_assert(torture,
+ ldb_dn_compare(dn, child_dn) != 0,
+ "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(child_dn, dn) != 0,
+ "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(dn, child_dn) == 0,
+ "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0");
+
+ /* Check comparisons with a truncated DN */
+ torture_assert(torture,
+ typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"),
+ "Failed to create 'typo' DN");
+
+ torture_assert(torture,
+ ldb_dn_compare(dn, typo_dn) != 0,
+ "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(typo_dn, dn) != 0,
+ "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0");
+
+ torture_assert(torture,
+ ldb_dn_compare_base(dn, typo_dn) != 0,
+ "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0");
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+static bool torture_ldb_dn_invalid_extended(struct torture_context *torture)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ struct ldb_context *ldb;
+ struct ldb_dn *dn;
+
+ const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";
+
+ torture_assert(torture,
+ ldb = ldb_init(mem_ctx, torture->ev),
+ "Failed to init ldb");
+
+ torture_assert_int_equal(torture,
+ ldb_register_samba_handlers(ldb), 0,
+ "Failed to register Samba handlers");
+
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
+
+ /* Check behaviour of a normal DN */
+ torture_assert(torture,
+ dn = ldb_dn_new(mem_ctx, ldb, "samba,dc=org"),
+ "Failed to create a 'normal' invalid DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'normal' invalid DN");
+
+ /* Now make an extended DN */
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<PID=%s>;%s",
+ sid, dn_str),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>%s",
+ sid, dn_str),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
+ sid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
+ hex_sid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
+ hex_guid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
+ guid),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ torture_assert(torture,
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=>"),
+ "Failed to create an invalid 'extended' DN");
+
+ torture_assert(torture,
+ ldb_dn_validate(dn) == false,
+ "should have failed to validate 'extended' DN");
+
+ return true;
+}
+
+NTSTATUS torture_ldb_init(void)
+{
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "LDB");
+ torture_suite_add_simple_test(suite, "ATTRS", torture_ldb_attrs);
+ torture_suite_add_simple_test(suite, "DN-ATTRS", torture_ldb_dn_attrs);
+ torture_suite_add_simple_test(suite, "DN-EXTENDED", torture_ldb_dn_extended);
+ torture_suite_add_simple_test(suite, "DN-INVALID-EXTENDED", torture_ldb_dn_invalid_extended);
+ torture_suite_add_simple_test(suite, "DN", torture_ldb_dn);
+
+ suite->description = talloc_strdup(suite, "LDB (samba-specific behaviour) tests");
+
+ torture_register_suite(suite);
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk
index 46d5e38e67..60cbf25eda 100644
--- a/source4/torture/local/config.mk
+++ b/source4/torture/local/config.mk
@@ -43,7 +43,7 @@ TORTURE_LOCAL_OBJ_FILES = \
$(torturesrcdir)/../../lib/util/charset/tests/charset.o \
$(torturesrcdir)/../libcli/security/tests/sddl.o \
$(torturesrcdir)/../lib/tdr/testsuite.o \
- $(torturesrcdir)/../lib/events/testsuite.o \
+ $(torturesrcdir)/../../lib/tevent/testsuite.o \
$(torturesrcdir)/../param/tests/share.o \
$(torturesrcdir)/../param/tests/loadparm.o \
$(torturesrcdir)/../auth/credentials/tests/simple.o \
diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c
index b688f1fbfe..ca557de8fe 100644
--- a/source4/torture/nbt/winsreplication.c
+++ b/source4/torture/nbt/winsreplication.c
@@ -107,10 +107,10 @@ static bool test_assoc_ctx1(struct torture_context *tctx)
wrepl_socket2 = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
torture_comment(tctx, "Setup 2 wrepl connections\n");
- status = wrepl_connect(wrepl_socket1, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);
+ status = wrepl_connect(wrepl_socket1, wrepl_best_ip(tctx->lp_ctx, address), address);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
- status = wrepl_connect(wrepl_socket2, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);
+ status = wrepl_connect(wrepl_socket2, wrepl_best_ip(tctx->lp_ctx, address), address);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
torture_comment(tctx, "Send a start association request (conn1)\n");
@@ -189,7 +189,7 @@ static bool test_assoc_ctx2(struct torture_context *tctx)
wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
torture_comment(tctx, "Setup wrepl connections\n");
- status = wrepl_connect(wrepl_socket, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);
+ status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
torture_comment(tctx, "Send 1st start association request\n");
@@ -258,7 +258,7 @@ static bool test_wins_replication(struct torture_context *tctx)
wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
torture_comment(tctx, "Setup wrepl connections\n");
- status = wrepl_connect(wrepl_socket, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, address), address);
+ status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
torture_comment(tctx, "Send a start association request\n");
@@ -557,7 +557,7 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(
if (!ctx->pull) return NULL;
torture_comment(tctx, "Setup wrepl conflict pull connection\n");
- status = wrepl_connect(ctx->pull, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
+ status = wrepl_connect(ctx->pull, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
if (!NT_STATUS_IS_OK(status)) return NULL;
status = wrepl_associate(ctx->pull, &associate);
@@ -724,7 +724,7 @@ static bool test_wrepl_update_one(struct torture_context *tctx,
wrepl_socket = wrepl_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
- status = wrepl_connect(wrepl_socket, lp_resolve_context(tctx->lp_ctx), wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
+ status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
CHECK_STATUS(tctx, status, NT_STATUS_OK);
status = wrepl_associate(wrepl_socket, &associate);
diff --git a/source4/torture/raw/chkpath.c b/source4/torture/raw/chkpath.c
index b66839b997..a39993489b 100644
--- a/source4/torture/raw/chkpath.c
+++ b/source4/torture/raw/chkpath.c
@@ -306,7 +306,7 @@ static bool test_chkpath_names(struct smbcli_state *cli, struct torture_context
case '?':/*0x3F*/
case '|':/*0x7C*/
if (i == '/' &&
- torture_setting_bool(tctx, "samba3", true)) {
+ torture_setting_bool(tctx, "samba3", false)) {
/* samba 3 handles '/' as '\\' */
break;
}
diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c
index 4ffb24eb03..f0afee26cc 100644
--- a/source4/torture/raw/oplock.c
+++ b/source4/torture/raw/oplock.c
@@ -2632,10 +2632,6 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
uint16_t fnum=0, fnum2=0,fnum3=0;
struct smbcli_state *cli3 = NULL;
- if (torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "BATCH23 disabled against samba3\n");
- }
-
if (!torture_setup_dir(cli1, BASEDIR)) {
return false;
}
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 306c271511..c7518d15a0 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -1688,13 +1688,16 @@ static bool test_LogonControl2Ex(struct torture_context *tctx,
{
NTSTATUS status;
struct netr_LogonControl2Ex r;
+ union netr_CONTROL_DATA_INFORMATION data;
union netr_CONTROL_QUERY_INFORMATION query;
int i;
+ data.domain = lp_workgroup(tctx->lp_ctx);
+
r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
- r.in.data.domain = lp_workgroup(tctx->lp_ctx);
+ r.in.data = &data;
r.out.query = &query;
for (i=1;i<4;i++) {
@@ -1707,8 +1710,10 @@ static bool test_LogonControl2Ex(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "LogonControl");
}
+ data.domain = lp_workgroup(tctx->lp_ctx);
+
r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
- r.in.data.domain = lp_workgroup(tctx->lp_ctx);
+ r.in.data = &data;
for (i=1;i<4;i++) {
r.in.level = i;
@@ -1720,8 +1725,10 @@ static bool test_LogonControl2Ex(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "LogonControl");
}
+ data.domain = lp_workgroup(tctx->lp_ctx);
+
r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
- r.in.data.domain = lp_workgroup(tctx->lp_ctx);
+ r.in.data = &data;
for (i=1;i<4;i++) {
r.in.level = i;
@@ -1733,8 +1740,10 @@ static bool test_LogonControl2Ex(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "LogonControl");
}
+ data.debug_level = ~0;
+
r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
- r.in.data.debug_level = ~0;
+ r.in.data = &data;
for (i=1;i<4;i++) {
r.in.level = i;
@@ -2128,7 +2137,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx,
q1.workstation_site = "Default-First-Site-Name";
q1.blob2.length = 0;
q1.blob2.size = 0;
- q1.blob2.data = NULL;
+ q1.blob2.array = NULL;
q1.product.string = "product string";
torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
@@ -2194,7 +2203,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx,
q1.workstation_site = "Default-First-Site-Name";
q1.blob2.length = 0;
q1.blob2.size = 0;
- q1.blob2.data = NULL;
+ q1.blob2.array = NULL;
q1.product.string = "product string";
torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index dc98c2cc9a..3f9a6607cf 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -50,6 +50,7 @@ _PUBLIC_ int torture_init(void)
{
extern NTSTATUS torture_base_init(void);
extern NTSTATUS torture_ldap_init(void);
+ extern NTSTATUS torture_ldb_init(void);
extern NTSTATUS torture_local_init(void);
extern NTSTATUS torture_nbt_init(void);
extern NTSTATUS torture_nbench_init(void);
diff --git a/source4/wrepl_server/wrepl_out_helpers.c b/source4/wrepl_server/wrepl_out_helpers.c
index 12605196ab..e1e3f38b12 100644
--- a/source4/wrepl_server/wrepl_out_helpers.c
+++ b/source4/wrepl_server/wrepl_out_helpers.c
@@ -193,7 +193,6 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn
state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET;
state->wreplconn= wreplconn;
state->c_req = wrepl_connect_send(wreplconn->sock,
- lp_resolve_context(service->task->lp_ctx),
partner->our_address?partner->our_address:wrepl_best_ip(service->task->lp_ctx, partner->address),
partner->address);
if (!state->c_req) goto failed;