summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-11-05 17:04:10 +1100
committerAndrew Bartlett <abartlet@samba.org>2009-11-12 16:34:04 +1100
commitf0d43e9e562bfd7c254a9b2446fb11f85186b45e (patch)
tree08c4a939a51fa0625e3d99302eec1847f729ecb8
parent973197cd9ded571ff02996cb5c133435a35976c5 (diff)
downloadsamba-f0d43e9e562bfd7c254a9b2446fb11f85186b45e.tar.gz
samba-f0d43e9e562bfd7c254a9b2446fb11f85186b45e.tar.bz2
samba-f0d43e9e562bfd7c254a9b2446fb11f85186b45e.zip
s4:dsdb Use new dsdb_dn code in LDB modules and Samba4 schema
This converts the code from using the binary DN code in ldb_dn to using a special Samba-specfic wrapper around ldb_dn. We also use the dsdb_dn code for DN+Binary and DN+String comparisons (changed from treating them as Binary blobs) Andrew Bartlett
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_out.c36
-rw-r--r--source4/dsdb/samdb/ldb_modules/extended_dn_store.c81
-rw-r--r--source4/dsdb/schema/schema_syntax.c34
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.c12
4 files changed, 99 insertions, 64 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
index cbbf8c6078..c4ddf6781f 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
@@ -2,7 +2,7 @@
ldb database library
Copyright (C) Simo Sorce 2005-2008
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -420,21 +420,30 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
}
/* 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) {
+ if (dsdb_dn_oid_to_format(attribute->syntax->ldap_oid) == DSDB_INVALID_DN) {
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, ldb_module_get_ctx(ac->module), &msg->elements[i].values[j]);
- if (!dn || !ldb_dn_validate(dn)) {
+ struct ldb_dn *dn;
+ struct dsdb_dn *dsdb_dn = NULL;
+ struct ldb_val *plain_dn = &msg->elements[i].values[j];
+ dsdb_dn = dsdb_dn_parse(msg, ldb_module_get_ctx(ac->module), plain_dn, attribute->syntax->ldap_oid);
+
+ if (!dsdb_dn || !ldb_dn_validate(dsdb_dn->dn)) {
+ ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
+ "could not parse %.*s as a %s DN", (int)plain_dn->length, plain_dn->data,
+ attribute->syntax->ldap_oid);
+ talloc_free(dsdb_dn);
return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_INVALID_DN_SYNTAX);
}
+ dn = dsdb_dn->dn;
if (p->normalise) {
ret = fix_dn(dn);
if (ret != LDB_SUCCESS) {
+ talloc_free(dsdb_dn);
return ldb_module_done(ac->req, NULL, NULL, ret);
}
}
@@ -453,24 +462,26 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
msg->elements[i].name,
&msg->elements[i].values[j]);
if (ret != LDB_SUCCESS) {
+ talloc_free(dsdb_dn);
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));
+ dn_str = dsdb_dn_get_linearized(msg->elements[i].values,
+ dsdb_dn);
} else {
- dn_str = talloc_steal(msg->elements[i].values,
- ldb_dn_get_extended_linearized(msg->elements[i].values,
- dn, ac->extended_type));
+ dn_str = dsdb_dn_get_extended_linearized(msg->elements[i].values,
+ dsdb_dn, ac->extended_type);
}
+
if (!dn_str) {
ldb_oom(ldb_module_get_ctx(ac->module));
+ talloc_free(dsdb_dn);
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);
+ talloc_free(dsdb_dn);
}
}
return ldb_module_send_entry(ac->req, msg, ares->controls);
@@ -717,8 +728,7 @@ static int extended_dn_out_dereference_init(struct ldb_module *module, const cha
}
for (cur = schema->attributes; cur; cur = cur->next) {
- if (strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.1") != 0 &&
- strcmp(cur->syntax->attributeSyntax_oid, "2.5.5.7") != 0) {
+ if (dsdb_dn_oid_to_format(cur->syntax->ldap_oid) == DSDB_INVALID_DN) {
continue;
}
dereference_control->dereference
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
index 122a9bb2b7..ef8532c82a 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c
@@ -2,7 +2,7 @@
ldb database library
Copyright (C) Simo Sorce 2005-2008
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007-2009
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@
struct extended_dn_replace_list {
struct extended_dn_replace_list *next;
- struct ldb_dn *dn;
+ struct dsdb_dn *dsdb_dn;
TALLOC_CTX *mem_ctx;
struct ldb_val *replace_dn;
struct extended_dn_context *ac;
@@ -157,12 +157,20 @@ static int extended_replace_dn(struct ldb_request *req, struct ldb_reply *ares)
* 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));
+
+ /* Rebuild with the string or binary 'extra part' the
+ * DN may have had as a prefix */
+ struct dsdb_dn *dsdb_dn = dsdb_dn_construct(ares, dn,
+ os->dsdb_dn->extra_part,
+ os->dsdb_dn->oid);
+ if (dsdb_dn) {
+ /* Replace the DN with the extended version of the DN
+ * (ie, add SID and GUID) */
+ *os->replace_dn = data_blob_string_const(
+ dsdb_dn_get_extended_linearized(os->mem_ctx,
+ dsdb_dn, 1));
+ talloc_free(dsdb_dn);
+ }
if (os->replace_dn->data == NULL) {
return ldb_module_done(os->ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
@@ -209,7 +217,9 @@ static int extended_replace_dn(struct ldb_request *req, struct ldb_reply *ares)
static int extended_store_replace(struct extended_dn_context *ac,
TALLOC_CTX *callback_mem_ctx,
- struct ldb_val *plain_dn)
+ struct ldb_val *plain_dn,
+ bool is_delete,
+ const char *oid)
{
int ret;
struct extended_dn_replace_list *os;
@@ -228,14 +238,25 @@ static int extended_store_replace(struct extended_dn_context *ac,
os->mem_ctx = callback_mem_ctx;
- os->dn = ldb_dn_from_ldb_val(os, ldb_module_get_ctx(ac->module), plain_dn);
- if (!os->dn || !ldb_dn_validate(os->dn)) {
+ os->dsdb_dn = dsdb_dn_parse(os, ldb_module_get_ctx(ac->module), plain_dn, oid);
+ if (!os->dsdb_dn || !ldb_dn_validate(os->dsdb_dn->dn)) {
talloc_free(os);
ldb_asprintf_errstring(ldb_module_get_ctx(ac->module),
- "could not parse %.*s as a DN", (int)plain_dn->length, plain_dn->data);
+ "could not parse %.*s as a %s DN", (int)plain_dn->length, plain_dn->data,
+ oid);
return LDB_ERR_INVALID_DN_SYNTAX;
}
+ if (is_delete && !ldb_dn_has_extended(os->dsdb_dn->dn)) {
+ /* NO need to figure this DN out, this element is
+ * going to be deleted anyway, and becuase it's not
+ * extended, we have enough information to do the
+ * delete */
+ talloc_free(os);
+ return LDB_SUCCESS;
+ }
+
+
os->replace_dn = plain_dn;
/* The search request here might happen to be for an
@@ -243,7 +264,7 @@ static int extended_store_replace(struct extended_dn_context *ac,
* module in the stack will convert this into a normal DN for
* processing */
ret = ldb_build_search_req(&os->search_req,
- ldb_module_get_ctx(ac->module), os, os->dn, LDB_SCOPE_BASE, NULL,
+ ldb_module_get_ctx(ac->module), os, os->dsdb_dn->dn, LDB_SCOPE_BASE, NULL,
attrs, NULL, os, extended_replace_dn,
ac->req);
@@ -302,9 +323,8 @@ static int extended_dn_add(struct ldb_module *module, struct ldb_request *req)
continue;
}
- /* We only setup an extended DN GUID on these particular DN objects */
- if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 &&
- strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) {
+ /* We only setup an extended DN GUID on DN elements */
+ if (dsdb_dn_oid_to_format(schema_attr->syntax->ldap_oid) == DSDB_INVALID_DN) {
continue;
}
@@ -324,14 +344,15 @@ static int extended_dn_add(struct ldb_module *module, struct ldb_request *req)
/* 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]);
+ ret = extended_store_replace(ac, ac->new_req->op.add.message->elements, &el->values[j],
+ false, schema_attr->syntax->ldap_oid);
if (ret != LDB_SUCCESS) {
return ret;
}
}
}
- /* if DNs were set continue */
+ /* if no DNs were set continue */
if (ac->ops == NULL) {
talloc_free(ac);
return ldb_next_request(module, req);
@@ -377,11 +398,10 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req
}
/* We only setup an extended DN GUID on these particular DN objects */
- if (strcmp(schema_attr->attributeSyntax_oid, "2.5.5.1") != 0 &&
- strcmp(schema_attr->attributeSyntax_oid, "2.5.5.7") != 0) {
+ if (dsdb_dn_oid_to_format(schema_attr->syntax->ldap_oid) == DSDB_INVALID_DN) {
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);
@@ -399,17 +419,14 @@ static int extended_dn_modify(struct ldb_module *module, struct ldb_request *req
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, ldb_module_get_ctx(module), &el->values[j]);
- if (!dn || !ldb_dn_validate(dn)) {
- ldb_asprintf_errstring(ldb_module_get_ctx(module),
- "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 we are just going to delete this
+ * element, only do a lookup if
+ * extended_store_replace determines it's an
+ * input of an extended DN */
+ bool is_delete = ((el->flags & LDB_FLAG_MOD_MASK) == LDB_FLAG_MOD_DELETE);
+
+ ret = extended_store_replace(ac, req->op.mod.message->elements, &el->values[j],
+ is_delete, schema_attr->syntax->ldap_oid);
if (ret != LDB_SUCCESS) {
return ret;
}
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index 65baaeb070..d50044acd0 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -1229,6 +1229,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
enum ndr_err_code ndr_err;
DATA_BLOB guid_blob;
struct ldb_dn *dn;
+ struct dsdb_dn *dsdb_dn;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
@@ -1296,9 +1297,9 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
}
/* set binary stuff */
- ldb_dn_set_binary(dn, &id3.binary);
+ dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
- out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
+ out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
talloc_free(tmp_ctx);
}
@@ -1333,17 +1334,20 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
enum ndr_err_code ndr_err;
const DATA_BLOB *guid_blob, *sid_blob;
- struct ldb_dn *dn;
+ struct dsdb_dn *dsdb_dn;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
out->value_ctr.values[i].blob = &blobs[i];
- dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
+ dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
- W_ERROR_HAVE_NO_MEMORY(dn);
+ if (dsdb_dn) {
+ talloc_free(tmp_ctx);
+ return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
+ }
- guid_blob = ldb_dn_get_extended_component(dn, "GUID");
+ guid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "GUID");
ZERO_STRUCT(id3);
@@ -1358,7 +1362,7 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
}
}
- sid_blob = ldb_dn_get_extended_component(dn, "SID");
+ sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
if (sid_blob) {
ndr_err = ndr_pull_struct_blob_all(sid_blob,
@@ -1371,16 +1375,10 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
}
}
- id3.dn = ldb_dn_get_linearized(dn);
- if (strncmp(id3.dn, "B:", 2) == 0) {
- id3.dn = strchr(id3.dn, ':');
- id3.dn = strchr(id3.dn+1, ':');
- id3.dn = strchr(id3.dn+1, ':');
- id3.dn++;
- }
+ id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
/* get binary stuff */
- ldb_dn_get_binary(dn, &id3.binary);
+ id3.binary = dsdb_dn->extra_part;
ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -1661,7 +1659,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.comment = "Object(DS-DN) == a DN",
},{
.name = "Object(DN-Binary)",
- .ldap_oid = "1.2.840.113556.1.4.903",
+ .ldap_oid = DSDB_SYNTAX_BINARY_DN,
.oMSyntax = 127,
.oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
.attributeSyntax_oid = "2.5.5.7",
@@ -1669,7 +1667,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
.equality = "octetStringMatch",
.comment = "OctetString: Binary+DN",
- .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
},{
/* not used in w2k3 schema */
.name = "Object(OR-Name)",
@@ -1716,7 +1713,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
},{
/* not used in w2k3 schema */
.name = "Object(DN-String)",
- .ldap_oid = "1.2.840.113556.1.4.904",
+ .ldap_oid = DSDB_SYNTAX_STRING_DN,
.oMSyntax = 127,
.oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
.attributeSyntax_oid = "2.5.5.14",
@@ -1724,7 +1721,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
.equality = "octetStringMatch",
.comment = "OctetString: String+DN",
- .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
}
};
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c
index f716fa676e..f2c985e81a 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -810,6 +810,18 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
.ldif_write_fn = ldif_write_replUpToDateVector,
.canonicalise_fn = ldb_handler_copy,
.comparison_fn = ldb_comparison_binary
+ },{
+ .name = DSDB_SYNTAX_BINARY_DN,
+ .ldif_read_fn = ldb_handler_copy,
+ .ldif_write_fn = ldb_handler_copy,
+ .canonicalise_fn = dsdb_dn_binary_canonicalise,
+ .comparison_fn = dsdb_dn_binary_comparison
+ },{
+ .name = DSDB_SYNTAX_STRING_DN,
+ .ldif_read_fn = ldb_handler_copy,
+ .ldif_write_fn = ldb_handler_copy,
+ .canonicalise_fn = dsdb_dn_string_canonicalise,
+ .comparison_fn = dsdb_dn_string_comparison
},
};