summaryrefslogtreecommitdiff
path: root/source4/dsdb/schema
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/schema')
-rw-r--r--source4/dsdb/schema/prefixmap.h45
-rw-r--r--source4/dsdb/schema/schema.h1
-rw-r--r--source4/dsdb/schema/schema_inferiors.c47
-rw-r--r--source4/dsdb/schema/schema_init.c281
-rw-r--r--source4/dsdb/schema/schema_prefixmap.c22
-rw-r--r--source4/dsdb/schema/schema_set.c5
-rw-r--r--source4/dsdb/schema/schema_syntax.c136
7 files changed, 335 insertions, 202 deletions
diff --git a/source4/dsdb/schema/prefixmap.h b/source4/dsdb/schema/prefixmap.h
new file mode 100644
index 0000000000..7b28c88749
--- /dev/null
+++ b/source4/dsdb/schema/prefixmap.h
@@ -0,0 +1,45 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ DRS::prefixMap data structures
+
+ Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 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
+ 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,
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _DSDB_PREFIXMAP_H
+#define _DSDB_PREFIXMAP_H
+
+/**
+ * oid-prefix in prefixmap
+ */
+struct dsdb_schema_prefixmap_oid {
+ uint32_t id;
+ DATA_BLOB *bin_oid; /* partial binary-oid prefix */
+};
+
+/**
+ * DSDB prefixMap internal presentation
+ */
+struct dsdb_schema_prefixmap {
+ uint32_t length;
+ struct dsdb_schema_prefixmap_oid *prefixes;
+};
+
+
+#include "dsdb/schema/proto.h"
+
+
+#endif /* _DSDB_PREFIXMAP_H */
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 4e7e503931..ddd9b375f6 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -119,6 +119,7 @@ struct dsdb_class {
const char **mustContain;
const char **mayContain;
const char **possibleInferiors;
+ const char **systemPossibleInferiors;
const char *defaultSecurityDescriptor;
diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c
index b02d557c58..ecac74a954 100644
--- a/source4/dsdb/schema/schema_inferiors.c
+++ b/source4/dsdb/schema/schema_inferiors.c
@@ -149,19 +149,22 @@ void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_cla
return;
}
-static void schema_create_subclasses(struct dsdb_schema *schema)
+static int schema_create_subclasses(struct dsdb_schema *schema)
{
- struct dsdb_class *schema_class;
+ struct dsdb_class *schema_class, *top;
for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
if (schema_class2 == NULL) {
DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName));
- continue;
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (schema_class2 && schema_class != schema_class2) {
if (schema_class2->subclasses_direct == NULL) {
schema_class2->subclasses_direct = str_list_make_empty(schema_class2);
+ if (!schema_class2->subclasses_direct) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,
schema_class->lDAPDisplayName);
@@ -175,7 +178,14 @@ static void schema_create_subclasses(struct dsdb_schema *schema)
schema_class->subClass_order = 0;
}
- schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1);
+ top = dsdb_class_by_lDAPDisplayName(schema, "top");
+ if (!top) {
+ DEBUG(0,("ERROR: no 'top' class in loaded schema\n"));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ schema_subclasses_order_recurse(schema, top, 1);
+ return LDB_SUCCESS;
}
static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
@@ -198,6 +208,25 @@ static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct ds
schema_class->possibleInferiors = str_list_unique(schema_class->possibleInferiors);
}
+static void schema_fill_system_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
+{
+ struct dsdb_class *c2;
+
+ for (c2=schema->classes; c2; c2=c2->next) {
+ char **superiors = schema_posssuperiors(schema, c2);
+ if (c2->objectClassCategory != 2
+ && c2->objectClassCategory != 3
+ && str_list_check(superiors, schema_class->lDAPDisplayName)) {
+ if (schema_class->systemPossibleInferiors == NULL) {
+ schema_class->systemPossibleInferiors = str_list_make_empty(schema_class);
+ }
+ schema_class->systemPossibleInferiors = str_list_add_const(schema_class->systemPossibleInferiors,
+ c2->lDAPDisplayName);
+ }
+ }
+ schema_class->systemPossibleInferiors = str_list_unique(schema_class->systemPossibleInferiors);
+}
+
/*
fill in a string class name from a governs_ID
*/
@@ -275,16 +304,21 @@ static void schema_fill_from_ids(struct dsdb_schema *schema)
}
}
-void schema_fill_constructed(struct dsdb_schema *schema)
+int schema_fill_constructed(struct dsdb_schema *schema)
{
+ int ret;
struct dsdb_class *schema_class;
schema_fill_from_ids(schema);
- schema_create_subclasses(schema);
+ ret = schema_create_subclasses(schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
schema_fill_possible_inferiors(schema, schema_class);
+ schema_fill_system_possible_inferiors(schema, schema_class);
}
/* free up our internal cache elements */
@@ -298,4 +332,5 @@ void schema_fill_constructed(struct dsdb_schema *schema)
schema_class->subclasses = NULL;
schema_class->posssuperiors = NULL;
}
+ return LDB_SUCCESS;
}
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;
diff --git a/source4/dsdb/schema/schema_prefixmap.c b/source4/dsdb/schema/schema_prefixmap.c
new file mode 100644
index 0000000000..d24c5add00
--- /dev/null
+++ b/source4/dsdb/schema/schema_prefixmap.c
@@ -0,0 +1,22 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ DRS::prefixMap implementation
+
+ Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 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
+ 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,
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 6f09f63596..9f22b32334 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -346,7 +346,10 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
return ret;
}
- schema_fill_constructed(schema);
+ ret = schema_fill_constructed(schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index c564471d4b..cbbd4a8636 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -1204,6 +1204,8 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
return WERR_OK;
}
+
+
static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
const struct dsdb_schema *schema,
const struct dsdb_attribute *attr,
@@ -1212,6 +1214,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
struct ldb_message_element *out)
{
uint32_t i;
+ int ret;
out->flags = 0;
out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
@@ -1222,39 +1225,81 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
W_ERROR_HAVE_NO_MEMORY(out->values);
for (i=0; i < out->num_values; i++) {
- struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
- char *binary;
- char *str;
+ struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
enum ndr_err_code ndr_err;
+ DATA_BLOB guid_blob;
+ struct ldb_dn *dn;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+ }
if (in->value_ctr.values[i].blob == NULL) {
+ talloc_free(tmp_ctx);
return WERR_FOOBAR;
}
if (in->value_ctr.values[i].blob->length == 0) {
+ talloc_free(tmp_ctx);
return WERR_FOOBAR;
}
- ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
- out->values, schema->iconv_convenience, &id3b,
- (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
+
+ /* windows sometimes sends an extra two pad bytes here */
+ ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
+ tmp_ctx, schema->iconv_convenience, &id3,
+ (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
return ntstatus_to_werror(status);
}
- /* TODO: handle id3.guid and id3.sid */
- binary = data_blob_hex_string(out->values, &id3b.binary);
- W_ERROR_HAVE_NO_MEMORY(binary);
+ dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
+ if (!dn) {
+ talloc_free(tmp_ctx);
+ /* If this fails, it must be out of memory, as it does not do much parsing */
+ W_ERROR_HAVE_NO_MEMORY(dn);
+ }
- str = talloc_asprintf(out->values, "B:%u:%s:%s",
- (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
- binary,
- id3b.dn);
- W_ERROR_HAVE_NO_MEMORY(str);
+ ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
+ return ntstatus_to_werror(status);
+ }
- /* TODO: handle id3.guid and id3.sid */
- out->values[i] = data_blob_string_const(str);
+ ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return WERR_FOOBAR;
+ }
+
+ talloc_free(guid_blob.data);
+
+ if (id3.__ndr_size_sid) {
+ DATA_BLOB sid_blob;
+ ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
+ (ndr_push_flags_fn_t)ndr_push_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
+ return ntstatus_to_werror(status);
+ }
+
+ ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return WERR_FOOBAR;
+ }
+ }
+
+ /* set binary stuff */
+ ldb_dn_set_binary(dn, &id3.binary);
+
+ out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
+ talloc_free(tmp_ctx);
}
return WERR_OK;
@@ -1285,27 +1330,72 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
W_ERROR_HAVE_NO_MEMORY(blobs);
for (i=0; i < in->num_values; i++) {
- struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
+ struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
enum ndr_err_code ndr_err;
+ const DATA_BLOB *guid_blob, *sid_blob;
+ struct ldb_dn *dn;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
out->value_ctr.values[i].blob = &blobs[i];
- /* TODO: handle id3b.guid and id3b.sid, id3.binary */
- ZERO_STRUCT(id3b);
- id3b.dn = (const char *)in->values[i].data;
- id3b.binary = data_blob(NULL, 0);
+ dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
+
+ W_ERROR_HAVE_NO_MEMORY(dn);
+
+ guid_blob = ldb_dn_get_extended_component(dn, "GUID");
- ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
- (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
+ ZERO_STRUCT(id3);
+
+ if (guid_blob) {
+ ndr_err = ndr_pull_struct_blob_all(guid_blob,
+ tmp_ctx, schema->iconv_convenience, &id3.guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
+ return ntstatus_to_werror(status);
+ }
+ }
+
+ sid_blob = ldb_dn_get_extended_component(dn, "SID");
+ if (sid_blob) {
+
+ ndr_err = ndr_pull_struct_blob_all(sid_blob,
+ tmp_ctx, schema->iconv_convenience, &id3.sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
+ return ntstatus_to_werror(status);
+ }
+ }
+
+ 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++;
+ }
+
+ /* get binary stuff */
+ ldb_dn_get_binary(dn, &id3.binary);
+
+ 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)) {
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+ talloc_free(tmp_ctx);
return ntstatus_to_werror(status);
}
+ talloc_free(tmp_ctx);
}
return WERR_OK;
}
+
+
static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
const struct dsdb_schema *schema,
const struct dsdb_attribute *attr,