diff options
Diffstat (limited to 'source4/dsdb/schema/schema_init.c')
-rw-r--r-- | source4/dsdb/schema/schema_init.c | 281 |
1 files changed, 109 insertions, 172 deletions
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index b876ab09fc..f8b7d5dd44 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -29,6 +29,9 @@ #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); struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) { @@ -50,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; } @@ -64,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++; @@ -96,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); @@ -125,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); @@ -146,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; @@ -158,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; @@ -209,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; } @@ -225,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)) { @@ -239,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; } @@ -282,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); @@ -389,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); @@ -410,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; + /* 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; - if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) { - continue; - } + oid_prefix = talloc_strndup(0, in, pstr - in); - val_str = in + prefixes[i].oid_len; - end_str = NULL; - errno = 0; - - 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; @@ -487,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, @@ -519,14 +554,14 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co return WERR_OK; } -WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes) +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) { struct prefixMapBlob *blob; enum ndr_err_code ndr_err; 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", @@ -586,10 +621,21 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 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); } @@ -906,7 +952,7 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema, /* Create a DSDB schema from the ldb results provided. This is called directly when the schema is provisioned from an on-disk LDIF file, or - from dsdb_schema_from_schema_dn below + from dsdb_schema_from_schema_dn in schema_fsmo */ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, @@ -1013,115 +1059,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, return LDB_SUCCESS; } -/* - Given an LDB, and the DN, return a populated schema -*/ - -int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, - struct smb_iconv_convenience *iconv_convenience, - struct ldb_dn *schema_dn, - struct dsdb_schema **schema, - char **error_string_out) -{ - TALLOC_CTX *tmp_ctx; - char *error_string; - int ret; - - struct ldb_result *schema_res; - struct ldb_result *a_res; - struct ldb_result *c_res; - static const char *schema_attrs[] = { - "prefixMap", - "schemaInfo", - "fSMORoleOwner", - NULL - }; - unsigned flags; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) { - dsdb_oom(error_string_out, mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* we don't want to trace the schema load */ - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING); - - /* - * setup the prefix mappings and schema info - */ - ret = ldb_search(ldb, tmp_ctx, &schema_res, - schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } else if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search the schema head: %s", - ldb_errstring(ldb)); - goto failed; - } - if (schema_res->count != 1) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: [%u] schema heads found on a base search", - schema_res->count); - goto failed; - } - - /* - * load the attribute definitions - */ - ret = ldb_search(ldb, tmp_ctx, &a_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=attributeSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - /* - * load the objectClass definitions - */ - ret = ldb_search(ldb, tmp_ctx, &c_res, - schema_dn, LDB_SCOPE_ONELEVEL, NULL, - "(objectClass=classSchema)"); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema: failed to search attributeSchema objects: %s", - ldb_errstring(ldb)); - goto failed; - } - - ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb, - lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")), - schema_res, a_res, c_res, schema, &error_string); - if (ret != LDB_SUCCESS) { - *error_string_out = talloc_asprintf(mem_ctx, - "dsdb_schema load failed: %s", - error_string); - goto failed; - } - talloc_steal(mem_ctx, *schema); - talloc_free(tmp_ctx); - - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - - return LDB_SUCCESS; - -failed: - if (flags & LDB_FLG_ENABLE_TRACING) { - flags = ldb_get_flags(ldb); - ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING); - } - talloc_free(tmp_ctx); - return ret; -} - static const struct { const char *name; |