s4-torture: Test for #9058
[Samba/gebeck_regimport.git] / source4 / dsdb / schema / schema_info_attr.c
blobe113033a52a7c295e67b4f6ff6b016fdb36082ad
1 /*
2 Unix SMB/CIFS implementation.
4 SCHEMA::schemaInfo implementation
6 Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "dsdb/common/util.h"
24 #include "dsdb/samdb/samdb.h"
25 #include "dsdb/samdb/ldb_modules/util.h"
26 #include <ldb_module.h>
27 #include "librpc/gen_ndr/ndr_drsuapi.h"
28 #include "librpc/gen_ndr/ndr_drsblobs.h"
29 #include "param/param.h"
32 /**
33 * Creates and initializes new dsdb_schema_info value.
34 * Initial schemaInfo values is with:
35 * revision = 0
36 * invocationId = GUID_ZERO
38 WERROR dsdb_schema_info_new(TALLOC_CTX *mem_ctx, struct dsdb_schema_info **_schema_info)
40 struct dsdb_schema_info *schema_info;
42 schema_info = talloc_zero(mem_ctx, struct dsdb_schema_info);
43 W_ERROR_HAVE_NO_MEMORY(schema_info);
45 *_schema_info = schema_info;
47 return WERR_OK;
50 /**
51 * Creates and initializes new dsdb_schema_info blob value.
52 * Initial schemaInfo values is with:
53 * revision = 0
54 * invocationId = GUID_ZERO
56 WERROR dsdb_schema_info_blob_new(TALLOC_CTX *mem_ctx, DATA_BLOB *_schema_info_blob)
58 DATA_BLOB blob;
60 blob = data_blob_talloc_zero(mem_ctx, 21);
61 W_ERROR_HAVE_NO_MEMORY(blob.data);
63 /* Set the schemaInfo marker to 0xFF */
64 blob.data[0] = 0xFF;
66 *_schema_info_blob = blob;
68 return WERR_OK;
72 /**
73 * Verify the 'blob' is a valid schemaInfo blob
75 bool dsdb_schema_info_blob_is_valid(const DATA_BLOB *blob)
77 if (!blob || !blob->data) {
78 return false;
81 /* schemaInfo blob must be 21 bytes long */
82 if (blob->length != 21) {
83 return false;
86 /* schemaInfo blob should start with 0xFF */
87 if (blob->data[0] != 0xFF) {
88 return false;
91 return true;
94 /**
95 * Parse schemaInfo structure from a data_blob
96 * (DATA_BLOB or ldb_val).
97 * Suitable for parsing blobs that comes from
98 * DRS interface of from LDB database
100 WERROR dsdb_schema_info_from_blob(const DATA_BLOB *blob,
101 TALLOC_CTX *mem_ctx, struct dsdb_schema_info **_schema_info)
103 TALLOC_CTX *temp_ctx;
104 enum ndr_err_code ndr_err;
105 struct dsdb_schema_info *schema_info;
106 struct schemaInfoBlob schema_info_blob;
108 /* verify schemaInfo blob is valid */
109 if (!dsdb_schema_info_blob_is_valid(blob)) {
110 return WERR_INVALID_PARAMETER;
113 temp_ctx = talloc_new(mem_ctx);
114 W_ERROR_HAVE_NO_MEMORY(temp_ctx);
116 ndr_err = ndr_pull_struct_blob_all(blob, temp_ctx,
117 &schema_info_blob,
118 (ndr_pull_flags_fn_t)ndr_pull_schemaInfoBlob);
119 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
120 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
121 talloc_free(temp_ctx);
122 return ntstatus_to_werror(nt_status);
125 schema_info = talloc(mem_ctx, struct dsdb_schema_info);
126 if (!schema_info) {
127 talloc_free(temp_ctx);
128 return WERR_NOMEM;
131 /* note that we accept revision numbers of zero now - w2k8r2
132 sends a revision of zero on initial vampire */
133 schema_info->revision = schema_info_blob.revision;
134 schema_info->invocation_id = schema_info_blob.invocation_id;
135 *_schema_info = schema_info;
137 talloc_free(temp_ctx);
138 return WERR_OK;
142 * Creates a blob from schemaInfo structure
143 * Suitable for packing schemaInfo into a blob
144 * which is to be used in DRS interface of LDB database
146 WERROR dsdb_blob_from_schema_info(const struct dsdb_schema_info *schema_info,
147 TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
149 enum ndr_err_code ndr_err;
150 struct schemaInfoBlob schema_info_blob;
152 schema_info_blob.marker = 0xFF;
153 schema_info_blob.revision = schema_info->revision;
154 schema_info_blob.invocation_id = schema_info->invocation_id;
156 ndr_err = ndr_push_struct_blob(blob, mem_ctx,
157 &schema_info_blob,
158 (ndr_push_flags_fn_t)ndr_push_schemaInfoBlob);
159 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
160 NTSTATUS nt_status = ndr_map_error2ntstatus(ndr_err);
161 return ntstatus_to_werror(nt_status);
164 return WERR_OK;
168 * Compares schemaInfo signatures in dsdb_schema and prefixMap.
169 * NOTE: At present function compares schemaInfo values
170 * as string without taking into account schemVersion field
172 * @return WERR_OK if schemaInfos are equal
173 * WERR_DS_DRA_SCHEMA_MISMATCH if schemaInfos are different
175 WERROR dsdb_schema_info_cmp(const struct dsdb_schema *schema,
176 const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
178 bool bres;
179 DATA_BLOB blob;
180 char *schema_info_str;
181 struct drsuapi_DsReplicaOIDMapping *mapping;
183 /* we should have at least schemaInfo element */
184 if (ctr->num_mappings < 1) {
185 return WERR_INVALID_PARAMETER;
188 /* verify schemaInfo element is valid */
189 mapping = &ctr->mappings[ctr->num_mappings - 1];
190 if (mapping->id_prefix != 0) {
191 return WERR_INVALID_PARAMETER;
194 blob = data_blob_const(mapping->oid.binary_oid, mapping->oid.length);
195 if (!dsdb_schema_info_blob_is_valid(&blob)) {
196 return WERR_INVALID_PARAMETER;
199 schema_info_str = hex_encode_talloc(NULL, blob.data, blob.length);
200 W_ERROR_HAVE_NO_MEMORY(schema_info_str);
202 bres = strequal(schema->schema_info, schema_info_str);
203 talloc_free(schema_info_str);
205 return bres ? WERR_OK : WERR_DS_DRA_SCHEMA_MISMATCH;