diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-12-19 21:47:45 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-12-19 21:47:45 +0100 |
commit | 5076c64d43c68a028ac944c336715b4cb277365f (patch) | |
tree | e88fc16979b75b5b30377e84b76ebb1b87e01591 /source4 | |
parent | 6998ef4fe021ebf40f63c2191d3259888a8ad7f4 (diff) | |
parent | 13eefa7c435cb5ac656f662c78260a82caf43180 (diff) | |
download | samba-5076c64d43c68a028ac944c336715b4cb277365f.tar.gz samba-5076c64d43c68a028ac944c336715b4cb277365f.tar.bz2 samba-5076c64d43c68a028ac944c336715b4cb277365f.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source4')
151 files changed, 4999 insertions, 14703 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/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index fa1af2ad61..d1a8e71842 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -27,7 +27,7 @@ import ldb from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE from samba import Ldb, substitute_var from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm -import samba.dcerpc.dom_sid +import samba.dcerpc.security import samba.security import samba.ndr @@ -116,7 +116,7 @@ class MapBaseTestCase(TestCaseInTempDir): super(MapBaseTestCase, self).tearDown() def assertSidEquals(self, text, ndr_sid): - sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.dom_sid.dom_sid, + sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid, str(ndr_sid[0])) sid_obj2 = samba.security.Sid(text) # For now, this is the only way we can compare these since the 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 ff365b3e38..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(¤t_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..001bc45ee1 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 LDB_SUCCESS; +} + +/* + return the extended dn syntax for a given name +*/ +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name) +{ + 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..02e21a2b25 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 LDB_SUCCESS; + } + } + } + + 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 LDB_SUCCESS; +} + +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 de0e9a49d6..c4c23022f8 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -1,4 +1,4 @@ -/* +/* ldb database library Copyright (C) Andrew Tridgell 2004 @@ -6,7 +6,7 @@ ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -39,7 +39,7 @@ 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. + 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 @@ -77,7 +77,7 @@ static int ltdb_idxptr_add(struct ldb_module *module, const struct ldb_message * ltdb->idxptr->num_dns = 0; return LDB_ERR_OPERATIONS_ERROR; } - ltdb->idxptr->dn_list[ltdb->idxptr->num_dns] = + 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; @@ -98,12 +98,12 @@ static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_elemen val = el->values[0]; if (val.length != sizeof(void *)) { - return LDB_ERR_OPERATIONS_ERROR; + 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; + return LDB_ERR_OPERATIONS_ERROR; } while (ptr) { @@ -112,7 +112,7 @@ static int ltdb_free_idxptr(struct ldb_module *module, struct ldb_message_elemen talloc_free(tmp); } - return 0; + return LDB_SUCCESS; } @@ -130,12 +130,12 @@ static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_messag val = el->values[0]; if (val.length != sizeof(void *)) { - return LDB_ERR_OPERATIONS_ERROR; + 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; + return LDB_ERR_OPERATIONS_ERROR; } /* count the length of the list */ @@ -146,7 +146,7 @@ static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_messag /* allocate the new values array */ val2 = talloc_realloc(NULL, el->values, struct ldb_val, i); if (val2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; + return LDB_ERR_OPERATIONS_ERROR; } el->values = val2; el->num_values = i; @@ -162,11 +162,11 @@ static int ltdb_convert_from_idxptr(struct ldb_module *module, struct ldb_messag } 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; } @@ -185,12 +185,12 @@ static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_ for (i=0;i<el->num_values;i++) { tmp = talloc(ltdb->idxptr, struct ldb_index_pointer); if (tmp == NULL) { - return LDB_ERR_OPERATIONS_ERROR; + 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; + return LDB_ERR_OPERATIONS_ERROR; } DLIST_ADD(ptr, tmp); } @@ -198,7 +198,7 @@ static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_ /* allocate the new values array */ val2 = talloc_realloc(NULL, el->values, struct ldb_val, 1); if (val2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; + return LDB_ERR_OPERATIONS_ERROR; } el->values = val2; el->num_values = 1; @@ -209,7 +209,7 @@ static int ltdb_convert_to_idxptr(struct ldb_module *module, struct ldb_message_ /* update the name */ el->name = LTDB_IDXPTR; - return LDB_SUCCESS; + return LDB_SUCCESS; } @@ -219,14 +219,14 @@ 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; + return LDB_SUCCESS; } /* 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_wrap(struct ldb_module *module, +static int ltdb_search_dn1_index(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg) { int ret, i; @@ -237,7 +237,7 @@ static int ltdb_search_dn1_wrap(struct ldb_module *module, /* 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 ret; + return LDB_ERR_OPERATIONS_ERROR; } for (i=0;i<msg->num_elements;i++) { @@ -263,9 +263,9 @@ 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_wrap(module, dn, msg) == LDB_SUCCESS) { + if (ltdb_search_dn1_index(module, dn, msg) == LDB_SUCCESS) { ret = ltdb_store(module, msg, TDB_REPLACE); } talloc_free(msg); @@ -292,7 +292,7 @@ int ltdb_index_transaction_commit(struct ldb_module *module) talloc_free(ltdb->idxptr); ltdb->idxptr = NULL; - return 0; + return LDB_SUCCESS; } /* cleanup the idxptr mode when transaction cancels */ @@ -302,13 +302,13 @@ int ltdb_index_transaction_cancel(struct ldb_module *module) talloc_get_type(module->private_data, struct ltdb_private); talloc_free(ltdb->idxptr); ltdb->idxptr = NULL; - return 0; + return LDB_SUCCESS; } - -/* a wrapper around ltdb_store() for the index code which - stores in IDXPTR format when idxptr mode is enabled + +/* 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 */ @@ -363,8 +363,8 @@ int ltdb_store_idxptr(struct ldb_module *module, const struct ldb_message *msg, return -1 if not found, or the index of the first occurance of needle if found */ -static int ldb_list_find(const void *needle, - const void *base, size_t nmemb, size_t size, +static int ldb_list_find(const void *needle, + const void *base, size_t nmemb, size_t size, comparison_fn_t comp_fn) { const char *base_p = (const char *)base; @@ -505,7 +505,7 @@ static int list_cmp(const char **s1, const char **s2) /* return a list of dn's that might match a simple indexed search or */ -static int ltdb_index_dn_simple(struct ldb_module *module, +static int ltdb_index_dn_simple(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -535,7 +535,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1_wrap(module, dn, msg); + ret = ltdb_search_dn1_index(module, dn, msg); talloc_free(dn); if (ret != LDB_SUCCESS) { return ret; @@ -557,7 +557,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module, } for (j=0;j<el->num_values;j++) { - list->dn[list->count] = + list->dn[list->count] = talloc_strdup(list->dn, (char *)el->values[j].data); if (!list->dn[list->count]) { talloc_free(msg); @@ -582,7 +582,7 @@ static int list_union(struct ldb_context *, struct dn_list *, const struct dn_li /* return a list of dn's that might match a leaf indexed search */ -static int ltdb_index_dn_leaf(struct ldb_module *module, +static int ltdb_index_dn_leaf(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -634,13 +634,13 @@ static int list_intersect(struct ldb_context *ldb, list3->count = 0; for (i=0;i<list->count;i++) { - if (ldb_list_find(list->dn[i], list2->dn, list2->count, + if (ldb_list_find(list->dn[i], list2->dn, list2->count, sizeof(char *), (comparison_fn_t)strcmp) != -1) { list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); list3->count++; } else { talloc_free(list->dn[i]); - } + } } talloc_free(list->dn); @@ -657,7 +657,7 @@ static int list_intersect(struct ldb_context *ldb, list = list | list2 relies on the lists being sorted */ -static int list_union(struct ldb_context *ldb, +static int list_union(struct ldb_context *ldb, struct dn_list *list, const struct dn_list *list2) { unsigned int i; @@ -676,14 +676,14 @@ static int list_union(struct ldb_context *ldb, list->dn = d; for (i=0;i<list2->count;i++) { - if (ldb_list_find(list2->dn[i], list->dn, count, + if (ldb_list_find(list2->dn[i], list->dn, count, sizeof(char *), (comparison_fn_t)strcmp) == -1) { list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); if (!list->dn[list->count]) { return LDB_ERR_OPERATIONS_ERROR; } list->count++; - } + } } if (list->count != count) { @@ -693,7 +693,7 @@ static int list_union(struct ldb_context *ldb, return LDB_ERR_NO_SUCH_OBJECT; } -static int ltdb_index_dn(struct ldb_module *module, +static int ltdb_index_dn(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list); @@ -702,7 +702,7 @@ static int ltdb_index_dn(struct ldb_module *module, /* OR two index results */ -static int ltdb_index_dn_or(struct ldb_module *module, +static int ltdb_index_dn_or(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -710,7 +710,7 @@ static int ltdb_index_dn_or(struct ldb_module *module, struct ldb_context *ldb = module->ldb; unsigned int i; int ret; - + ret = LDB_ERR_OPERATIONS_ERROR; list->dn = NULL; list->count = 0; @@ -767,7 +767,7 @@ static int ltdb_index_dn_or(struct ldb_module *module, /* NOT an index results */ -static int ltdb_index_dn_not(struct ldb_module *module, +static int ltdb_index_dn_not(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -775,8 +775,8 @@ static int ltdb_index_dn_not(struct ldb_module *module, /* the only way to do an indexed not would be if we could negate the not via another not or if we knew the total number of database elements so we could know that the - existing expression covered the whole database. - + existing expression covered the whole database. + instead, we just give up, and rely on a full index scan (unless an outer & manages to reduce the list) */ @@ -786,7 +786,7 @@ static int ltdb_index_dn_not(struct ldb_module *module, /* AND two index results */ -static int ltdb_index_dn_and(struct ldb_module *module, +static int ltdb_index_dn_and(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -794,7 +794,7 @@ static int ltdb_index_dn_and(struct ldb_module *module, struct ldb_context *ldb = module->ldb; unsigned int i; int ret; - + ret = LDB_ERR_OPERATIONS_ERROR; list->dn = NULL; list->count = 0; @@ -848,7 +848,7 @@ static int ltdb_index_dn_and(struct ldb_module *module, /* AND index results and ONE level special index */ -static int ltdb_index_dn_one(struct ldb_module *module, +static int ltdb_index_dn_one(struct ldb_module *module, struct ldb_dn *parent_dn, struct dn_list *list) { @@ -859,13 +859,13 @@ static int ltdb_index_dn_one(struct ldb_module *module, struct ldb_val val; unsigned int i, j; int ret; - + list2 = talloc_zero(module, struct dn_list); if (list2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } - /* the attribute is indexed. Pull the list of DNs that match the + /* the attribute is indexed. Pull the list of DNs that match the search criterion */ val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(parent_dn)); val.length = strlen((char *)val.data); @@ -881,7 +881,7 @@ static int ltdb_index_dn_one(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1_wrap(module, key, msg); + ret = ltdb_search_dn1_index(module, key, msg); talloc_free(key); if (ret != LDB_SUCCESS) { return ret; @@ -946,7 +946,7 @@ static int ltdb_index_dn_one(struct ldb_module *module, return a list of dn's that might match a indexed search or an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches */ -static int ltdb_index_dn(struct ldb_module *module, +static int ltdb_index_dn(struct ldb_module *module, const struct ldb_parse_tree *tree, const struct ldb_message *index_list, struct dn_list *list) @@ -988,7 +988,7 @@ static int ltdb_index_dn(struct ldb_module *module, filter a candidate dn_list from an indexed search into a set of results extracting just the given attributes */ -static int ltdb_index_filter(const struct dn_list *dn_list, +static int ltdb_index_filter(const struct dn_list *dn_list, struct ltdb_context *ac) { struct ldb_message *msg; @@ -1009,7 +1009,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1_wrap(ac->module, dn, msg); + ret = ltdb_search_dn1(ac->module, dn, msg); talloc_free(dn); if (ret == LDB_ERR_NO_SUCH_OBJECT) { /* the record has disappeared? yes, this can happen */ @@ -1037,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; @@ -1050,7 +1050,7 @@ static int ltdb_index_filter(const struct dn_list *dn_list, /* search the database with a LDAP-like expression using indexes returns -1 if an indexed search is not possible, in which - case the caller should call ltdb_search_full() + case the caller should call ltdb_search_full() */ int ltdb_search_indexed(struct ltdb_context *ac) { @@ -1126,14 +1126,14 @@ int ltdb_search_indexed(struct ltdb_context *ac) /* add a index element where this is the first indexed DN for this value */ -static int ltdb_index_add1_new(struct ldb_context *ldb, +static int ltdb_index_add1_new(struct ldb_context *ldb, struct ldb_message *msg, const char *dn) { struct ldb_message_element *el; /* add another entry */ - el = talloc_realloc(msg, msg->elements, + el = talloc_realloc(msg, msg->elements, struct ldb_message_element, msg->num_elements+1); if (!el) { return LDB_ERR_OPERATIONS_ERROR; @@ -1162,7 +1162,7 @@ static int ltdb_index_add1_new(struct ldb_context *ldb, add a index element where this is not the first indexed DN for this value */ -static int ltdb_index_add1_add(struct ldb_context *ldb, +static int ltdb_index_add1_add(struct ldb_context *ldb, struct ldb_message *msg, int idx, const char *dn) @@ -1178,7 +1178,7 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, } v2 = talloc_realloc(msg->elements, msg->elements[idx].values, - struct ldb_val, + struct ldb_val, msg->elements[idx].num_values+1); if (!v2) { return LDB_ERR_OPERATIONS_ERROR; @@ -1195,7 +1195,7 @@ static int ltdb_index_add1_add(struct ldb_context *ldb, /* add an index entry for one message element */ -static int ltdb_index_add1(struct ldb_module *module, const char *dn, +static int ltdb_index_add1(struct ldb_module *module, const char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; @@ -1217,7 +1217,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn, } talloc_steal(msg, dn_key); - ret = ltdb_search_dn1_wrap(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; @@ -1267,7 +1267,7 @@ static int ltdb_index_add0(struct ldb_module *module, const char *dn, } for (i = 0; i < num_el; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, + ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, NULL, LTDB_IDXATTR); if (ret == -1) { continue; @@ -1305,7 +1305,7 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) /* delete an index entry for one message element */ -int ltdb_index_del_value(struct ldb_module *module, const char *dn, +int ltdb_index_del_value(struct ldb_module *module, const char *dn, struct ldb_message_element *el, int v_idx) { struct ldb_context *ldb = module->ldb; @@ -1329,7 +1329,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, return LDB_ERR_OPERATIONS_ERROR; } - ret = ltdb_search_dn1_wrap(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; @@ -1359,9 +1359,9 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, } if (j != msg->elements[i].num_values - 1) { - memmove(&msg->elements[i].values[j], - &msg->elements[i].values[j+1], - (msg->elements[i].num_values-(j+1)) * + memmove(&msg->elements[i].values[j], + &msg->elements[i].values[j+1], + (msg->elements[i].num_values-(j+1)) * sizeof(msg->elements[i].values[0])); } msg->elements[i].num_values--; @@ -1388,7 +1388,7 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) const char *dn; unsigned int i, j; - /* find the list of indexed fields */ + /* find the list of indexed fields */ if (ltdb->cache->indexlist->num_elements == 0) { /* no indexed fields */ return LDB_SUCCESS; @@ -1420,7 +1420,7 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) return LDB_SUCCESS; } -/* +/* handle special index for one level searches */ int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add) @@ -1511,7 +1511,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * return -1; } - /* check if the DN key has changed, perhaps due to the + /* check if the DN key has changed, perhaps due to the case insensitivity of an element changing */ key2 = ltdb_key(module, msg->dn); if (key2.dptr == NULL) { 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/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 37a874a708..821bd04b5c 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/registry/config.mk b/source4/lib/registry/config.mk index 9af61f9632..6528127b0b 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -103,12 +103,8 @@ torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o $(eval $(call proto_header_template,$(libregistrysrcdir)/tests/proto.h,$(torture_registry_OBJ_FILES:.o=.c))) -[PYTHON::swig_registry] -LIBRARY_REALNAME = samba/_registry.$(SHLIBEXT) -PUBLIC_DEPENDENCIES = registry - -swig_registry_OBJ_FILES = $(libregistrysrcdir)/registry_wrap.o - -$(eval $(call python_py_module_template,samba/registry.py,$(libregistrysrcdir)/registry.py)) +[PYTHON::py_registry] +LIBRARY_REALNAME = samba/registry.$(SHLIBEXT) +PUBLIC_DEPENDENCIES = registry PYTALLOC swig_credentials param -$(swig_registry_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) +py_registry_OBJ_FILES = $(libregistrysrcdir)/pyregistry.o diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c new file mode 100644 index 0000000000..e49fdad8a2 --- /dev/null +++ b/source4/lib/registry/pyregistry.c @@ -0,0 +1,432 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include <Python.h> +#include "libcli/util/pyerrors.h" +#include "lib/registry/registry.h" +#include "scripting/python/modules.h" /* for py_iconv_convenience() */ +#include <pytalloc.h> +#include <tevent.h> + +extern struct loadparm_context *lp_from_py_object(PyObject *py_obj); +extern struct cli_credentials *cli_credentials_from_py_object(PyObject *py_obj); + +PyAPI_DATA(PyTypeObject) PyRegistryKey; +PyAPI_DATA(PyTypeObject) PyRegistry; +PyAPI_DATA(PyTypeObject) PyHiveKey; + +static PyObject *py_get_predefined_key_by_name(PyObject *self, PyObject *args) +{ + char *name; + WERROR result; + struct registry_context *ctx = py_talloc_get_ptr(self); + struct registry_key *key; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + result = reg_get_predefined_key_by_name(ctx, name, &key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_import(&PyRegistryKey, key); +} + +static PyObject *py_key_del_abs(PyObject *self, PyObject *args) +{ + char *path; + WERROR result; + struct registry_context *ctx = py_talloc_get_ptr(self); + + if (!PyArg_ParseTuple(args, "s", &path)) + return NULL; + + result = reg_key_del_abs(ctx, path); + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *py_get_predefined_key(PyObject *self, PyObject *args) +{ + uint32_t hkey; + struct registry_context *ctx = py_talloc_get_ptr(self); + WERROR result; + struct registry_key *key; + + if (!PyArg_ParseTuple(args, "I", &hkey)) + return NULL; + + result = reg_get_predefined_key(ctx, hkey, &key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_import(&PyRegistryKey, key); +} + +static PyObject *py_diff_apply(PyObject *self, PyObject *args) +{ + char *filename; + WERROR result; + struct registry_context *ctx = py_talloc_get_ptr(self); + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + result = reg_diff_apply(ctx, py_iconv_convenience(NULL), filename); + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *py_mount_hive(PyObject *self, PyObject *args) +{ + struct registry_context *ctx = py_talloc_get_ptr(self); + uint32_t hkey; + PyObject *py_hivekey, *py_elements = Py_None; + const char **elements; + WERROR result; + + if (!PyArg_ParseTuple(args, "OI|O", &py_hivekey, &hkey, &py_elements)) + return NULL; + + if (!PyList_Check(py_elements) && py_elements != Py_None) { + PyErr_SetString(PyExc_TypeError, "Expected list of elements"); + return NULL; + } + + if (py_elements == Py_None) { + elements = NULL; + } else { + int i; + elements = talloc_array(NULL, const char *, PyList_Size(py_elements)); + for (i = 0; i < PyList_Size(py_elements); i++) + elements[i] = PyString_AsString(PyList_GetItem(py_elements, i)); + } + + SMB_ASSERT(ctx != NULL); + + result = reg_mount_hive(ctx, py_talloc_get_ptr(py_hivekey), hkey, elements); + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *registry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + WERROR result; + struct registry_context *ctx; + result = reg_open_local(NULL, &ctx); + PyErr_WERROR_IS_ERR_RAISE(result); + return py_talloc_import(&PyRegistry, ctx); +} + +static PyMethodDef registry_methods[] = { + { "get_predefined_key_by_name", py_get_predefined_key_by_name, METH_VARARGS, + "S.get_predefined_key_by_name(name) -> key\n" + "Find a predefined key by name" }, + { "key_del_abs", py_key_del_abs, METH_VARARGS, "S.key_del_abs(name) -> None\n" + "Delete a key by absolute path." }, + { "get_predefined_key", py_get_predefined_key, METH_VARARGS, "S.get_predefined_key(hkey_id) -> key\n" + "Find a predefined key by id" }, + { "diff_apply", py_diff_apply, METH_VARARGS, "S.diff_apply(filename) -> None\n" + "Apply the diff from the specified file" }, + { "mount_hive", py_mount_hive, METH_VARARGS, "S.mount_hive(key, key_id, elements=None) -> None\n" + "Mount the specified key at the specified path." }, + { NULL } +}; + +PyTypeObject PyRegistry = { + .tp_name = "Registry", + .tp_methods = registry_methods, + .tp_new = registry_new, + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, +}; + +static PyObject *py_hive_key_del(PyObject *self, PyObject *args) +{ + char *name; + struct hive_key *key = py_talloc_get_ptr(self); + WERROR result; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + result = hive_key_del(key, name); + + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *py_hive_key_flush(PyObject *self) +{ + WERROR result; + struct hive_key *key = py_talloc_get_ptr(self); + + result = hive_key_flush(key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *py_hive_key_del_value(PyObject *self, PyObject *args) +{ + char *name; + WERROR result; + struct hive_key *key = py_talloc_get_ptr(self); + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + result = hive_key_del_value(key, name); + + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyObject *py_hive_key_set_value(PyObject *self, PyObject *args) +{ + char *name; + uint32_t type; + DATA_BLOB value; + WERROR result; + struct hive_key *key = py_talloc_get_ptr(self); + + if (!PyArg_ParseTuple(args, "siz#", &name, &type, &value.data, &value.length)) + return NULL; + + if (value.data != NULL) + result = hive_key_set_value(key, name, type, value); + else + result = hive_key_del_value(key, name); + + PyErr_WERROR_IS_ERR_RAISE(result); + + return Py_None; +} + +static PyMethodDef hive_key_methods[] = { + { "del", py_hive_key_del, METH_VARARGS, "S.del(name) -> None\n" + "Delete a subkey" }, + { "flush", (PyCFunction)py_hive_key_flush, METH_NOARGS, "S.flush() -> None\n" + "Flush this key to disk" }, + { "del_value", py_hive_key_del_value, METH_VARARGS, "S.del_value(name) -> None\n" + "Delete a value" }, + { "set_value", py_hive_key_set_value, METH_VARARGS, "S.set_value(name, type, data) -> None\n" + "Set a value" }, + { NULL } +}; + +static PyObject *hive_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + /* reg_open_hive */ + return Py_None; +} + +PyTypeObject PyHiveKey = { + .tp_name = "HiveKey", + .tp_methods = hive_key_methods, + .tp_new = hive_open, + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, +}; + +PyTypeObject PyRegistryKey = { + .tp_name = "RegistryKey", + .tp_basicsize = sizeof(py_talloc_Object), + .tp_dealloc = py_talloc_dealloc, +}; + +static PyObject *py_open_samba(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *kwnames[] = { "lp_ctx", "session_info", NULL }; + struct registry_context *reg_ctx; + WERROR result; + struct loadparm_context *lp_ctx; + PyObject *py_lp_ctx, *py_session_info, *py_credentials; + struct auth_session_info *session_info; + struct cli_credentials *credentials; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO", discard_const_p(char *, kwnames), + &py_lp_ctx, &py_session_info, &py_credentials)) + return NULL; + + lp_ctx = lp_from_py_object(py_lp_ctx); + if (lp_ctx == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); + return NULL; + } + + credentials = cli_credentials_from_py_object(py_credentials); + if (credentials == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials"); + return NULL; + } + + session_info = NULL; /* FIXME */ + + result = reg_open_samba(NULL, ®_ctx, NULL, + lp_ctx, session_info, credentials); + if (!W_ERROR_IS_OK(result)) { + PyErr_SetWERROR(result); + return NULL; + } + + return py_talloc_import(&PyRegistry, reg_ctx); +} + +static PyObject *py_open_directory(PyObject *self, PyObject *args) +{ + char *location; + WERROR result; + struct hive_key *key; + + if (!PyArg_ParseTuple(args, "s", &location)) + return NULL; + + result = reg_open_directory(NULL, location, &key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_import(&PyHiveKey, key); +} + +static PyObject *py_create_directory(PyObject *self, PyObject *args) +{ + char *location; + WERROR result; + struct hive_key *key; + + if (!PyArg_ParseTuple(args, "s", &location)) + return NULL; + + result = reg_create_directory(NULL, location, &key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_import(&PyHiveKey, key); +} + +static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *kwnames[] = { "location", "session_info", "credentials", "lp_ctx", NULL }; + PyObject *py_session_info = Py_None, *py_credentials = Py_None, *py_lp_ctx = Py_None; + WERROR result; + char *location; + struct loadparm_context *lp_ctx; + struct cli_credentials *credentials; + struct hive_key *key; + struct auth_session_info *session_info; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO", + discard_const_p(char *, kwnames), + &location, + &py_session_info, &py_credentials, + &py_lp_ctx)) + return NULL; + + lp_ctx = lp_from_py_object(py_lp_ctx); + if (lp_ctx == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); + return NULL; + } + + credentials = cli_credentials_from_py_object(py_credentials); + if (credentials == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials"); + return NULL; + } + + session_info = NULL; /* FIXME */ + + result = reg_open_ldb_file(NULL, location, session_info, credentials, + event_context_init(NULL), lp_ctx, &key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_import(&PyHiveKey, key); +} + +static PyObject *py_str_regtype(PyObject *self, PyObject *args) +{ + int regtype; + + if (!PyArg_ParseTuple(args, "i", ®type)) + return NULL; + + return PyString_FromString(str_regtype(regtype)); +} + +static PyObject *py_get_predef_name(PyObject *self, PyObject *args) +{ + uint32_t hkey; + const char *str; + + if (!PyArg_ParseTuple(args, "I", &hkey)) + return NULL; + + str = reg_get_predef_name(hkey); + if (str == NULL) + return Py_None; + return PyString_FromString(str); +} + +static PyMethodDef py_registry_methods[] = { + { "open_samba", (PyCFunction)py_open_samba, METH_VARARGS|METH_KEYWORDS, "open_samba() -> reg" }, + { "open_directory", py_open_directory, METH_VARARGS, "open_dir(location) -> key" }, + { "create_directory", py_create_directory, METH_VARARGS, "create_dir(location) -> key" }, + { "open_ldb", (PyCFunction)py_open_ldb_file, METH_VARARGS|METH_KEYWORDS, "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key" }, + { "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> str" }, + { "get_predef_name", py_get_predef_name, METH_VARARGS, "get_predef_name(hkey) -> str" }, + { NULL } +}; + +void initregistry(void) +{ + PyObject *m; + + if (PyType_Ready(&PyHiveKey) < 0) + return; + + if (PyType_Ready(&PyRegistry) < 0) + return; + + if (PyType_Ready(&PyRegistryKey) < 0) + return; + + m = Py_InitModule3("registry", py_registry_methods, "Registry"); + if (m == NULL) + return; + + PyModule_AddObject(m, "HKEY_CLASSES_ROOT", PyInt_FromLong(HKEY_CLASSES_ROOT)); + PyModule_AddObject(m, "HKEY_CURRENT_USER", PyInt_FromLong(HKEY_CURRENT_USER)); + PyModule_AddObject(m, "HKEY_LOCAL_MACHINE", PyInt_FromLong(HKEY_LOCAL_MACHINE)); + PyModule_AddObject(m, "HKEY_USERS", PyInt_FromLong(HKEY_USERS)); + PyModule_AddObject(m, "HKEY_PERFORMANCE_DATA", PyInt_FromLong(HKEY_PERFORMANCE_DATA)); + PyModule_AddObject(m, "HKEY_CURRENT_CONFIG", PyInt_FromLong(HKEY_CURRENT_CONFIG)); + PyModule_AddObject(m, "HKEY_DYN_DATA", PyInt_FromLong(HKEY_DYN_DATA)); + PyModule_AddObject(m, "HKEY_PERFORMANCE_TEXT", PyInt_FromLong(HKEY_PERFORMANCE_TEXT)); + PyModule_AddObject(m, "HKEY_PERFORMANCE_NLSTEXT", PyInt_FromLong(HKEY_PERFORMANCE_NLSTEXT)); + + Py_INCREF(&PyRegistry); + PyModule_AddObject(m, "Registry", (PyObject *)&PyRegistry); + + Py_INCREF(&PyHiveKey); + PyModule_AddObject(m, "HiveKey", (PyObject *)&PyHiveKey); + + Py_INCREF(&PyRegistryKey); + PyModule_AddObject(m, "RegistryKey", (PyObject *)&PyRegistryKey); +} diff --git a/source4/lib/registry/registry.i b/source4/lib/registry/registry.i deleted file mode 100644 index cbd5fe8793..0000000000 --- a/source4/lib/registry/registry.i +++ /dev/null @@ -1,223 +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/>. -*/ - -%define DOCSTRING -"Access to various registry formats and the Samba registry." -%enddef - -%module(docstring=DOCSTRING) registry - -%{ -/* Include headers */ -#include <stdint.h> -#include <stdbool.h> - -#include "includes.h" -#include "registry.h" -#include "param/param.h" -#include "events/events.h" -#include "scripting/python/modules.h" - -typedef struct registry_context reg; -typedef struct hive_key hive_key; -%} -%include "../../libcli/util/errors.i" - -/* FIXME: This should be in another file */ -%typemap(default,noblock=1) struct auth_session_info * { - $1 = NULL; -} - -%import "stdint.i" -%import "../../../lib/talloc/talloc.i" -%import "../../auth/credentials/credentials.i" -%import "../../param/param.i" -%import "../events/events.i" - -/* Utility functions */ - -const char *reg_get_predef_name(uint32_t hkey); -const char *str_regtype(int type); - -/* Registry contexts */ -%typemap(in,noblock=1,numinputs=0) struct registry_context ** (struct registry_context *tmp) { - $1 = &tmp; -} - -%typemap(argout,noblock=1) struct registry_context ** { - $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_registry_context, 0); -} - -%typemap(in,noblock=1,numinputs=0) struct smb_iconv_convenience *ic { - $1 = py_iconv_convenience(NULL); -} - -%typemap(freearg,noblock=1) struct smb_iconv_convenience *ic { - talloc_free($1); -} - -%rename(Registry) reg_open_local; -WERROR reg_open_local(TALLOC_CTX *parent_ctx, struct registry_context **ctx); - -%typemap(in,noblock=1) const char ** { - /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - $1 = (char **) malloc((size+1)*sizeof(const char *)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyString_Check(o)) - $1[i] = PyString_AsString(PyList_GetItem($input,i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free($1); - return NULL; - } - } - $1[i] = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } -} - -%typemap(freearg,noblock=1) const char ** { - free((char **) $1); -} - -%talloctype(reg); - -typedef struct registry_context { - %extend { - - %feature("docstring") get_predefined_key_by_name "S.get_predefined_key_by_name(name) -> key\n" - "Find a predefined key by name"; - WERROR get_predefined_key_by_name(const char *name, - struct registry_key **key); - - %feature("docstring") key_del_abs "S.key_del_abs(name) -> None\n" - "Delete a key by absolute path."; - WERROR key_del_abs(const char *path); - %feature("docstring") get_predefined_key "S.get_predefined_key(hkey_id) -> key\n" - "Find a predefined key by id"; - WERROR get_predefined_key(uint32_t hkey_id, struct registry_key **key); - %feature("docstring") diff_apply "S.diff_apply(filename) -> None\n" - "Apply the diff from the specified file"; - - WERROR diff_apply(struct smb_iconv_convenience *ic, const char *filename); - WERROR generate_diff(struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, - void *callback_data); - - WERROR mount_hive(struct hive_key *key, uint32_t hkey_id, - const char **elements=NULL); - - struct registry_key *import_hive_key(struct hive_key *hive, uint32_t predef_key, const char **elements); - %feature("docstring") mount_hive "S.mount_hive(key, predef_name) -> None\n" - "Mount the specified key at the specified path."; - WERROR mount_hive(struct hive_key *key, const char *predef_name) - { - int i; - for (i = 0; reg_predefined_keys[i].name; i++) { - if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) - return reg_mount_hive($self, key, - reg_predefined_keys[i].handle, NULL); - } - return WERR_INVALID_NAME; - } - - } -} reg; - -/* Hives */ -%typemap(in,noblock=1,numinputs=0) struct hive_key ** (struct hive_key *tmp) { - $1 = &tmp; -} - -%typemap(argout,noblock=1) struct hive_key ** { - Py_XDECREF($result); - $result = SWIG_NewPointerObj(*$1, SWIGTYPE_p_hive_key, 0); -} - -%feature("docstring") reg_open_hive "S.__init__(location, session_info=None, credentials=None, loadparm_context=None)"; -%rename(hive_key) reg_open_hive; -WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct event_context *ev_ctx, - struct loadparm_context *lp_ctx, - struct hive_key **root); - -%feature("docstring") reg_open_ldb_file "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key"; -%rename(open_ldb) reg_open_ldb_file; -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct event_context *ev_ctx, - struct loadparm_context *lp_ctx, - struct hive_key **k); - -%feature("docstring") reg_create_directory "create_dir(location) -> key"; -%rename(create_dir) reg_create_directory; -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); - -%feature("docstring") reg_open_directory "open_dir(location) -> key"; -%rename(open_dir) reg_open_directory; -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); - -%talloctype(hive_key); - -typedef struct hive_key { - %extend { - %feature("docstring") del "S.del(name) -> None\n" - "Delete a subkey"; - WERROR del(const char *name); - %feature("docstring") flush "S.flush() -> None\n" - "Flush this key to disk"; - WERROR flush(void); - %feature("docstring") del_value "S.del_value(name) -> None\n" - "Delete a value"; - WERROR del_value(const char *name); - %feature("docstring") set_value "S.set_value(name, type, data) -> None\n" - "Set a value"; - WERROR set_value(const char *name, uint32_t type, const DATA_BLOB data); - } -} hive_key; - -%rename(open_samba) reg_open_samba; - -%feature("docstring") reg_open_samba "open_samba() -> reg"; -WERROR reg_open_samba(TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct event_context *ev_ctx, - struct loadparm_context *lp_ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); - -/* Constants */ -%constant uint32_t HKEY_CLASSES_ROOT = HKEY_CLASSES_ROOT; -%constant uint32_t HKEY_CURRENT_USER = HKEY_CURRENT_USER; -%constant uint32_t HKEY_LOCAL_MACHINE = HKEY_LOCAL_MACHINE; -%constant uint32_t HKEY_USERS = HKEY_USERS; -%constant uint32_t HKEY_PERFORMANCE_DATA = HKEY_PERFORMANCE_DATA; -%constant uint32_t HKEY_CURRENT_CONFIG = HKEY_CURRENT_CONFIG; -%constant uint32_t HKEY_DYN_DATA = HKEY_DYN_DATA; -%constant uint32_t HKEY_PERFORMANCE_TEXT = HKEY_PERFORMANCE_TEXT; -%constant uint32_t HKEY_PERFORMANCE_NLSTEXT = HKEY_PERFORMANCE_NLSTEXT; diff --git a/source4/lib/registry/registry.py b/source4/lib/registry/registry.py deleted file mode 100644 index e086a6ad37..0000000000 --- a/source4/lib/registry/registry.py +++ /dev/null @@ -1,151 +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. - -""" -Access to various registry formats and the Samba registry. -""" - -import _registry -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 - - -import credentials -import param -import events -reg_get_predef_name = _registry.reg_get_predef_name -str_regtype = _registry.str_regtype -Registry = _registry.Registry -class reg(object): - thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') - __repr__ = _swig_repr - def get_predefined_key_by_name(*args, **kwargs): - """ - S.get_predefined_key_by_name(name) -> key - Find a predefined key by name - """ - return _registry.reg_get_predefined_key_by_name(*args, **kwargs) - - def key_del_abs(*args, **kwargs): - """ - S.key_del_abs(name) -> None - Delete a key by absolute path. - """ - return _registry.reg_key_del_abs(*args, **kwargs) - - def get_predefined_key(*args, **kwargs): - """ - S.get_predefined_key(hkey_id) -> key - Find a predefined key by id - """ - return _registry.reg_get_predefined_key(*args, **kwargs) - - def diff_apply(*args, **kwargs): - """ - S.diff_apply(filename) -> None - Apply the diff from the specified file - """ - return _registry.reg_diff_apply(*args, **kwargs) - - def mount_hive(*args): - """ - S.mount_hive(key, predef_name) -> None - Mount the specified key at the specified path. - """ - return _registry.reg_mount_hive(*args) - - def __init__(self, *args, **kwargs): - _registry.reg_swiginit(self,_registry.new_reg(*args, **kwargs)) - __swig_destroy__ = _registry.delete_reg -reg.get_predefined_key_by_name = new_instancemethod(_registry.reg_get_predefined_key_by_name,None,reg) -reg.key_del_abs = new_instancemethod(_registry.reg_key_del_abs,None,reg) -reg.get_predefined_key = new_instancemethod(_registry.reg_get_predefined_key,None,reg) -reg.diff_apply = new_instancemethod(_registry.reg_diff_apply,None,reg) -reg.generate_diff = new_instancemethod(_registry.reg_generate_diff,None,reg) -reg.import_hive_key = new_instancemethod(_registry.reg_import_hive_key,None,reg) -reg.mount_hive = new_instancemethod(_registry.reg_mount_hive,None,reg) -reg_swigregister = _registry.reg_swigregister -reg_swigregister(reg) - - -def hive_key(*args, **kwargs): - """S.__init__(location, session_info=None, credentials=None, loadparm_context=None)""" - return _registry.hive_key(*args, **kwargs) - -def open_ldb(*args, **kwargs): - """open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key""" - return _registry.open_ldb(*args, **kwargs) - -def create_dir(*args, **kwargs): - """create_dir(location) -> key""" - return _registry.create_dir(*args, **kwargs) - -def open_dir(*args, **kwargs): - """open_dir(location) -> key""" - return _registry.open_dir(*args, **kwargs) - -def open_samba(*args, **kwargs): - """open_samba() -> reg""" - return _registry.open_samba(*args, **kwargs) -HKEY_CLASSES_ROOT = _registry.HKEY_CLASSES_ROOT -HKEY_CURRENT_USER = _registry.HKEY_CURRENT_USER -HKEY_LOCAL_MACHINE = _registry.HKEY_LOCAL_MACHINE -HKEY_USERS = _registry.HKEY_USERS -HKEY_PERFORMANCE_DATA = _registry.HKEY_PERFORMANCE_DATA -HKEY_CURRENT_CONFIG = _registry.HKEY_CURRENT_CONFIG -HKEY_DYN_DATA = _registry.HKEY_DYN_DATA -HKEY_PERFORMANCE_TEXT = _registry.HKEY_PERFORMANCE_TEXT -HKEY_PERFORMANCE_NLSTEXT = _registry.HKEY_PERFORMANCE_NLSTEXT - - diff --git a/source4/lib/registry/registry_wrap.c b/source4/lib/registry/registry_wrap.c deleted file mode 100644 index 69b390f48a..0000000000 --- a/source4/lib/registry/registry_wrap.c +++ /dev/null @@ -1,4489 +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_auth_session_info swig_types[1] -#define SWIGTYPE_p_char swig_types[2] -#define SWIGTYPE_p_cli_credentials swig_types[3] -#define SWIGTYPE_p_event_context swig_types[4] -#define SWIGTYPE_p_hive_key swig_types[5] -#define SWIGTYPE_p_int swig_types[6] -#define SWIGTYPE_p_loadparm_context swig_types[7] -#define SWIGTYPE_p_loadparm_service swig_types[8] -#define SWIGTYPE_p_long_long swig_types[9] -#define SWIGTYPE_p_p_char swig_types[10] -#define SWIGTYPE_p_p_hive_key swig_types[11] -#define SWIGTYPE_p_p_registry_context swig_types[12] -#define SWIGTYPE_p_p_registry_key swig_types[13] -#define SWIGTYPE_p_param_context swig_types[14] -#define SWIGTYPE_p_param_opt swig_types[15] -#define SWIGTYPE_p_param_section swig_types[16] -#define SWIGTYPE_p_reg_diff_callbacks swig_types[17] -#define SWIGTYPE_p_registry_context swig_types[18] -#define SWIGTYPE_p_registry_key swig_types[19] -#define SWIGTYPE_p_short swig_types[20] -#define SWIGTYPE_p_signed_char swig_types[21] -#define SWIGTYPE_p_smb_iconv_convenience swig_types[22] -#define SWIGTYPE_p_unsigned_char swig_types[23] -#define SWIGTYPE_p_unsigned_int swig_types[24] -#define SWIGTYPE_p_unsigned_long_long swig_types[25] -#define SWIGTYPE_p_unsigned_short swig_types[26] -static swig_type_info *swig_types[28]; -static swig_module_info swig_module = {swig_types, 27, 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):= _registry.so - ------------------------------------------------*/ -#define SWIG_init init_registry - -#define SWIG_name "_registry" - -#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 headers */ -#include <stdint.h> -#include <stdbool.h> - -#include "includes.h" -#include "registry.h" -#include "param/param.h" -#include "events/events.h" -#include "scripting/python/modules.h" - -typedef struct registry_context reg; -typedef struct hive_key hive_key; - - -#include "libcli/util/pyerrors.h" - - -#include <limits.h> -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include <float.h> - - -#include <math.h> - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) -{ - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v >= 0) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else if (PyLong_Check(obj)) { - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_int (PyObject * obj, unsigned int *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v > UINT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (unsigned int)(v); - } - } - return res; -} - - -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; -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - return pchar_descriptor ? - SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); - } else { - return PyString_FromStringAndSize(carray, (int)(size)); - } - } else { - return SWIG_Py_Void(); - } -} - - -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtr(const char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - - -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; -} - - - - -SWIGINTERN WERROR reg_mount_hive__SWIG_1(reg *self,struct hive_key *key,char const *predef_name){ - int i; - for (i = 0; reg_predefined_keys[i].name; i++) { - if (!strcasecmp(reg_predefined_keys[i].name, predef_name)) - return reg_mount_hive(self, key, - reg_predefined_keys[i].handle, NULL); - } - return WERR_INVALID_NAME; - } - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject* -SWIG_From_unsigned_SS_long (unsigned long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLong(value) : PyInt_FromLong((long)(value)); -} - - -SWIGINTERNINLINE PyObject * -SWIG_From_unsigned_SS_int (unsigned int value) -{ - return SWIG_From_unsigned_SS_long (value); -} - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_reg_get_predef_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - uint32_t arg1 ; - unsigned int val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "hkey", NULL - }; - char *result = 0 ; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:reg_get_predef_name",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_unsigned_SS_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "reg_get_predef_name" "', argument " "1"" of type '" "uint32_t""'"); - } - arg1 = (uint32_t)(val1); - result = (char *)reg_get_predef_name(arg1); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_str_regtype(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - int arg1 ; - int val1 ; - int ecode1 = 0 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "type", NULL - }; - char *result = 0 ; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:str_regtype",kwnames,&obj0)) SWIG_fail; - ecode1 = SWIG_AsVal_int(obj0, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "str_regtype" "', argument " "1"" of type '" "int""'"); - } - arg1 = (int)(val1); - result = (char *)str_regtype(arg1); - resultobj = SWIG_FromCharPtr((const char *)result); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - struct registry_context **arg2 = (struct registry_context **) 0 ; - struct registry_context *tmp2 ; - WERROR result; - - arg1 = NULL; - arg2 = &tmp2; - if (!SWIG_Python_UnpackTuple(args,"Registry",0,0,0)) SWIG_fail; - result = reg_open_local(arg1,arg2); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - char *arg2 = (char *) 0 ; - struct registry_key **arg3 = (struct registry_key **) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "name",(char *) "key", NULL - }; - WERROR result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key_by_name",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_get_predefined_key_by_name" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_get_predefined_key_by_name" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_p_registry_key, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_get_predefined_key_by_name" "', argument " "3"" of type '" "struct registry_key **""'"); - } - arg3 = (struct registry_key **)(argp3); - result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - char *arg2 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "path", NULL - }; - WERROR result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_key_del_abs",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_key_del_abs" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_key_del_abs" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - result = reg_key_del_abs(arg1,(char const *)arg2); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - uint32_t arg2 ; - struct registry_key **arg3 = (struct registry_key **) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - unsigned int val2 ; - int ecode2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "hkey_id",(char *) "key", NULL - }; - WERROR result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:reg_get_predefined_key",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_get_predefined_key" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - ecode2 = SWIG_AsVal_unsigned_SS_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "reg_get_predefined_key" "', argument " "2"" of type '" "uint32_t""'"); - } - arg2 = (uint32_t)(val2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_p_registry_key, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_get_predefined_key" "', argument " "3"" of type '" "struct registry_key **""'"); - } - arg3 = (struct registry_key **)(argp3); - result = reg_get_predefined_key(arg1,arg2,arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - struct smb_iconv_convenience *arg2 = (struct smb_iconv_convenience *) 0 ; - char *arg3 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - int res3 ; - char *buf3 = 0 ; - int alloc3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "filename", NULL - }; - WERROR result; - - arg2 = py_iconv_convenience(NULL); - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:reg_diff_apply",kwnames,&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_diff_apply" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res3 = SWIG_AsCharPtrAndSize(obj1, &buf3, NULL, &alloc3); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_diff_apply" "', argument " "3"" of type '" "char const *""'"); - } - arg3 = (char *)(buf3); - result = reg_diff_apply(arg1,arg2,(char const *)arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - talloc_free(arg2); - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return resultobj; -fail: - talloc_free(arg2); - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - struct registry_context *arg2 = (struct registry_context *) 0 ; - struct reg_diff_callbacks *arg3 = (struct reg_diff_callbacks *) 0 ; - void *arg4 = (void *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - int res4 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "ctx2",(char *) "callbacks",(char *) "callback_data", NULL - }; - WERROR result; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_generate_diff",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_generate_diff" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_generate_diff" "', argument " "2"" of type '" "struct registry_context *""'"); - } - arg2 = (struct registry_context *)(argp2); - res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_reg_diff_callbacks, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_generate_diff" "', argument " "3"" of type '" "struct reg_diff_callbacks const *""'"); - } - arg3 = (struct reg_diff_callbacks *)(argp3); - res4 = SWIG_ConvertPtr(obj3,SWIG_as_voidptrptr(&arg4), 0, 0); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "reg_generate_diff" "', argument " "4"" of type '" "void *""'"); - } - result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - struct hive_key *arg2 = (struct hive_key *) 0 ; - uint32_t arg3 ; - char **arg4 = (char **) NULL ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - unsigned int val3 ; - int ecode3 = 0 ; - WERROR result; - - if ((nobjs < 3) || (nobjs > 4)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_mount_hive" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_mount_hive" "', argument " "2"" of type '" "struct hive_key *""'"); - } - arg2 = (struct hive_key *)(argp2); - ecode3 = SWIG_AsVal_unsigned_SS_int(swig_obj[2], &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_mount_hive" "', argument " "3"" of type '" "uint32_t""'"); - } - arg3 = (uint32_t)(val3); - if (swig_obj[3]) { - /* Check if is a list */ - if (PyList_Check(swig_obj[3])) { - int size = PyList_Size(swig_obj[3]); - int i = 0; - arg4 = (char **) malloc((size+1)*sizeof(const char *)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem(swig_obj[3],i); - if (PyString_Check(o)) - arg4[i] = PyString_AsString(PyList_GetItem(swig_obj[3],i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free(arg4); - return NULL; - } - } - arg4[i] = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } - } - result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - free((char **) arg4); - return resultobj; -fail: - free((char **) arg4); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_import_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - struct hive_key *arg2 = (struct hive_key *) 0 ; - uint32_t arg3 ; - char **arg4 = (char **) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - unsigned int val3 ; - int ecode3 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "self",(char *) "hive",(char *) "predef_key",(char *) "elements", NULL - }; - struct registry_key *result = 0 ; - - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:reg_import_hive_key",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_import_hive_key" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_import_hive_key" "', argument " "2"" of type '" "struct hive_key *""'"); - } - arg2 = (struct hive_key *)(argp2); - ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3); - if (!SWIG_IsOK(ecode3)) { - SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "reg_import_hive_key" "', argument " "3"" of type '" "uint32_t""'"); - } - arg3 = (uint32_t)(val3); - /* Check if is a list */ - if (PyList_Check(obj3)) { - int size = PyList_Size(obj3); - int i = 0; - arg4 = (char **) malloc((size+1)*sizeof(const char *)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem(obj3,i); - if (PyString_Check(o)) - arg4[i] = PyString_AsString(PyList_GetItem(obj3,i)); - else { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free(arg4); - return NULL; - } - } - arg4[i] = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } - result = (struct registry_key *)reg_import_hive_key(arg1,arg2,arg3,(char const **)arg4); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_key, 0 | 0 ); - free((char **) arg4); - return resultobj; -fail: - free((char **) arg4); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 0 ; - struct hive_key *arg2 = (struct hive_key *) 0 ; - char *arg3 = (char *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; - int res3 ; - char *buf3 = 0 ; - int alloc3 = 0 ; - WERROR result; - - if ((nobjs < 3) || (nobjs > 3)) SWIG_fail; - res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_registry_context, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "reg_mount_hive" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_hive_key, 0 | 0 ); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "reg_mount_hive" "', argument " "2"" of type '" "struct hive_key *""'"); - } - arg2 = (struct hive_key *)(argp2); - res3 = SWIG_AsCharPtrAndSize(swig_obj[2], &buf3, NULL, &alloc3); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "reg_mount_hive" "', argument " "3"" of type '" "char const *""'"); - } - arg3 = (char *)(buf3); - result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return resultobj; -fail: - if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_reg_mount_hive(PyObject *self, PyObject *args) { - int argc; - PyObject *argv[5]; - - if (!(argc = SWIG_Python_UnpackTuple(args,"reg_mount_hive",0,4,argv))) SWIG_fail; - --argc; - if ((argc >= 3) && (argc <= 4)) { - int _v = 0; - { - { - int res = SWIG_AsVal_unsigned_SS_int(argv[2], NULL); - _v = SWIG_CheckState(res); - } - } - if (!_v) goto check_1; - return _wrap_reg_mount_hive__SWIG_0(self, argc, argv); - } -check_1: - - if (argc == 3) { - return _wrap_reg_mount_hive__SWIG_1(self, argc, argv); - } - -fail: - SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'reg_mount_hive'.\n" - " Possible C/C++ prototypes are:\n" - " mount_hive(reg *,struct hive_key *,uint32_t,char const **)\n" - " mount_hive(reg *,struct hive_key *,char const *)\n"); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_new_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - reg *result = 0 ; - - if (!SWIG_Python_UnpackTuple(args,"new_reg",0,0,0)) SWIG_fail; - result = (reg *)calloc(1, sizeof(reg)); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_registry_context, SWIG_POINTER_NEW | 0 ); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_delete_reg(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - reg *arg1 = (reg *) 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_registry_context, SWIG_POINTER_DISOWN | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_reg" "', argument " "1"" of type '" "reg *""'"); - } - arg1 = (reg *)(argp1); - free((char *) arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *reg_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *obj; - if (!SWIG_Python_UnpackTuple(args,(char*)"swigregister", 1, 1,&obj)) return NULL; - SWIG_TypeNewClientData(SWIGTYPE_p_registry_context, SWIG_NewClientData(obj)); - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject *reg_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - return SWIG_Python_InitShadowInstance(args); -} - -SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char *arg2 = (char *) 0 ; - struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; - struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; - struct event_context *arg5 = (struct event_context *) 0 ; - struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; - struct hive_key **arg7 = (struct hive_key **) 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - void *argp4 = 0 ; - int res4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - void *argp6 = 0 ; - int res6 = 0 ; - struct hive_key *tmp7 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - char * kwnames[] = { - (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL - }; - WERROR result; - - arg3 = NULL; - arg4 = NULL; - arg5 = event_context_init(NULL); - arg6 = loadparm_init(NULL); - arg1 = NULL; - arg7 = &tmp7; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:hive_key",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "hive_key" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (obj1) { - res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "hive_key" "', argument " "3"" of type '" "struct auth_session_info *""'"); - } - arg3 = (struct auth_session_info *)(argp3); - } - if (obj2) { - res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "hive_key" "', argument " "4"" of type '" "struct cli_credentials *""'"); - } - arg4 = (struct cli_credentials *)(argp4); - } - if (obj3) { - res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "hive_key" "', argument " "5"" of type '" "struct event_context *""'"); - } - arg5 = (struct event_context *)(argp5); - } - if (obj4) { - res6 = SWIG_ConvertPtr(obj4, &argp6,SWIGTYPE_p_loadparm_context, 0 | 0 ); - if (!SWIG_IsOK(res6)) { - SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "hive_key" "', argument " "6"" of type '" "struct loadparm_context *""'"); - } - arg6 = (struct loadparm_context *)(argp6); - } - result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg7, SWIGTYPE_p_hive_key, 0); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char *arg2 = (char *) 0 ; - struct auth_session_info *arg3 = (struct auth_session_info *) 0 ; - struct cli_credentials *arg4 = (struct cli_credentials *) 0 ; - struct event_context *arg5 = (struct event_context *) 0 ; - struct loadparm_context *arg6 = (struct loadparm_context *) 0 ; - struct hive_key **arg7 = (struct hive_key **) 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - void *argp3 = 0 ; - int res3 = 0 ; - void *argp4 = 0 ; - int res4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - void *argp6 = 0 ; - int res6 = 0 ; - struct hive_key *tmp7 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - PyObject * obj4 = 0 ; - char * kwnames[] = { - (char *) "location",(char *) "session_info",(char *) "credentials",(char *) "ev_ctx",(char *) "lp_ctx", NULL - }; - WERROR result; - - arg3 = NULL; - arg4 = NULL; - arg5 = event_context_init(NULL); - arg6 = loadparm_init(NULL); - arg1 = NULL; - arg7 = &tmp7; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:open_ldb",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; - res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_ldb" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - if (obj1) { - res3 = SWIG_ConvertPtr(obj1, &argp3,SWIGTYPE_p_auth_session_info, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_ldb" "', argument " "3"" of type '" "struct auth_session_info *""'"); - } - arg3 = (struct auth_session_info *)(argp3); - } - if (obj2) { - res4 = SWIG_ConvertPtr(obj2, &argp4,SWIGTYPE_p_cli_credentials, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_ldb" "', argument " "4"" of type '" "struct cli_credentials *""'"); - } - arg4 = (struct cli_credentials *)(argp4); - } - if (obj3) { - res5 = SWIG_ConvertPtr(obj3, &argp5,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_ldb" "', argument " "5"" of type '" "struct event_context *""'"); - } - arg5 = (struct event_context *)(argp5); - } - if (obj4) { - res6 = SWIG_ConvertPtr(obj4, &argp6,SWIGTYPE_p_loadparm_context, 0 | 0 ); - if (!SWIG_IsOK(res6)) { - SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "open_ldb" "', argument " "6"" of type '" "struct loadparm_context *""'"); - } - arg6 = (struct loadparm_context *)(argp6); - } - result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6,arg7); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg7, SWIGTYPE_p_hive_key, 0); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char *arg2 = (char *) 0 ; - struct hive_key **arg3 = (struct hive_key **) 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - struct hive_key *tmp3 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "location", NULL - }; - WERROR result; - - arg1 = NULL; - arg3 = &tmp3; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:create_dir",kwnames,&obj0)) SWIG_fail; - res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "create_dir" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - result = reg_create_directory(arg1,(char const *)arg2,arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - char *arg2 = (char *) 0 ; - struct hive_key **arg3 = (struct hive_key **) 0 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - struct hive_key *tmp3 ; - PyObject * obj0 = 0 ; - char * kwnames[] = { - (char *) "location", NULL - }; - WERROR result; - - arg1 = NULL; - arg3 = &tmp3; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:open_dir",kwnames,&obj0)) SWIG_fail; - res2 = SWIG_AsCharPtrAndSize(obj0, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_dir" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - result = reg_open_directory(arg1,(char const *)arg2,arg3); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - Py_XDECREF(resultobj); - resultobj = SWIG_NewPointerObj(*arg3, SWIGTYPE_p_hive_key, 0); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { - PyObject *resultobj = 0; - TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; - struct registry_context **arg2 = (struct registry_context **) 0 ; - struct event_context *arg3 = (struct event_context *) 0 ; - struct loadparm_context *arg4 = (struct loadparm_context *) 0 ; - struct auth_session_info *arg5 = (struct auth_session_info *) 0 ; - struct cli_credentials *arg6 = (struct cli_credentials *) 0 ; - struct registry_context *tmp2 ; - void *argp3 = 0 ; - int res3 = 0 ; - void *argp4 = 0 ; - int res4 = 0 ; - void *argp5 = 0 ; - int res5 = 0 ; - void *argp6 = 0 ; - int res6 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - PyObject * obj3 = 0 ; - char * kwnames[] = { - (char *) "ev_ctx",(char *) "lp_ctx",(char *) "session_info",(char *) "credentials", NULL - }; - WERROR result; - - arg3 = event_context_init(NULL); - arg4 = loadparm_init(NULL); - arg5 = NULL; - arg6 = NULL; - arg1 = NULL; - arg2 = &tmp2; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OOOO:open_samba",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; - if (obj0) { - res3 = SWIG_ConvertPtr(obj0, &argp3,SWIGTYPE_p_event_context, 0 | 0 ); - if (!SWIG_IsOK(res3)) { - SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "open_samba" "', argument " "3"" of type '" "struct event_context *""'"); - } - arg3 = (struct event_context *)(argp3); - } - if (obj1) { - res4 = SWIG_ConvertPtr(obj1, &argp4,SWIGTYPE_p_loadparm_context, 0 | 0 ); - if (!SWIG_IsOK(res4)) { - SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "open_samba" "', argument " "4"" of type '" "struct loadparm_context *""'"); - } - arg4 = (struct loadparm_context *)(argp4); - } - if (obj2) { - res5 = SWIG_ConvertPtr(obj2, &argp5,SWIGTYPE_p_auth_session_info, 0 | 0 ); - if (!SWIG_IsOK(res5)) { - SWIG_exception_fail(SWIG_ArgError(res5), "in method '" "open_samba" "', argument " "5"" of type '" "struct auth_session_info *""'"); - } - arg5 = (struct auth_session_info *)(argp5); - } - if (obj3) { - res6 = SWIG_ConvertPtr(obj3, &argp6,SWIGTYPE_p_cli_credentials, 0 | 0 ); - if (!SWIG_IsOK(res6)) { - SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "open_samba" "', argument " "6"" of type '" "struct cli_credentials *""'"); - } - arg6 = (struct cli_credentials *)(argp6); - } - result = reg_open_samba(arg1,arg2,arg3,arg4,arg5,arg6); - if (!W_ERROR_IS_OK(result)) { - PyErr_SetWERROR(result); - SWIG_fail; - } else if (resultobj == NULL) { - resultobj = Py_None; - } - resultobj = SWIG_NewPointerObj(*arg2, SWIGTYPE_p_registry_context, 0); - return resultobj; -fail: - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"reg_get_predef_name", (PyCFunction) _wrap_reg_get_predef_name, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"str_regtype", (PyCFunction) _wrap_str_regtype, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"Registry", (PyCFunction)_wrap_Registry, METH_NOARGS, NULL}, - { (char *)"reg_get_predefined_key_by_name", (PyCFunction) _wrap_reg_get_predefined_key_by_name, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.get_predefined_key_by_name(name) -> key\n" - "Find a predefined key by name\n" - ""}, - { (char *)"reg_key_del_abs", (PyCFunction) _wrap_reg_key_del_abs, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.key_del_abs(name) -> None\n" - "Delete a key by absolute path.\n" - ""}, - { (char *)"reg_get_predefined_key", (PyCFunction) _wrap_reg_get_predefined_key, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.get_predefined_key(hkey_id) -> key\n" - "Find a predefined key by id\n" - ""}, - { (char *)"reg_diff_apply", (PyCFunction) _wrap_reg_diff_apply, METH_VARARGS | METH_KEYWORDS, (char *)"\n" - "S.diff_apply(filename) -> None\n" - "Apply the diff from the specified file\n" - ""}, - { (char *)"reg_generate_diff", (PyCFunction) _wrap_reg_generate_diff, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_import_hive_key", (PyCFunction) _wrap_reg_import_hive_key, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"reg_mount_hive", _wrap_reg_mount_hive, METH_VARARGS, NULL}, - { (char *)"new_reg", (PyCFunction)_wrap_new_reg, METH_NOARGS, NULL}, - { (char *)"delete_reg", (PyCFunction)_wrap_delete_reg, METH_O, NULL}, - { (char *)"reg_swigregister", reg_swigregister, METH_VARARGS, NULL}, - { (char *)"reg_swiginit", reg_swiginit, METH_VARARGS, NULL}, - { (char *)"hive_key", (PyCFunction) _wrap_hive_key, METH_VARARGS | METH_KEYWORDS, (char *)"S.__init__(location, session_info=None, credentials=None, loadparm_context=None)"}, - { (char *)"open_ldb", (PyCFunction) _wrap_open_ldb, METH_VARARGS | METH_KEYWORDS, (char *)"open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key"}, - { (char *)"create_dir", (PyCFunction) _wrap_create_dir, METH_VARARGS | METH_KEYWORDS, (char *)"create_dir(location) -> key"}, - { (char *)"open_dir", (PyCFunction) _wrap_open_dir, METH_VARARGS | METH_KEYWORDS, (char *)"open_dir(location) -> key"}, - { (char *)"open_samba", (PyCFunction) _wrap_open_samba, METH_VARARGS | METH_KEYWORDS, (char *)"open_samba() -> reg"}, - { 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_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 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_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 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_hive_key = {"_p_hive_key", "struct hive_key *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 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 _swigt__p_p_hive_key = {"_p_p_hive_key", "struct hive_key **", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_registry_context = {"_p_p_registry_context", "struct registry_context **", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_p_registry_key = {"_p_p_registry_key", "struct registry_key **", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_param_opt = {"_p_param_opt", "struct param_opt *|param_opt *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_reg_diff_callbacks = {"_p_reg_diff_callbacks", "struct reg_diff_callbacks *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_registry_context = {"_p_registry_context", "struct registry_context *|reg *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_registry_key = {"_p_registry_key", "struct registry_key *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_smb_iconv_convenience = {"_p_smb_iconv_convenience", "struct smb_iconv_convenience *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_TALLOC_CTX, - &_swigt__p_auth_session_info, - &_swigt__p_char, - &_swigt__p_cli_credentials, - &_swigt__p_event_context, - &_swigt__p_hive_key, - &_swigt__p_int, - &_swigt__p_loadparm_context, - &_swigt__p_loadparm_service, - &_swigt__p_long_long, - &_swigt__p_p_char, - &_swigt__p_p_hive_key, - &_swigt__p_p_registry_context, - &_swigt__p_p_registry_key, - &_swigt__p_param_context, - &_swigt__p_param_opt, - &_swigt__p_param_section, - &_swigt__p_reg_diff_callbacks, - &_swigt__p_registry_context, - &_swigt__p_registry_key, - &_swigt__p_short, - &_swigt__p_signed_char, - &_swigt__p_smb_iconv_convenience, - &_swigt__p_unsigned_char, - &_swigt__p_unsigned_int, - &_swigt__p_unsigned_long_long, - &_swigt__p_unsigned_short, -}; - -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_auth_session_info[] = { {&_swigt__p_auth_session_info, 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_cli_credentials[] = { {&_swigt__p_cli_credentials, 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_hive_key[] = { {&_swigt__p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_loadparm_service[] = { {&_swigt__p_loadparm_service, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 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 _swigc__p_p_hive_key[] = { {&_swigt__p_p_hive_key, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_registry_context[] = { {&_swigt__p_p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_p_registry_key[] = { {&_swigt__p_p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_param_opt[] = { {&_swigt__p_param_opt, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_reg_diff_callbacks[] = { {&_swigt__p_reg_diff_callbacks, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_registry_context[] = { {&_swigt__p_registry_context, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_registry_key[] = { {&_swigt__p_registry_key, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_smb_iconv_convenience[] = { {&_swigt__p_smb_iconv_convenience, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_TALLOC_CTX, - _swigc__p_auth_session_info, - _swigc__p_char, - _swigc__p_cli_credentials, - _swigc__p_event_context, - _swigc__p_hive_key, - _swigc__p_int, - _swigc__p_loadparm_context, - _swigc__p_loadparm_service, - _swigc__p_long_long, - _swigc__p_p_char, - _swigc__p_p_hive_key, - _swigc__p_p_registry_context, - _swigc__p_p_registry_key, - _swigc__p_param_context, - _swigc__p_param_opt, - _swigc__p_param_section, - _swigc__p_reg_diff_callbacks, - _swigc__p_registry_context, - _swigc__p_registry_key, - _swigc__p_short, - _swigc__p_signed_char, - _swigc__p_smb_iconv_convenience, - _swigc__p_unsigned_char, - _swigc__p_unsigned_int, - _swigc__p_unsigned_long_long, - _swigc__p_unsigned_short, -}; - - -/* -------- 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); - - - SWIG_Python_SetConstant(d, "HKEY_CLASSES_ROOT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CLASSES_ROOT))); - SWIG_Python_SetConstant(d, "HKEY_CURRENT_USER",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CURRENT_USER))); - SWIG_Python_SetConstant(d, "HKEY_LOCAL_MACHINE",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_LOCAL_MACHINE))); - SWIG_Python_SetConstant(d, "HKEY_USERS",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_USERS))); - SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_DATA",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_DATA))); - SWIG_Python_SetConstant(d, "HKEY_CURRENT_CONFIG",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_CURRENT_CONFIG))); - SWIG_Python_SetConstant(d, "HKEY_DYN_DATA",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_DYN_DATA))); - SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_TEXT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_TEXT))); - SWIG_Python_SetConstant(d, "HKEY_PERFORMANCE_NLSTEXT",SWIG_From_unsigned_SS_int((unsigned int)(HKEY_PERFORMANCE_NLSTEXT))); -} - diff --git a/source4/lib/registry/tests/bindings.py b/source4/lib/registry/tests/bindings.py index 1fb5c70b70..8c3233ef1e 100644 --- a/source4/lib/registry/tests/bindings.py +++ b/source4/lib/registry/tests/bindings.py @@ -25,7 +25,7 @@ import samba.tests class HelperTests(unittest.TestCase): def test_predef_to_name(self): self.assertEquals("HKEY_LOCAL_MACHINE", - registry.reg_get_predef_name(0x80000002)) + registry.get_predef_name(0x80000002)) def test_str_regtype(self): self.assertEquals("REG_DWORD", registry.str_regtype(4)) 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/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c index b902dddb0f..bbb363e0dd 100644 --- a/source4/libcli/auth/smbencrypt.c +++ b/source4/libcli/auth/smbencrypt.c @@ -585,7 +585,7 @@ bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, *new_pass = data_blob_talloc(mem_ctx, &in_buffer[512 - byte_len], byte_len); - if (!*new_pass->data) { + if (!new_pass->data) { return false; } 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/util/pyerrors.h b/source4/libcli/util/pyerrors.h index 47e6f58b5d..66823f4a41 100644 --- a/source4/libcli/util/pyerrors.h +++ b/source4/libcli/util/pyerrors.h @@ -30,4 +30,16 @@ #define PyErr_SetNTSTATUS(status) \ PyErr_SetObject(PyExc_RuntimeError, PyErr_FromNTSTATUS(status)) +#define PyErr_NTSTATUS_IS_ERR_RAISE(status) \ + if (NT_STATUS_IS_ERR(status)) { \ + PyErr_SetNTSTATUS(status); \ + return NULL; \ + } + +#define PyErr_WERROR_IS_ERR_RAISE(status) \ + if (!W_ERROR_IS_OK(status)) { \ + PyErr_SetWERROR(status); \ + return NULL; \ + } + #endif /* __PYERRORS_H__ */ 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 dcf2f3e0ab..7871a93604 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -57,7 +57,7 @@ NDR_SECURITY_OBJ_FILES = ../librpc/gen_ndr/ndr_security.o \ $(gen_ndrsrcdir)/ndr_server_id.o PUBLIC_HEADERS += ../librpc/gen_ndr/security.h - +PUBLIC_HEADERS += $(gen_ndrsrcdir)/server_id.h [SUBSYSTEM::NDR_AUDIOSRV] PUBLIC_DEPENDENCIES = LIBNDR 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/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index a27386bb13..117d16d20a 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -25,7 +25,7 @@ #include "includes.h" #include "system/filesys.h" #include "ntvfs/sysdep/sys_notify.h" -#include "lib/events/events.h" +#include "../lib/tevent/tevent.h" #include "../lib/util/dlinklist.h" #include "param/param.h" 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..3711ed7bab 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": @@ -650,7 +653,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): reg = registry.Registry() hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) - reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") + reg.mount_hive(hive, registry.HKEY_LOCAL_MACHINE) provision_reg = setup_path("provision.reg") assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) @@ -827,6 +830,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, message("Setting up sam.ldb AD schema") setup_add_ldif(samdb, setup_path("schema.ldif"), {"SCHEMADN": names.schemadn}) + setup_add_ldif(samdb, setup_path("aggregate_schema.ldif"), + {"SCHEMADN": names.schemadn}) message("Setting up sam.ldb configuration data") setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 0e0c29dac8..a3dac27709 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -25,9 +25,28 @@ REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" REGISTRY_DB_VERSION = 1 import os +import struct import tdb +def fetch_uint32(tdb, key): + try: + data = tdb[key] + except KeyError: + return None + assert len(data) == 4 + return struct.unpack("<L", data)[0] + + +def fetch_int32(tdb, key): + try: + data = tdb[key] + except KeyError: + return None + assert len(data) == 4 + return struct.unpack("<l", data)[0] + + class TdbDatabase(object): """Simple Samba 3 TDB database reader.""" def __init__(self, file): @@ -60,7 +79,7 @@ class Registry(TdbDatabase): def keys(self): """Return list with all the keys.""" - return [k.rstrip("\x00") for k in self.tdb.keys() if not k.startswith(REGISTRY_VALUE_PREFIX)] + return [k.rstrip("\x00") for k in self.tdb.iterkeys() if not k.startswith(REGISTRY_VALUE_PREFIX)] def subkeys(self, key): """Retrieve the subkeys for the specified key. @@ -71,7 +90,6 @@ class Registry(TdbDatabase): data = self.tdb.get("%s\x00" % key) if data is None: return [] - import struct (num, ) = struct.unpack("<L", data[0:4]) keys = data[4:].split("\0") assert keys[-1] == "" @@ -89,7 +107,6 @@ class Registry(TdbDatabase): if data is None: return {} ret = {} - import struct (num, ) = struct.unpack("<L", data[0:4]) data = data[4:] for i in range(num): @@ -115,16 +132,16 @@ class PolicyDatabase(TdbDatabase): :param file: Path to the file to open. """ super(PolicyDatabase, self).__init__(file) - self.min_password_length = self.tdb.fetch_uint32("min password length\x00") - self.password_history = self.tdb.fetch_uint32("password history\x00") - self.user_must_logon_to_change_password = self.tdb.fetch_uint32("user must logon to change pasword\x00") - self.maximum_password_age = self.tdb.fetch_uint32("maximum password age\x00") - self.minimum_password_age = self.tdb.fetch_uint32("minimum password age\x00") - self.lockout_duration = self.tdb.fetch_uint32("lockout duration\x00") - self.reset_count_minutes = self.tdb.fetch_uint32("reset count minutes\x00") - self.bad_lockout_minutes = self.tdb.fetch_uint32("bad lockout minutes\x00") - self.disconnect_time = self.tdb.fetch_int32("disconnect time\x00") - self.refuse_machine_password_change = self.tdb.fetch_uint32("refuse machine password change\x00") + self.min_password_length = fetch_uint32(self.tdb, "min password length\x00") + self.password_history = fetch_uint32(self.tdb, "password history\x00") + self.user_must_logon_to_change_password = fetch_uint32(self.tdb, "user must logon to change pasword\x00") + self.maximum_password_age = fetch_uint32(self.tdb, "maximum password age\x00") + self.minimum_password_age = fetch_uint32(self.tdb, "minimum password age\x00") + self.lockout_duration = fetch_uint32(self.tdb, "lockout duration\x00") + self.reset_count_minutes = fetch_uint32(self.tdb, "reset count minutes\x00") + self.bad_lockout_minutes = fetch_uint32(self.tdb, "bad lockout minutes\x00") + self.disconnect_time = fetch_int32(self.tdb, "disconnect time\x00") + self.refuse_machine_password_change = fetch_uint32(self.tdb, "refuse machine password change\x00") # FIXME: Read privileges as well @@ -143,14 +160,14 @@ MEMBEROF_PREFIX = "MEMBEROF/" class GroupMappingDatabase(TdbDatabase): """Samba 3 group mapping database reader.""" def _check_version(self): - assert self.tdb.fetch_int32("INFO/version\x00") in (GROUPDB_DATABASE_VERSION_V1, GROUPDB_DATABASE_VERSION_V2) + assert fetch_int32(self.tdb, "INFO/version\x00") in (GROUPDB_DATABASE_VERSION_V1, GROUPDB_DATABASE_VERSION_V2) def groupsids(self): """Retrieve the SIDs for the groups in this database. :return: List with sids as strings. """ - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith(GROUP_PREFIX): yield k[len(GROUP_PREFIX):].rstrip("\0") @@ -164,14 +181,13 @@ class GroupMappingDatabase(TdbDatabase): data = self.tdb.get("%s%s\0" % (GROUP_PREFIX, sid)) if data is None: return data - import struct (gid, sid_name_use) = struct.unpack("<lL", data[0:8]) (nt_name, comment, _) = data[8:].split("\0") return (gid, sid_name_use, nt_name, comment) def aliases(self): """Retrieve the aliases in this database.""" - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith(MEMBEROF_PREFIX): yield k[len(MEMBEROF_PREFIX):].rstrip("\0") @@ -189,17 +205,17 @@ IDMAP_VERSION_V2 = 2 class IdmapDatabase(TdbDatabase): """Samba 3 ID map database reader.""" def _check_version(self): - assert self.tdb.fetch_int32("IDMAP_VERSION\0") == IDMAP_VERSION_V2 + assert fetch_int32(self.tdb, "IDMAP_VERSION\0") == IDMAP_VERSION_V2 def uids(self): """Retrieve a list of all uids in this database.""" - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith(IDMAP_USER_PREFIX): yield int(k[len(IDMAP_USER_PREFIX):].rstrip("\0")) def gids(self): """Retrieve a list of all gids in this database.""" - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith(IDMAP_GROUP_PREFIX): yield int(k[len(IDMAP_GROUP_PREFIX):].rstrip("\0")) @@ -222,11 +238,11 @@ class IdmapDatabase(TdbDatabase): def get_user_hwm(self): """Obtain the user high-water mark.""" - return self.tdb.fetch_uint32(IDMAP_HWM_USER) + return fetch_uint32(self.tdb, IDMAP_HWM_USER) def get_group_hwm(self): """Obtain the group high-water mark.""" - return self.tdb.fetch_uint32(IDMAP_HWM_GROUP) + return fetch_uint32(self.tdb, IDMAP_HWM_GROUP) class SecretsDatabase(TdbDatabase): @@ -244,7 +260,7 @@ class SecretsDatabase(TdbDatabase): return self.tdb.get("SECRETS/DOMGUID/%s" % host) def ldap_dns(self): - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith("SECRETS/LDAP_BIND_PW/"): yield k[len("SECRETS/LDAP_BIND_PW/"):].rstrip("\0") @@ -253,7 +269,7 @@ class SecretsDatabase(TdbDatabase): :return: Iterator over the names of domains in this database. """ - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith("SECRETS/SID/"): yield k[len("SECRETS/SID/"):].rstrip("\0") @@ -264,10 +280,10 @@ class SecretsDatabase(TdbDatabase): return self.tdb.get("SECRETS/AFS_KEYFILE/%s" % host) def get_machine_sec_channel_type(self, host): - return self.tdb.fetch_uint32("SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host) + return fetch_uint32(self.tdb, "SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host) def get_machine_last_change_time(self, host): - return self.tdb.fetch_uint32("SECRETS/MACHINE_LAST_CHANGE_TIME/%s" % host) + return fetch_uint32(self.tdb, "SECRETS/MACHINE_LAST_CHANGE_TIME/%s" % host) def get_machine_password(self, host): return self.tdb.get("SECRETS/MACHINE_PASSWORD/%s" % host) @@ -279,7 +295,7 @@ class SecretsDatabase(TdbDatabase): return self.tdb.get("SECRETS/$DOMTRUST.ACC/%s" % host) def trusted_domains(self): - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith("SECRETS/$DOMTRUST.ACC/"): yield k[len("SECRETS/$DOMTRUST.ACC/"):].rstrip("\0") @@ -296,7 +312,7 @@ SHARE_DATABASE_VERSION_V2 = 2 class ShareInfoDatabase(TdbDatabase): """Samba 3 Share Info database reader.""" def _check_version(self): - assert self.tdb.fetch_int32("INFO/version\0") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) + assert fetch_int32(self.tdb, "INFO/version\0") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): """Obtain the security descriptor on a particular share. @@ -492,12 +508,12 @@ class LdapSam(object): class TdbSam(TdbDatabase): """Samba 3 TDB passdb backend reader.""" def _check_version(self): - self.version = self.tdb.fetch_uint32("INFO/version\0") or 0 + self.version = fetch_uint32(self.tdb, "INFO/version\0") or 0 assert self.version in (0, 1, 2) def usernames(self): """Iterate over the usernames in this Tdb database.""" - for k in self.tdb.keys(): + for k in self.tdb.iterkeys(): if k.startswith(TDBSAM_USER_PREFIX): yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0") @@ -506,7 +522,6 @@ class TdbSam(TdbDatabase): def __getitem__(self, name): data = self.tdb["%s%s\0" % (TDBSAM_USER_PREFIX, name)] user = SAMUser(name) - import struct def unpack_string(data): (length, ) = struct.unpack("<L", data[:4]) 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/selftest/tests.sh b/source4/selftest/tests.sh index 569759835a..0a5bdf62cd 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -401,7 +401,7 @@ plantest "samr.python" dc $SUBUNITRUN samba.tests.dcerpc.sam plantest "dcerpc.bare.python" dc $SUBUNITRUN samba.tests.dcerpc.bare plantest "unixinfo.python" dc $SUBUNITRUN samba.tests.dcerpc.unix plantest "samdb.python" none $SUBUNITRUN samba.tests.samdb -plantest "events.python" none PYTHONPATH="$PYTHONPATH:lib/events" $SUBUNITRUN tests +plantest "events.python" none PYTHONPATH="$PYTHONPATH:../lib/tevent" $SUBUNITRUN tests plantest "messaging.python" none PYTHONPATH="$PYTHONPATH:lib/messaging/tests" $SUBUNITRUN bindings plantest "samba3sam.python" none PYTHONPATH="$PYTHONPATH:dsdb/samdb/ldb_modules/tests" $SUBUNITRUN samba3sam plantest "subunit.python" none $SUBUNITRUN subunit diff --git a/source4/setup/ad-schema/MS-AD_Schema_Attributes_v20080618.txt b/source4/setup/ad-schema/MS-AD_Schema_Attributes_v20080618.txt index 324a5bf3f9..743e1d0abe 100644 --- a/source4/setup/ad-schema/MS-AD_Schema_Attributes_v20080618.txt +++ b/source4/setup/ad-schema/MS-AD_Schema_Attributes_v20080618.txt @@ -1654,7 +1654,6 @@ searchFlags: 0 rangeLower: 1
rangeUpper: 512
mapiID: 35943
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Employee-Type
@@ -1669,7 +1668,6 @@ searchFlags: fCOPY rangeLower: 1
rangeUpper: 256
mapiID: 35945
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Enabled
@@ -1756,7 +1754,6 @@ searchFlags: 0 mapiID: 32935
systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-
systemOnly: TRUE
cn: Extended-Class-Info
@@ -2722,8 +2719,6 @@ mapiID: 14857 isMemberOfPartialAttributeSet: TRUE
systemFlags: FLAG_SCHEMA_BASE_OBJECT
-systemFlags: 0
-
cn: Address-Home
ldapDisplayName: homePostalAddress
attributeId: 1.2.840.113556.1.2.617
@@ -2737,7 +2732,6 @@ rangeLower: 1 rangeUpper: 4096
attributeSecurityGuid: 77b5b886-944a-11d1-aebd-0000f80367c1
mapiID: 14941
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: host
@@ -2978,8 +2972,6 @@ mapiID: 32959 systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-searchFlags: 0
-
cn: IpHostNumber
ldapDisplayName: ipHostNumber
attributeId: 1.3.6.1.1.1.1.19
@@ -6280,7 +6272,7 @@ isSingleValued: TRUE systemOnly: FALSE
searchFlags: 0
rangeLower: 0
-schemaIdGuid:: 421f889a-472e-4fe4-8eb9-e1d0bc6071b2
+schemaIdGuid: 421f889a-472e-4fe4-8eb9-e1d0bc6071b2
systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
@@ -6294,7 +6286,7 @@ systemOnly: FALSE searchFlags: 0
rangeLower: 0
rangeUpper: 65535
-schemaIdGuid:: b8c8c35e-4a19-4a95-99d0-69fe4446286f
+schemaIdGuid: b8c8c35e-4a19-4a95-99d0-69fe4446286f
systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
@@ -6307,7 +6299,7 @@ isSingleValued: TRUE systemOnly: FALSE
searchFlags: 0
rangeLower: 0
-schemaIdGuid:: b05bda89-76af-468a-b892-1be55558ecc8
+schemaIdGuid: b05bda89-76af-468a-b892-1be55558ecc8
systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
@@ -6717,7 +6709,7 @@ omSyntax: 1 isSingleValued: TRUE
systemOnly: FALSE
searchFlags: 0
-schemaIdGuid:: 75ccdd8f-af6c-4487-bb4b-69e4d38a959c
+schemaIdGuid: 75ccdd8f-af6c-4487-bb4b-69e4d38a959c
systemFlags: FLAG_SCHEMA_BASE_OBJECT
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
@@ -7032,6 +7024,7 @@ schemaFlagsEx: FLAG_ATTR_IS_CRITICAL cn: ms-DS-Resultant-PSO
ldapDisplayName: msDS-ResultantPSO
+attributeId: 1.2.840.113556.1.4.2022
attributeSyntax: 2.5.5.1
omSyntax: 127
isSingleValued: TRUE
@@ -7494,7 +7487,7 @@ attributeSyntax: 2.5.5.10 omSyntax: 4
isSingleValued: TRUE
rangeUpper: 102400
-schemaIdGuid: 1fd55ea8-88a7-47dc-8129-0daa-97186a54
+schemaIdGuid: 1fd55ea8-88a7-47dc-8129-0daa97186a54
searchFlags: fRODCFilteredAttribute | fCONFIDENTIAL | fCOPY |fPRESERVEONDELETE
systemFlags: FLAG_SCHEMA_BASE_OBJECT
@@ -7522,7 +7515,6 @@ systemFlags: FLAG_SCHEMA_BASE_OBJECT cn: ms-FVE-VolumeGuid
ldapDisplayName: msFVE-VolumeGuid
-attributeId: 1.2.840.113556.1.4.1965
attributeId: 1.2.840.113556.1.4.1998
attributeSyntax: 2.5.5.10
omSyntax: 4
@@ -8425,8 +8417,6 @@ rangeUpper: 128 isMemberOfPartialAttributeSet: TRUE
systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
-systemFlags: FLAG_SCHEMA_BASE_OBJECT
-
cn: MSMQ-Version
ldapDisplayName: mSMQVersion
attributeId: 1.2.840.113556.1.4.942
@@ -12196,7 +12186,6 @@ systemOnly: TRUE searchFlags: 0
linkID: 101
systemFlags: FLAG_SCHEMA_BASE_OBJECT | FLAG_ATTR_NOT_REPLICATED
-
isSingleValued: TRUE
cn: Repl-Interval
@@ -12224,8 +12213,6 @@ isMemberOfPartialAttributeSet: TRUE systemFlags: FLAG_SCHEMA_BASE_OBJECT | FLAG_ATTR_IS_OPERATIONAL |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER | FLAG_ATTR_NOT_REPLICATED
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER | FLAG_ATTR_NOT_REPLICATED
-
cn: Repl-Topology-Stay-Of-Execution
ldapDisplayName: replTopologyStayOfExecution
attributeId: 1.2.840.113556.1.4.677
@@ -12872,7 +12859,6 @@ searchFlags: 0 rangeLower: 1
rangeUpper: 64
mapiID: 33072
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Next-Level-Store
@@ -12929,7 +12915,6 @@ searchFlags: 0 linkID: 95
systemFlags: FLAG_SCHEMA_BASE_OBJECT | FLAG_ATTR_NOT_REPLICATED
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-
isSingleValued: TRUE
cn: Server-Role
@@ -12942,7 +12927,6 @@ schemaIdGuid: bf967a33-0de6-11d0-a285-00aa003049e2 systemOnly: FALSE
searchFlags: 0
attributeSecurityGuid: b8119fd0-04f6-4762-ab7a-4986c76b3f9a
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Server-State
@@ -13235,7 +13219,6 @@ attributeSecurityGuid: 59ba2f42-79a2-11d0-9020-00c04fc2d3cf isMemberOfPartialAttributeSet: TRUE
systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-
systemOnly: TRUE
cn: Signature-Algorithms
@@ -13339,7 +13322,6 @@ isSingleValued: FALSE schemaIdGuid: 1be8f17c-a9ff-11d0-afe2-00c04fd930c9
systemOnly: FALSE
searchFlags: 0
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Surname
@@ -14442,7 +14424,6 @@ rangeUpper: 32768 attributeSecurityGuid: 77b5b886-944a-11d1-aebd-0000f80367c1
mapiID: 14960
isMemberOfPartialAttributeSet: TRUE
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: User-Workstations
@@ -14580,8 +14561,6 @@ isMemberOfPartialAttributeSet: TRUE systemFlags: FLAG_SCHEMA_BASE_OBJECT | FLAG_ATTR_IS_OPERATIONAL |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
-
cn: Version-Number
ldapDisplayName: versionNumber
attributeId: 1.2.840.113556.1.4.141
@@ -14708,8 +14687,6 @@ isMemberOfPartialAttributeSet: TRUE systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-systemFlags: FLAG_SCHEMA_BASE_OBJECT
-
cn: Organization-Name
ldapDisplayName: o
attributeId: 2.5.4.10
@@ -14892,7 +14869,6 @@ mapiID: 32807 isMemberOfPartialAttributeSet: TRUE
systemFlags: FLAG_SCHEMA_BASE_OBJECT |FLAG_ATTR_REQ_PARTIAL_SET_MEMBER
schemaFlagsEx: FLAG_ATTR_IS_CRITICAL
-
systemOnly: FALSE
cn: Object-Version
@@ -14971,7 +14947,6 @@ isSingleValued: TRUE schemaIdGuid: 07383076-91df-11d1-aebc-0000f80367c1
systemOnly: FALSE
searchFlags: 0
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: OMT-Indx-Guid
@@ -15099,7 +15074,6 @@ isSingleValued: TRUE schemaIdGuid: 0738307b-91df-11d1-aebc-0000f80367c1
systemOnly: FALSE
searchFlags: 0
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: organizationalStatus
@@ -15244,7 +15218,6 @@ isSingleValued: TRUE schemaIdGuid: 0738307a-91df-11d1-aebc-0000f80367c1
systemOnly: FALSE
searchFlags: 0
-
systemFlags: FLAG_SCHEMA_BASE_OBJECT
cn: Phone-Office-Other
diff --git a/source4/setup/ad-schema/MS-AD_Schema_Classes_v20080618.txt b/source4/setup/ad-schema/MS-AD_Schema_Classes_v20080618.txt index cd784edfc3..e2655d57da 100644 --- a/source4/setup/ad-schema/MS-AD_Schema_Classes_v20080618.txt +++ b/source4/setup/ad-schema/MS-AD_Schema_Classes_v20080618.txt @@ -277,20 +277,20 @@ subClassOf: top systemMustContain: msDS-MaximumPasswordAge, msDS-MinimumPasswordAge,msDS-MinimumPasswordLength, msDS-PasswordComplexityEnabled,msDS-LockoutObservationWindow, msDS-LockoutDuration,msDS-LockoutThreshold, msDS-PasswordReversibleEncryptionEnabled,msDS-PasswordSettingsPrecedence, msDS-PasswordHistoryLength
systemMayContain: msDS-PSOAppliesTo
systemPossSuperiors: msDS-PasswordSettingsContainer
-schemaIdGuid:: 3bcd9db8-f84b-451c-952f-6c52b81f9ec6
+schemaIdGuid: 3bcd9db8-f84b-451c-952f-6c52b81f9ec6
defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)
systemOnly: FALSE
defaultObjectCategory: CN=ms-DS-Password-Settings,CN=Schema,CN=Configuration,<RootDomainDN>
systemFlags: FLAG_SCHEMA_BASE_OBJECT
-cn: ms-DS-Password-Settings
+cn: ms-DS-Password-Settings-Container
ldapDisplayName: msDS-PasswordSettingsContainer
governsId: 1.2.840.113556.1.5.256
objectClassCategory: 1
rdnAttId: cn
subClassOf: top
systemPossSuperiors: Container
-schemaIdGuid:: 5b06b06a-4cf3-44c0-bd16-43bc10a987da
+schemaIdGuid: 5b06b06a-4cf3-44c0-bd16-43bc10a987da
defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)
systemOnly: FALSE
defaultObjectCategory: CN=ms-DS-Password-Settings-Container,CN=Schema,CN=Configuration,<RootDomainDN>
diff --git a/source4/setup/aggregate_schema.ldif b/source4/setup/aggregate_schema.ldif new file mode 100644 index 0000000000..2726704719 --- /dev/null +++ b/source4/setup/aggregate_schema.ldif @@ -0,0 +1,3 @@ +dn: CN=Aggregate,${SCHEMADN} +objectClass: top +objectClass: subSchema diff --git a/source4/setup/prefixMap.txt b/source4/setup/prefixMap.txt index 8ba9b9531c..267098000b 100644 --- a/source4/setup/prefixMap.txt +++ b/source4/setup/prefixMap.txt @@ -30,5 +30,12 @@ 29:1.3.6.1.4.1.250.1 30:1.2.840.113549.1.9 31:0.9.2342.19200300.100.4 -32:1.3.6.1.4.1.7165.4.1 -33:1.3.6.1.4.1.7165.4.2 +32:1.2.840.113556.1.6.23 +33:1.2.840.113556.1.6.18.1 +34:1.2.840.113556.1.6.18.2 +35:1.2.840.113556.1.6.13.3 +36:1.2.840.113556.1.6.13.4 +37:1.3.6.1.1.1.1 +38:1.3.6.1.1.1.2 +39:1.3.6.1.4.1.7165.4.1 +40:1.3.6.1.4.1.7165.4.2 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.ldif b/source4/setup/schema.ldif index 40ef709ac3..56eb7ce0c0 100644 --- a/source4/setup/schema.ldif +++ b/source4/setup/schema.ldif @@ -10373,6 +10373,3 @@ systemFlags: 16 defaultHidingValue: TRUE defaultObjectCategory: CN=Group-Policy-Container,${SCHEMADN} -dn: CN=Aggregate,${SCHEMADN} -objectClass: top -objectClass: subSchema 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; |