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/>.
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"
33 * Creates and initializes new dsdb_schema_info value.
34 * Initial schemaInfo values is with:
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
;
51 * Creates and initializes new dsdb_schema_info blob value.
52 * Initial schemaInfo values is with:
54 * invocationId = GUID_ZERO
56 WERROR
dsdb_schema_info_blob_new(TALLOC_CTX
*mem_ctx
, DATA_BLOB
*_schema_info_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 */
66 *_schema_info_blob
= blob
;
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
) {
81 /* schemaInfo blob must be 21 bytes long */
82 if (blob
->length
!= 21) {
86 /* schemaInfo blob should start with 0xFF */
87 if (blob
->data
[0] != 0xFF) {
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
,
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
);
127 talloc_free(temp_ctx
);
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
);
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
,
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
);
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
)
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
;