summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamen Mazdrashki <kamen.mazdrashki@postpath.com>2009-10-11 21:00:55 +0300
committerAnatoliy Atanasov <anatoliy.atanasov@postpath.com>2009-10-16 12:54:14 +0300
commit40a8a2268454a55103c5c675d6fc07efa3cb6f31 (patch)
treeb8adb8aaeccda66052c2b0ef9cbb38d91c5889e9
parent7e8fb4ad06a3e2e5ae17b06299c7c4cd4e87012e (diff)
downloadsamba-40a8a2268454a55103c5c675d6fc07efa3cb6f31.tar.gz
samba-40a8a2268454a55103c5c675d6fc07efa3cb6f31.tar.bz2
samba-40a8a2268454a55103c5c675d6fc07efa3cb6f31.zip
s4/drs: Propagate redefinition of drsuapi_DsReplicaOID into code base
The biggest change is that 'oid' field is transmited in binary format. Also the field name is changed to 'binary_oid' so that field format to be clear for callers. After those changes, Samba4 should work the way it works before - i.e. no added value here but we should not fail when partial-oid is part of prefixMap transmited from Win server. Also, thre is a bug in this patch - partial-binary-OIDs are not handled correctly. Partial-binary-OIDs received during replication will be encoded, but not handled correctly.
-rw-r--r--source4/dsdb/schema/schema_init.c166
-rw-r--r--source4/lib/ldb-samba/ldif_handlers.c37
2 files changed, 134 insertions, 69 deletions
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 9dd3ce0ccc..f8b7d5dd44 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -29,6 +29,7 @@
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "param/param.h"
#include "lib/ldb/include/ldb_module.h"
+#include "../lib/util/asn1.h"
static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes);
@@ -52,11 +53,11 @@ WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct d
W_ERROR_HAVE_NO_MEMORY(schema->prefixes);
for (i=0, j=0; i < ctr->num_mappings; i++) {
- if (ctr->mappings[i].oid.oid == NULL) {
+ if (ctr->mappings[i].oid.binary_oid == NULL) {
return WERR_INVALID_PARAM;
}
- if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
+ if (ctr->mappings[i].oid.binary_oid[0] == 0xFF) {
if (ctr->mappings[i].id_prefix != 0) {
return WERR_INVALID_PARAM;
}
@@ -66,21 +67,33 @@ WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct d
return WERR_INVALID_PARAM;
}
- if (ctr->mappings[i].oid.__ndr_size != 21) {
+ if (ctr->mappings[i].oid.length != 21) {
return WERR_INVALID_PARAM;
}
- schema->schema_info = talloc_strdup(schema, ctr->mappings[i].oid.oid);
+ schema->schema_info = hex_encode_talloc(schema,
+ ctr->mappings[i].oid.binary_oid,
+ ctr->mappings[i].oid.length);
W_ERROR_HAVE_NO_MEMORY(schema->schema_info);
} else {
+ DATA_BLOB oid_blob;
+ const char *partial_oid = NULL;
+
/* the last array member should contain the magic value not a oid */
if (i == (ctr->num_mappings - 1)) {
return WERR_INVALID_PARAM;
}
+ oid_blob = data_blob_const(ctr->mappings[i].oid.binary_oid,
+ ctr->mappings[i].oid.length);
+ if (!ber_read_partial_OID_String(schema->prefixes, oid_blob, &partial_oid)) {
+ DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
+ ctr->mappings[i].id_prefix));
+ return WERR_INVALID_PARAM;
+ }
+
schema->prefixes[j].id = ctr->mappings[i].id_prefix<<16;
- schema->prefixes[j].oid = talloc_asprintf(schema->prefixes, "%s.",
- ctr->mappings[i].oid.oid);
+ schema->prefixes[j].oid = partial_oid;
W_ERROR_HAVE_NO_MEMORY(schema->prefixes[j].oid);
schema->prefixes[j].oid_len = strlen(schema->prefixes[j].oid);
j++;
@@ -98,7 +111,7 @@ WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema,
WERROR status;
enum ndr_err_code ndr_err;
struct prefixMapBlob pfm;
- char *schema_info;
+ DATA_BLOB schema_info_blob;
TALLOC_CTX *mem_ctx = talloc_new(schema);
W_ERROR_HAVE_NO_MEMORY(mem_ctx);
@@ -127,12 +140,12 @@ WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema,
pfm.ctr.dsdb.num_mappings);
W_ERROR_HAVE_NO_MEMORY(pfm.ctr.dsdb.mappings);
- schema_info = data_blob_hex_string(pfm.ctr.dsdb.mappings, schemaInfo);
- W_ERROR_HAVE_NO_MEMORY(schema_info);
+ schema_info_blob = data_blob_dup_talloc(pfm.ctr.dsdb.mappings, schemaInfo);
+ W_ERROR_HAVE_NO_MEMORY(schema_info_blob.data);
pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].id_prefix = 0;
- pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.__ndr_size = schemaInfo->length;
- pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.oid = schema_info;
+ pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.length = schemaInfo->length;
+ pfm.ctr.dsdb.mappings[pfm.ctr.dsdb.num_mappings - 1].oid.binary_oid = schema_info_blob.data;
/* call the drsuapi version */
status = dsdb_load_oid_mappings_drsuapi(schema, &pfm.ctr.dsdb);
@@ -148,6 +161,7 @@ WERROR dsdb_get_oid_mappings_drsuapi(const struct dsdb_schema *schema,
TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaOIDMapping_Ctr **_ctr)
{
+ DATA_BLOB oid_blob;
struct drsuapi_DsReplicaOIDMapping_Ctr *ctr;
uint32_t i;
@@ -160,18 +174,23 @@ WERROR dsdb_get_oid_mappings_drsuapi(const struct dsdb_schema *schema,
W_ERROR_HAVE_NO_MEMORY(ctr->mappings);
for (i=0; i < schema->num_prefixes; i++) {
+ if (!ber_write_partial_OID_String(ctr->mappings, &oid_blob, schema->prefixes[i].oid)) {
+ DEBUG(0, ("write_partial_OID failed for %s", schema->prefixes[i].oid));
+ return WERR_INTERNAL_ERROR;
+ }
+
ctr->mappings[i].id_prefix = schema->prefixes[i].id>>16;
- ctr->mappings[i].oid.oid = talloc_strndup(ctr->mappings,
- schema->prefixes[i].oid,
- schema->prefixes[i].oid_len - 1);
- W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid);
+ ctr->mappings[i].oid.length = oid_blob.length;
+ ctr->mappings[i].oid.binary_oid = oid_blob.data;
}
if (include_schema_info) {
+ oid_blob = strhex_to_data_blob(ctr->mappings, schema->schema_info);
+ W_ERROR_HAVE_NO_MEMORY(oid_blob.data);
+
ctr->mappings[i].id_prefix = 0;
- ctr->mappings[i].oid.oid = talloc_strdup(ctr->mappings,
- schema->schema_info);
- W_ERROR_HAVE_NO_MEMORY(ctr->mappings[i].oid.oid);
+ ctr->mappings[i].oid.length = oid_blob.length;
+ ctr->mappings[i].oid.binary_oid = oid_blob.data;
}
*_ctr = ctr;
@@ -211,13 +230,14 @@ WERROR dsdb_get_oid_mappings_ldb(const struct dsdb_schema *schema,
WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
{
uint32_t i,j;
+ DATA_BLOB oid_blob;
for (i=0; i < ctr->num_mappings; i++) {
- if (ctr->mappings[i].oid.oid == NULL) {
+ if (ctr->mappings[i].oid.binary_oid == NULL) {
return WERR_INVALID_PARAM;
}
- if (strncasecmp(ctr->mappings[i].oid.oid, "ff", 2) == 0) {
+ if (ctr->mappings[i].oid.binary_oid[0] == 0xFF) {
if (ctr->mappings[i].id_prefix != 0) {
return WERR_INVALID_PARAM;
}
@@ -227,13 +247,19 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const
return WERR_INVALID_PARAM;
}
- if (ctr->mappings[i].oid.__ndr_size != 21) {
+ if (ctr->mappings[i].oid.length != 21) {
return WERR_INVALID_PARAM;
}
- if (strcasecmp(schema->schema_info, ctr->mappings[i].oid.oid) != 0) {
+ oid_blob = strhex_to_data_blob(NULL, schema->schema_info);
+ W_ERROR_HAVE_NO_MEMORY(oid_blob.data);
+
+ if (memcmp(oid_blob.data, ctr->mappings[i].oid.binary_oid, 21) != 0) {
+ data_blob_free(&oid_blob);
return WERR_DS_DRA_SCHEMA_MISMATCH;
}
+
+ data_blob_free(&oid_blob);
} else {
/* the last array member should contain the magic value not a oid */
if (i == (ctr->num_mappings - 1)) {
@@ -241,21 +267,26 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const
}
for (j=0; j < schema->num_prefixes; j++) {
- size_t oid_len;
if (schema->prefixes[j].id != (ctr->mappings[i].id_prefix<<16)) {
continue;
}
- oid_len = strlen(ctr->mappings[i].oid.oid);
+ if (!ber_write_partial_OID_String(NULL, &oid_blob, schema->prefixes[j].oid)) {
+ return WERR_INTERNAL_ERROR;
+ }
- if (oid_len != (schema->prefixes[j].oid_len - 1)) {
+ if (oid_blob.length != ctr->mappings[j].oid.length) {
+ data_blob_free(&oid_blob);
return WERR_DS_DRA_SCHEMA_MISMATCH;
}
- if (strncmp(ctr->mappings[i].oid.oid, schema->prefixes[j].oid, oid_len) != 0) {
- return WERR_DS_DRA_SCHEMA_MISMATCH;
+ if (memcmp(ctr->mappings[i].oid.binary_oid, oid_blob.data, oid_blob.length) != 0) {
+ data_blob_free(&oid_blob);
+ return WERR_DS_DRA_SCHEMA_MISMATCH;
}
+ data_blob_free(&oid_blob);
+
break;
}
@@ -284,7 +315,7 @@ WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CT
continue;
}
- val = talloc_asprintf(mem_ctx, "%s%u",
+ val = talloc_asprintf(mem_ctx, "%s.%u",
schema->prefixes[i].oid,
in & 0xFFFF);
W_ERROR_HAVE_NO_MEMORY(val);
@@ -391,8 +422,6 @@ WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struc
DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n"));
return WERR_FOOBAR;
}
- /* Add one because we need to copy the dot */
- size += 1;
/* Create a spot in the prefixMap for one more prefix*/
(*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes);
@@ -412,37 +441,33 @@ WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struc
WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out)
{
uint32_t i;
+ char *oid_prefix;
+ char *pstr;
+ char *end_str;
+ unsigned val;
- for (i=0; i < num_prefixes; i++) {
- const char *val_str;
- char *end_str;
- unsigned val;
-
- if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) {
- continue;
- }
+ /* make oid prefix, i.e. oid w/o last subidentifier */
+ pstr = strrchr(in, '.');
+ if (!pstr) return WERR_INVALID_PARAM;
+ if (pstr < in) return WERR_INVALID_PARAM;
+ if ((pstr - in) < 4) return WERR_INVALID_PARAM;
- val_str = in + prefixes[i].oid_len;
- end_str = NULL;
- errno = 0;
+ oid_prefix = talloc_strndup(0, in, pstr - in);
- if (val_str[0] == '\0') {
- return WERR_INVALID_PARAM;
+ for (i=0; i < num_prefixes; i++) {
+ if (strcmp(prefixes[i].oid, oid_prefix) == 0) {
+ break;
}
+ }
- /* two '.' chars are invalid */
- if (val_str[0] == '.') {
- return WERR_INVALID_PARAM;
- }
+ talloc_free(oid_prefix);
- val = strtoul(val_str, &end_str, 10);
- if (end_str[0] == '.' && end_str[1] != '\0') {
- /*
- * if it's a '.' and not the last char
- * then maybe an other mapping apply
- */
- continue;
- } else if (end_str[0] != '\0') {
+ if (i < num_prefixes) {
+ /* move next to '.' char */
+ pstr++;
+
+ val = strtoul(pstr, &end_str, 10);
+ if (end_str[0] != '\0') {
return WERR_INVALID_PARAM;
} else if (val > 0xFFFF) {
return WERR_INVALID_PARAM;
@@ -489,8 +514,16 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co
}
for (i=0; i < schema->num_prefixes; i++) {
- pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16;
- pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, schema->prefixes[i].oid);
+ DATA_BLOB oid_blob;
+
+ if (!ber_write_partial_OID_String(pm.ctr.dsdb.mappings, &oid_blob, schema->prefixes[i].oid)) {
+ DEBUG(0, ("write_partial_OID failed for %s", schema->prefixes[i].oid));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ pm.ctr.dsdb.mappings[i].id_prefix = schema->prefixes[i].id>>16;
+ pm.ctr.dsdb.mappings[i].oid.length = oid_blob.length;
+ pm.ctr.dsdb.mappings[i].oid.binary_oid = oid_blob.data;
}
ndr_err = ndr_push_struct_blob(&ndr_blob, msg,
@@ -528,7 +561,7 @@ static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_contex
uint32_t i;
const struct ldb_val *prefix_val;
struct ldb_dn *schema_dn;
- struct ldb_result *schema_res;
+ struct ldb_result *schema_res = NULL;
int ret;
static const char *schema_attrs[] = {
"prefixMap",
@@ -588,10 +621,21 @@ static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_contex
return WERR_NOMEM;
}
for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
- char *oid;
+ DATA_BLOB oid_blob;
+ const char *partial_oid;
+
+ oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid,
+ blob->ctr.dsdb.mappings[i].oid.length);
+
+ if (!ber_read_partial_OID_String(mem_ctx, oid_blob, &partial_oid)) {
+ DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
+ blob->ctr.dsdb.mappings[i].id_prefix));
+ talloc_free(blob);
+ return WERR_INVALID_PARAM;
+ }
+
(*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16;
- oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid);
- (*prefixes)[i].oid = talloc_asprintf_append(oid, ".");
+ (*prefixes)[i].oid = partial_oid;
(*prefixes)[i].oid_len = strlen((*prefixes)[i].oid);
}
diff --git a/source4/lib/ldb-samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c
index 4d8af75a51..59f8622a37 100644
--- a/source4/lib/ldb-samba/ldif_handlers.c
+++ b/source4/lib/ldb-samba/ldif_handlers.c
@@ -33,6 +33,7 @@
#include "librpc/ndr/libndr.h"
#include "libcli/security/security.h"
#include "param/param.h"
+#include "../lib/util/asn1.h"
/*
use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob
@@ -507,6 +508,7 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
struct prefixMapBlob *blob;
enum ndr_err_code ndr_err;
char *string, *line, *p, *oid;
+ DATA_BLOB oid_blob;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
@@ -563,8 +565,12 @@ static int ldif_read_prefixMap(struct ldb_context *ldb, void *mem_ctx,
/* we know there must be at least ":" */
oid++;
- blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.oid
- = talloc_strdup(blob->ctr.dsdb.mappings, oid);
+ if (!ber_write_partial_OID_String(blob->ctr.dsdb.mappings, &oid_blob, oid)) {
+ talloc_free(tmp_ctx);
+ return -1;
+ }
+ blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.length = oid_blob.length;
+ blob->ctr.dsdb.mappings[blob->ctr.dsdb.num_mappings].oid.binary_oid = oid_blob.data;
blob->ctr.dsdb.num_mappings++;
@@ -615,32 +621,47 @@ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx,
blob,
(ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(blob);
- return -1;
+ goto failed;
}
if (blob->version != PREFIX_MAP_VERSION_DSDB) {
- return -1;
+ goto failed;
}
string = talloc_strdup(mem_ctx, "");
if (string == NULL) {
- return -1;
+ goto failed;
}
for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
+ DATA_BLOB oid_blob;
+ const char *partial_oid = NULL;
+
if (i > 0) {
string = talloc_asprintf_append(string, ";");
}
+
+ oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid,
+ blob->ctr.dsdb.mappings[i].oid.length);
+ if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) {
+ DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X",
+ blob->ctr.dsdb.mappings[i].id_prefix));
+ goto failed;
+ }
string = talloc_asprintf_append(string, "%u:%s",
blob->ctr.dsdb.mappings[i].id_prefix,
- blob->ctr.dsdb.mappings[i].oid.oid);
+ partial_oid);
+ talloc_free(discard_const(partial_oid));
if (string == NULL) {
- return -1;
+ goto failed;
}
}
talloc_free(blob);
*out = data_blob_string_const(string);
return 0;
+
+failed:
+ talloc_free(blob);
+ return -1;
}
static bool ldif_comparision_prefixMap_isString(const struct ldb_val *v)