From 027583e6de2a6981d1c0e8959e1e37bf758be8f9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Aug 2006 23:58:04 +0000 Subject: r17525: This is a merge from the Google Summer of Code 2006 project by Martin Kühl . MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Martin took over the work done last year by Jelmer, in last year's SoC. This was a substanital task, as the the ldb modules API changed significantly during the past year, with the addition of async calls. This changeset reimplements and enables the ldb_map ldb module and adapts the example module and test case, both named samba3sam, to the implementation. The ldb_map module supports splitting an ldb database into two parts (called the "local" and "remote" part) and storing the data in one of them (the remote database) in a different format while the other acts as a fallback. This allows ldb to e.g. store to and load data from a remote LDAP server and present it according to the Samba4 schema while still allowing the LDAP to present and modify its data separately. A complex example of this is the samba3sam module (by Jelmer Vernooij), which maps data between the samba3 and samba4 schemas. A simpler example is given by the entryUUID module (by Andrew Bartlett), which handles some of the differences between AD and OpenLDAP in operational attributes. It principally maps objectGUID, to and from entryUUID elements. This is also an example of a module that doesn't use the local backend as fallback storage. This merge also splits the ldb_map.c file into smaller, more manageable parts. (This used to be commit af2bece4d343a9f787b2e3628848b266cec2b9f0) --- source4/dsdb/samdb/ldb_modules/config.mk | 12 ++ source4/dsdb/samdb/ldb_modules/entryUUID.c | 182 +++++++++++++++++++++++++++++ source4/dsdb/samdb/ldb_modules/samba3sam.c | 35 +++++- 3 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 source4/dsdb/samdb/ldb_modules/entryUUID.c (limited to 'source4/dsdb/samdb') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 799d650ee7..6168a73d94 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -33,6 +33,18 @@ OBJ_FILES = \ # End MODULE ldb_samldb ################################################ +################################################ +# Start MODULE ldb_entryUUID +[MODULE::ldb_entryUUID] +SUBSYSTEM = ldb +INIT_FUNCTION = ldb_entryUUID_module_init +ENABLE = YES +OBJ_FILES = \ + entryUUID.o +# +# End MODULE ldb_entryUUID +################################################ + # ################################################ # # Start MODULE ldb_proxy # [MODULE::ldb_proxy] diff --git a/source4/dsdb/samdb/ldb_modules/entryUUID.c b/source4/dsdb/samdb/ldb_modules/entryUUID.c new file mode 100644 index 0000000000..5f7efc1681 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/entryUUID.c @@ -0,0 +1,182 @@ +/* + ldb database module + + LDAP semantics mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Andrew Bartlett 2006 + + 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 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This module relies on ldb_map to do all the real work, but performs + some of the trivial mappings between AD semantics and that provided + by OpenLDAP and similar servers. +*/ + +#include "includes.h" +#include "ldb/include/ldb.h" +#include "ldb/include/ldb_private.h" +#include "ldb/include/ldb_errors.h" +#include "ldb/modules/ldb_map.h" + +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/ndr/libndr.h" + +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); + struct ldb_val out = data_blob(NULL, 0); + + if (!NT_STATUS_IS_OK(status)) { + return out; + } + status = ndr_push_struct_blob(&out, ctx, &guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NT_STATUS_IS_OK(status)) { + return out; + } + + return out; +} + +static struct ldb_val decode_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val) +{ + struct GUID *guid; + NTSTATUS status; + struct ldb_val out = data_blob(NULL, 0); + + guid = talloc(ctx, struct GUID); + if (guid == NULL) { + return out; + } + status = ndr_pull_struct_blob(val, guid, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(guid); + return out; + } + out = data_blob_string_const(GUID_string(ctx, guid)); + talloc_free(guid); + return out; +} + +/* The backend holds binary sids, so just copy them back */ +static struct ldb_val sid_copy(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val) +{ + struct ldb_val out = data_blob(NULL, 0); + ldb_handler_copy(module->ldb, ctx, val, &out); + + return out; +} + +/* Ensure we always convert sids into binary, so the backend doesn't have to know about both forms */ +static struct ldb_val sid_always_binary(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val) +{ + struct ldb_val out = data_blob(NULL, 0); + const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, "objectSid"); + + if (handler->canonicalise_fn(module->ldb, ctx, val, &out) != LDB_SUCCESS) { + return data_blob(NULL, 0); + } + + return out; +} + +const struct ldb_map_attribute entryUUID_attributes[] = +{ + /* objectGUID */ + { + .local_name = "objectGUID", + .type = MAP_CONVERT, + .u = { + .convert = { + .remote_name = "entryUUID", + .convert_local = decode_guid, + .convert_remote = encode_guid, + }, + }, + }, + /* objectSid */ + { + .local_name = "objectSid", + .type = MAP_CONVERT, + .u = { + .convert = { + .remote_name = "objectSid", + .convert_local = sid_always_binary, + .convert_remote = sid_copy, + }, + }, + }, + { + .local_name = "whenCreated", + .type = MAP_RENAME, + .u = { + .rename = { + .remote_name = "createTimestamp" + } + } + }, + { + .local_name = "whenChanged", + .type = MAP_RENAME, + .u = { + .rename = { + .remote_name = "modifyTimestamp" + } + } + }, + { + .local_name = "*", + .type = MAP_KEEP, + }, + { + .local_name = NULL, + } +}; + +/* the context init function */ +static int entryUUID_init(struct ldb_module *module) +{ + int ret; + + ret = ldb_map_init(module, entryUUID_attributes, NULL, NULL); + if (ret != LDB_SUCCESS) + return ret; + + return ldb_next_init(module); +} + +static struct ldb_module_ops entryUUID_ops = { + .name = "entryUUID", + .init_context = entryUUID_init, +}; + +/* the init function */ +int ldb_entryUUID_module_init(void) +{ + struct ldb_module_ops ops = ldb_map_get_ops(); + entryUUID_ops.add = ops.add; + entryUUID_ops.modify = ops.modify; + entryUUID_ops.del = ops.del; + entryUUID_ops.rename = ops.rename; + entryUUID_ops.search = ops.search; + entryUUID_ops.wait = ops.wait; + + return ldb_register_module(&entryUUID_ops); +} diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c index 80cedb7b08..670d9ef0d8 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sam.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c @@ -5,11 +5,17 @@ */ #include "includes.h" -#include "ldb/modules/ldb_map.h" #include "ldb/include/ldb.h" #include "ldb/include/ldb_private.h" +#include "ldb/include/ldb_errors.h" +#include "ldb/modules/ldb_map.h" #include "system/passwd.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/ndr/libndr.h" +#include "libcli/security/security.h" +#include "libcli/security/proto.h" + /* * sambaSID -> member (dn!) * sambaSIDList -> member (dn!) @@ -855,8 +861,33 @@ const struct ldb_map_attribute samba3_attributes[] = } }; +/* the context init function */ +static int samba3sam_init(struct ldb_module *module) +{ + int ret; + + ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, "samba3sam"); + if (ret != LDB_SUCCESS) + return ret; + + return ldb_next_init(module); +} + +static struct ldb_module_ops samba3sam_ops = { + .name = "samba3sam", + .init_context = samba3sam_init, +}; + /* the init function */ int ldb_samba3sam_module_init(void) { - return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, "samba3sam"); + struct ldb_module_ops ops = ldb_map_get_ops(); + samba3sam_ops.add = ops.add; + samba3sam_ops.modify = ops.modify; + samba3sam_ops.del = ops.del; + samba3sam_ops.rename = ops.rename; + samba3sam_ops.search = ops.search; + samba3sam_ops.wait = ops.wait; + + return ldb_register_module(&samba3sam_ops); } -- cgit