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
+ 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,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_private.h"
#include "ldb/include/ldb_errors.h"
-#include "ldb/modules/ldb_map.h"
+#include "ldb/ldb_map/ldb_map.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/ndr/libndr.h"
return out;
}
+static struct ldb_val encode_ns_guid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ struct GUID guid;
+ NTSTATUS status = NS_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 guid_ns_string(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ NTSTATUS status;
+ 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 {
+ struct GUID *guid_p;
+ guid_p = talloc(ctx, struct GUID);
+ if (guid_p == NULL) {
+ return out;
+ }
+ status = ndr_pull_struct_blob(val, guid_p, guid_p,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(guid_p);
+ return out;
+ }
+ out = data_blob_string_const(NS_GUID_string(ctx, guid_p));
+ talloc_free(guid_p);
+ }
+ return out;
+}
+
/* The backend holds binary sids, so just copy them back */
static struct ldb_val val_copy(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
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) {
+ const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(module->ldb, "objectSid");
+
+ if (a->syntax->canonicalise_fn(module->ldb, ctx, val, &out) != LDB_SUCCESS) {
return data_blob(NULL, 0);
}
}
-const struct ldb_map_attribute entryUUID_attributes[] =
+static const struct ldb_map_attribute entryUUID_attributes[] =
{
/* objectGUID */
{
},
},
},
+ /* invocationId */
+ {
+ .local_name = "invocationId",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "invocationId",
+ .convert_local = guid_always_string,
+ .convert_remote = encode_guid,
+ },
+ },
+ },
/* objectSid */
{
.local_name = "objectSid",
}
}
},
+ {
+ .local_name = "objectClasses",
+ .type = MAP_RENAME,
+ .u = {
+ .rename = {
+ .remote_name = "samba4ObjectClasses"
+ }
+ }
+ },
+ {
+ .local_name = "dITContentRules",
+ .type = MAP_RENAME,
+ .u = {
+ .rename = {
+ .remote_name = "samba4DITContentRules"
+ }
+ }
+ },
+ {
+ .local_name = "attributeTypes",
+ .type = MAP_RENAME,
+ .u = {
+ .rename = {
+ .remote_name = "samba4AttributeTypes"
+ }
+ }
+ },
{
.local_name = "sambaPassword",
.type = MAP_RENAME,
}
}
},
+#if 0
{
.local_name = "allowedChildClassesEffective",
.type = MAP_CONVERT,
},
},
},
+#endif
{
.local_name = "objectCategory",
.type = MAP_CONVERT,
}
};
+/* This objectClass conflicts with builtin classes on OpenLDAP */
+const struct ldb_map_objectclass entryUUID_objectclasses[] =
+{
+ {
+ .local_name = "subSchema",
+ .remote_name = "samba4SubSchema"
+ },
+ {
+ .local_name = NULL
+ }
+};
+
/* These things do not show up in wildcard searches in OpenLDAP, but
* we need them to show up in the AD-like view */
-const char * const wildcard_attributes[] = {
+static const char * const entryUUID_wildcard_attributes[] = {
+ "objectGUID",
+ "whenCreated",
+ "whenChanged",
+ "usnCreated",
+ "usnChanged",
+ NULL
+};
+
+static const struct ldb_map_attribute nsuniqueid_attributes[] =
+{
+ /* objectGUID */
+ {
+ .local_name = "objectGUID",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "nsuniqueid",
+ .convert_local = guid_ns_string,
+ .convert_remote = encode_ns_guid,
+ },
+ },
+ },
+ /* objectSid */
+ {
+ .local_name = "objectSid",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "objectSid",
+ .convert_local = sid_always_binary,
+ .convert_remote = val_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 = "sambaPassword",
+ .type = MAP_RENAME,
+ .u = {
+ .rename = {
+ .remote_name = "userPassword"
+ }
+ }
+ },
+#if 0
+ {
+ .local_name = "allowedChildClassesEffective",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "allowedChildClassesEffective",
+ .convert_local = class_to_oid,
+ .convert_remote = class_from_oid,
+ },
+ },
+ },
+#endif
+ {
+ .local_name = "objectCategory",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "objectCategory",
+ .convert_local = objectCategory_always_dn,
+ .convert_remote = val_copy,
+ },
+ },
+ },
+ {
+ .local_name = "distinguishedName",
+ .type = MAP_RENAME,
+ .u = {
+ .rename = {
+ .remote_name = "entryDN"
+ }
+ }
+ },
+ {
+ .local_name = "groupType",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "groupType",
+ .convert_local = normalise_to_signed32,
+ .convert_remote = val_copy,
+ },
+ }
+ },
+ {
+ .local_name = "sAMAccountType",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "sAMAccountType",
+ .convert_local = normalise_to_signed32,
+ .convert_remote = val_copy,
+ },
+ }
+ },
+ {
+ .local_name = "usnChanged",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "modifyTimestamp",
+ .convert_local = usn_to_timestamp,
+ .convert_remote = timestamp_to_usn,
+ },
+ },
+ },
+ {
+ .local_name = "usnCreated",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "createTimestamp",
+ .convert_local = usn_to_timestamp,
+ .convert_remote = timestamp_to_usn,
+ },
+ },
+ },
+ {
+ .local_name = "*",
+ .type = MAP_KEEP,
+ },
+ {
+ .local_name = NULL,
+ }
+};
+
+/* These things do not show up in wildcard searches in OpenLDAP, but
+ * we need them to show up in the AD-like view */
+static const char * const nsuniqueid_wildcard_attributes[] = {
"objectGUID",
"whenCreated",
"whenChanged",
struct entryUUID_private *entryUUID_private;
struct ldb_dn *schema_dn;
- ret = ldb_map_init(module, entryUUID_attributes, NULL, wildcard_attributes, NULL);
+ ret = ldb_map_init(module, entryUUID_attributes, entryUUID_objectclasses, entryUUID_wildcard_attributes, NULL);
if (ret != LDB_SUCCESS)
return ret;
ret = fetch_objectclass_schema(module->ldb, schema_dn, entryUUID_private,
&entryUUID_private->objectclass_res);
if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(module->ldb, "Failed to fetch objectClass schema elements: %s\n", ldb_errstring(module->ldb));
- return ret;
+ /* Perhaps no schema yet */
+ return LDB_SUCCESS;
+ }
+
+ ret = find_base_dns(module, entryUUID_private);
+
+ return ldb_next_init(module);
+}
+
+/* the context init function */
+static int nsuniqueid_init(struct ldb_module *module)
+{
+ int ret;
+ struct map_private *map_private;
+ struct entryUUID_private *entryUUID_private;
+ struct ldb_dn *schema_dn;
+
+ ret = ldb_map_init(module, nsuniqueid_attributes, NULL, nsuniqueid_wildcard_attributes, NULL);
+ if (ret != LDB_SUCCESS)
+ return ret;
+
+ map_private = talloc_get_type(module->private_data, struct map_private);
+
+ entryUUID_private = talloc_zero(map_private, struct entryUUID_private);
+ map_private->caller_private = entryUUID_private;
+
+ schema_dn = find_schema_dn(module->ldb, map_private);
+ if (!schema_dn) {
+ /* Perhaps no schema yet */
+ return LDB_SUCCESS;
+ }
+
+ ret = fetch_objectclass_schema(module->ldb, schema_dn, entryUUID_private,
+ &entryUUID_private->objectclass_res);
+ if (ret != LDB_SUCCESS) {
+ /* Perhaps no schema yet */
+ return LDB_SUCCESS;
}
ret = find_base_dns(module, entryUUID_private);
.sequence_number = entryUUID_sequence_number
};
+static struct ldb_module_ops nsuniqueid_ops = {
+ .name = "nsuniqueid",
+ .init_context = nsuniqueid_init,
+ .sequence_number = entryUUID_sequence_number
+};
+
/* the init function */
int ldb_entryUUID_module_init(void)
{
+ int ret;
struct ldb_module_ops ops = ldb_map_get_ops();
entryUUID_ops.add = ops.add;
entryUUID_ops.modify = ops.modify;
entryUUID_ops.rename = ops.rename;
entryUUID_ops.search = ops.search;
entryUUID_ops.wait = ops.wait;
- return ldb_register_module(&entryUUID_ops);
+ ret = ldb_register_module(&entryUUID_ops);
+
+ if (ret) {
+ return ret;
+ }
+
+ nsuniqueid_ops.add = ops.add;
+ nsuniqueid_ops.modify = ops.modify;
+ nsuniqueid_ops.del = ops.del;
+ nsuniqueid_ops.rename = ops.rename;
+ nsuniqueid_ops.search = ops.search;
+ nsuniqueid_ops.wait = ops.wait;
+ ret = ldb_register_module(&nsuniqueid_ops);
+
+ return ret;
}