r20453: add conversation for the DN_BINARY attribute syntax
[Samba/gbeck.git] / source / dsdb / schema / schema_syntax.c
blob6b82968d2e4f940747660fe07cfc2bf25522382b
1 /*
2 Unix SMB/CIFS mplementation.
3 DSDB schema syntaxes
5 Copyright (C) Stefan Metzmacher 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "dsdb/samdb/samdb.h"
24 #include "librpc/gen_ndr/ndr_drsuapi.h"
25 #include "lib/ldb/include/ldb.h"
26 #include "system/time.h"
27 #include "lib/charset/charset.h"
28 #include "librpc/ndr/libndr.h"
30 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
31 const struct dsdb_attribute *attr,
32 const struct drsuapi_DsReplicaAttribute *in,
33 TALLOC_CTX *mem_ctx,
34 struct ldb_message_element *out)
36 uint32_t i;
38 out->flags = 0;
39 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
40 W_ERROR_HAVE_NO_MEMORY(out->name);
42 out->num_values = in->value_ctr.data_blob.num_values;
43 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
44 W_ERROR_HAVE_NO_MEMORY(out->values);
46 for (i=0; i < out->num_values; i++) {
47 char *str;
49 if (in->value_ctr.data_blob.values[i].data == NULL) {
50 return WERR_FOOBAR;
53 str = talloc_asprintf(out->values, "%s: not implemented",
54 attr->syntax->name);
55 W_ERROR_HAVE_NO_MEMORY(str);
57 out->values[i] = data_blob_string_const(str);
60 return WERR_OK;
63 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(const struct dsdb_schema *schema,
64 const struct dsdb_attribute *attr,
65 const struct ldb_message_element *in,
66 TALLOC_CTX *mem_ctx,
67 struct drsuapi_DsReplicaAttribute *out)
69 return WERR_FOOBAR;
72 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(const struct dsdb_schema *schema,
73 const struct dsdb_attribute *attr,
74 const struct drsuapi_DsReplicaAttribute *in,
75 TALLOC_CTX *mem_ctx,
76 struct ldb_message_element *out)
78 uint32_t i;
80 switch (attr->attributeID_id) {
81 case DRSUAPI_ATTRIBUTE_isSingleValued:
82 case DRSUAPI_ATTRIBUTE_showInAdvancedViewOnly:
83 case DRSUAPI_ATTRIBUTE_isMemberOfPartialAttributeSet:
84 return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
87 out->flags = 0;
88 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
89 W_ERROR_HAVE_NO_MEMORY(out->name);
91 out->num_values = in->value_ctr.data_blob.num_values;
92 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
93 W_ERROR_HAVE_NO_MEMORY(out->values);
95 for (i=0; i < out->num_values; i++) {
96 uint32_t v;
97 char *str;
99 if (in->value_ctr.data_blob.values[i].data == NULL) {
100 return WERR_FOOBAR;
103 if (in->value_ctr.data_blob.values[i].data->length != 4) {
104 return WERR_FOOBAR;
107 v = IVAL(in->value_ctr.data_blob.values[i].data->data, 0);
109 if (v != 0) {
110 str = talloc_strdup(out->values, "TRUE");
111 W_ERROR_HAVE_NO_MEMORY(str);
112 } else {
113 str = talloc_strdup(out->values, "FALSE");
114 W_ERROR_HAVE_NO_MEMORY(str);
117 out->values[i] = data_blob_string_const(str);
120 return WERR_OK;
123 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(const struct dsdb_schema *schema,
124 const struct dsdb_attribute *attr,
125 const struct ldb_message_element *in,
126 TALLOC_CTX *mem_ctx,
127 struct drsuapi_DsReplicaAttribute *out)
129 uint32_t i;
130 DATA_BLOB *blobs;
132 if (attr->attributeID_id == 0xFFFFFFFF) {
133 return WERR_FOOBAR;
136 out->attid = attr->attributeID_id;
137 out->value_ctr.data_blob.num_values = in->num_values;
138 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
139 struct drsuapi_DsAttributeValueDataBlob,
140 in->num_values);
141 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
143 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
144 W_ERROR_HAVE_NO_MEMORY(blobs);
146 for (i=0; i < in->num_values; i++) {
147 out->value_ctr.data_blob.values[i].data = &blobs[i];
149 blobs[i] = data_blob_talloc(blobs, NULL, 4);
150 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
152 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
153 SIVAL(blobs[i].data, 0, 0x00000001);
154 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
155 SIVAL(blobs[i].data, 0, 0x00000000);
156 } else {
157 return WERR_FOOBAR;
161 return WERR_OK;
164 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(const struct dsdb_schema *schema,
165 const struct dsdb_attribute *attr,
166 const struct drsuapi_DsReplicaAttribute *in,
167 TALLOC_CTX *mem_ctx,
168 struct ldb_message_element *out)
170 uint32_t i;
172 switch (attr->attributeID_id) {
173 case DRSUAPI_ATTRIBUTE_instanceType:
174 case DRSUAPI_ATTRIBUTE_rangeLower:
175 case DRSUAPI_ATTRIBUTE_rangeUpper:
176 case DRSUAPI_ATTRIBUTE_objectVersion:
177 case DRSUAPI_ATTRIBUTE_oMSyntax:
178 case DRSUAPI_ATTRIBUTE_searchFlags:
179 case DRSUAPI_ATTRIBUTE_systemFlags:
180 case DRSUAPI_ATTRIBUTE_msDS_Behavior_Version:
181 return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
184 out->flags = 0;
185 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
186 W_ERROR_HAVE_NO_MEMORY(out->name);
188 out->num_values = in->value_ctr.data_blob.num_values;
189 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
190 W_ERROR_HAVE_NO_MEMORY(out->values);
192 for (i=0; i < out->num_values; i++) {
193 int32_t v;
194 char *str;
196 if (in->value_ctr.data_blob.values[i].data == NULL) {
197 return WERR_FOOBAR;
200 if (in->value_ctr.data_blob.values[i].data->length != 4) {
201 return WERR_FOOBAR;
204 v = IVALS(in->value_ctr.data_blob.values[i].data->data, 0);
206 str = talloc_asprintf(out->values, "%d", v);
207 W_ERROR_HAVE_NO_MEMORY(str);
209 out->values[i] = data_blob_string_const(str);
212 return WERR_OK;
215 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(const struct dsdb_schema *schema,
216 const struct dsdb_attribute *attr,
217 const struct ldb_message_element *in,
218 TALLOC_CTX *mem_ctx,
219 struct drsuapi_DsReplicaAttribute *out)
221 uint32_t i;
222 DATA_BLOB *blobs;
224 if (attr->attributeID_id == 0xFFFFFFFF) {
225 return WERR_FOOBAR;
228 out->attid = attr->attributeID_id;
229 out->value_ctr.data_blob.num_values = in->num_values;
230 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
231 struct drsuapi_DsAttributeValueDataBlob,
232 in->num_values);
233 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
235 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
236 W_ERROR_HAVE_NO_MEMORY(blobs);
238 for (i=0; i < in->num_values; i++) {
239 int32_t v;
241 out->value_ctr.data_blob.values[i].data = &blobs[i];
243 blobs[i] = data_blob_talloc(blobs, NULL, 4);
244 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
246 v = strtol((const char *)in->values[i].data, NULL, 10);
248 SIVALS(blobs[i].data, 0, v);
251 return WERR_OK;
254 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
255 const struct dsdb_attribute *attr,
256 const struct drsuapi_DsReplicaAttribute *in,
257 TALLOC_CTX *mem_ctx,
258 struct ldb_message_element *out)
260 uint32_t i;
262 out->flags = 0;
263 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
264 W_ERROR_HAVE_NO_MEMORY(out->name);
266 out->num_values = in->value_ctr.data_blob.num_values;
267 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
268 W_ERROR_HAVE_NO_MEMORY(out->values);
270 for (i=0; i < out->num_values; i++) {
271 int64_t v;
272 char *str;
274 if (in->value_ctr.data_blob.values[i].data == NULL) {
275 return WERR_FOOBAR;
278 if (in->value_ctr.data_blob.values[i].data->length != 8) {
279 return WERR_FOOBAR;
282 v = BVALS(in->value_ctr.data_blob.values[i].data->data, 0);
284 str = talloc_asprintf(out->values, "%lld", v);
285 W_ERROR_HAVE_NO_MEMORY(str);
287 out->values[i] = data_blob_string_const(str);
290 return WERR_OK;
293 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(const struct dsdb_schema *schema,
294 const struct dsdb_attribute *attr,
295 const struct ldb_message_element *in,
296 TALLOC_CTX *mem_ctx,
297 struct drsuapi_DsReplicaAttribute *out)
299 uint32_t i;
300 DATA_BLOB *blobs;
302 if (attr->attributeID_id == 0xFFFFFFFF) {
303 return WERR_FOOBAR;
306 out->attid = attr->attributeID_id;
307 out->value_ctr.data_blob.num_values = in->num_values;
308 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
309 struct drsuapi_DsAttributeValueDataBlob,
310 in->num_values);
311 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
313 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
314 W_ERROR_HAVE_NO_MEMORY(blobs);
316 for (i=0; i < in->num_values; i++) {
317 int64_t v;
319 out->value_ctr.data_blob.values[i].data = &blobs[i];
321 blobs[i] = data_blob_talloc(blobs, NULL, 8);
322 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
324 v = strtoll((const char *)in->values[i].data, NULL, 10);
326 SBVALS(blobs[i].data, 0, v);
329 return WERR_OK;
332 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(const struct dsdb_schema *schema,
333 const struct dsdb_attribute *attr,
334 const struct drsuapi_DsReplicaAttribute *in,
335 TALLOC_CTX *mem_ctx,
336 struct ldb_message_element *out)
338 uint32_t i;
340 out->flags = 0;
341 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
342 W_ERROR_HAVE_NO_MEMORY(out->name);
344 out->num_values = in->value_ctr.data_blob.num_values;
345 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
346 W_ERROR_HAVE_NO_MEMORY(out->values);
348 for (i=0; i < out->num_values; i++) {
349 NTTIME v;
350 time_t t;
351 char *str;
353 if (in->value_ctr.data_blob.values[i].data == NULL) {
354 return WERR_FOOBAR;
357 if (in->value_ctr.data_blob.values[i].data->length != 8) {
358 return WERR_FOOBAR;
361 v = BVAL(in->value_ctr.data_blob.values[i].data->data, 0);
362 v *= 10000000;
363 t = nt_time_to_unix(v);
365 str = ldb_timestring(out->values, t);
366 W_ERROR_HAVE_NO_MEMORY(str);
368 out->values[i] = data_blob_string_const(str);
371 return WERR_OK;
374 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(const struct dsdb_schema *schema,
375 const struct dsdb_attribute *attr,
376 const struct ldb_message_element *in,
377 TALLOC_CTX *mem_ctx,
378 struct drsuapi_DsReplicaAttribute *out)
380 uint32_t i;
381 DATA_BLOB *blobs;
383 if (attr->attributeID_id == 0xFFFFFFFF) {
384 return WERR_FOOBAR;
387 out->attid = attr->attributeID_id;
388 out->value_ctr.data_blob.num_values = in->num_values;
389 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
390 struct drsuapi_DsAttributeValueDataBlob,
391 in->num_values);
392 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
394 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
395 W_ERROR_HAVE_NO_MEMORY(blobs);
397 for (i=0; i < in->num_values; i++) {
398 NTTIME v;
399 time_t t;
401 out->value_ctr.data_blob.values[i].data = &blobs[i];
403 blobs[i] = data_blob_talloc(blobs, NULL, 8);
404 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
406 t = ldb_string_to_time((const char *)in->values[i].data);
407 unix_to_nt_time(&v, t);
409 SBVAL(blobs[i].data, 0, v);
412 return WERR_OK;
415 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(const struct dsdb_schema *schema,
416 const struct dsdb_attribute *attr,
417 const struct drsuapi_DsReplicaAttribute *in,
418 TALLOC_CTX *mem_ctx,
419 struct ldb_message_element *out)
421 uint32_t i;
423 switch (attr->attributeID_id) {
424 case DRSUAPI_ATTRIBUTE_invocationId:
425 case DRSUAPI_ATTRIBUTE_schemaIDGUID:
426 return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
429 out->flags = 0;
430 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
431 W_ERROR_HAVE_NO_MEMORY(out->name);
433 out->num_values = in->value_ctr.data_blob.num_values;
434 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
435 W_ERROR_HAVE_NO_MEMORY(out->values);
437 for (i=0; i < out->num_values; i++) {
438 if (in->value_ctr.data_blob.values[i].data == NULL) {
439 return WERR_FOOBAR;
442 if (in->value_ctr.data_blob.values[i].data->length == 0) {
443 return WERR_FOOBAR;
446 out->values[i] = data_blob_dup_talloc(out->values,
447 in->value_ctr.data_blob.values[i].data);
448 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
451 return WERR_OK;
454 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(const struct dsdb_schema *schema,
455 const struct dsdb_attribute *attr,
456 const struct ldb_message_element *in,
457 TALLOC_CTX *mem_ctx,
458 struct drsuapi_DsReplicaAttribute *out)
460 uint32_t i;
461 DATA_BLOB *blobs;
463 if (attr->attributeID_id == 0xFFFFFFFF) {
464 return WERR_FOOBAR;
467 out->attid = attr->attributeID_id;
468 out->value_ctr.data_blob.num_values = in->num_values;
469 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
470 struct drsuapi_DsAttributeValueDataBlob,
471 in->num_values);
472 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
474 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
475 W_ERROR_HAVE_NO_MEMORY(blobs);
477 for (i=0; i < in->num_values; i++) {
478 out->value_ctr.data_blob.values[i].data = &blobs[i];
480 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
481 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
484 return WERR_OK;
487 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(const struct dsdb_schema *schema,
488 const struct dsdb_attribute *attr,
489 const struct drsuapi_DsReplicaAttribute *in,
490 TALLOC_CTX *mem_ctx,
491 struct ldb_message_element *out)
493 uint32_t i;
495 out->flags = 0;
496 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
497 W_ERROR_HAVE_NO_MEMORY(out->name);
499 out->num_values = in->value_ctr.data_blob.num_values;
500 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
501 W_ERROR_HAVE_NO_MEMORY(out->values);
503 for (i=0; i < out->num_values; i++) {
504 uint32_t v;
505 const struct dsdb_class *c;
506 const char *str;
508 if (in->value_ctr.object_class_id.values[i].objectClassId == NULL) {
509 return WERR_FOOBAR;
512 v = *in->value_ctr.object_class_id.values[i].objectClassId;
514 c = dsdb_class_by_governsID_id(schema, v);
515 if (!c) {
516 return WERR_FOOBAR;
519 str = talloc_strdup(out->values, c->lDAPDisplayName);
520 W_ERROR_HAVE_NO_MEMORY(str);
522 /* the values need to be reversed */
523 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
526 return WERR_OK;
529 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(const struct dsdb_schema *schema,
530 const struct dsdb_attribute *attr,
531 const struct drsuapi_DsReplicaAttribute *in,
532 TALLOC_CTX *mem_ctx,
533 struct ldb_message_element *out)
535 uint32_t i;
537 out->flags = 0;
538 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
539 W_ERROR_HAVE_NO_MEMORY(out->name);
541 out->num_values = in->value_ctr.data_blob.num_values;
542 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
543 W_ERROR_HAVE_NO_MEMORY(out->values);
545 for (i=0; i < out->num_values; i++) {
546 uint32_t v;
547 WERROR status;
548 const char *str;
550 if (in->value_ctr.oid.values[i].value == NULL) {
551 return WERR_FOOBAR;
554 v = *in->value_ctr.oid.values[i].value;
556 status = dsdb_map_int2oid(schema, v, out->values, &str);
557 W_ERROR_NOT_OK_RETURN(status);
559 out->values[i] = data_blob_string_const(str);
562 return WERR_OK;
565 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(const struct dsdb_schema *schema,
566 const struct dsdb_attribute *attr,
567 const struct drsuapi_DsReplicaAttribute *in,
568 TALLOC_CTX *mem_ctx,
569 struct ldb_message_element *out)
571 uint32_t i;
573 switch (attr->attributeID_id) {
574 case DRSUAPI_ATTRIBUTE_objectClass:
575 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
576 case DRSUAPI_ATTRIBUTE_governsID:
577 case DRSUAPI_ATTRIBUTE_attributeID:
578 case DRSUAPI_ATTRIBUTE_attributeSyntax:
579 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(schema, attr, in, mem_ctx, out);
582 out->flags = 0;
583 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
584 W_ERROR_HAVE_NO_MEMORY(out->name);
586 out->num_values = in->value_ctr.data_blob.num_values;
587 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
588 W_ERROR_HAVE_NO_MEMORY(out->values);
590 for (i=0; i < out->num_values; i++) {
591 uint32_t v;
592 const char *name;
593 char *str;
595 if (in->value_ctr.data_blob.values[i].data == NULL) {
596 return WERR_FOOBAR;
599 if (in->value_ctr.data_blob.values[i].data->length != 4) {
600 return WERR_FOOBAR;
603 v = IVAL(in->value_ctr.data_blob.values[i].data->data, 0);
605 name = dsdb_lDAPDisplayName_by_id(schema, v);
606 if (!name) {
607 return WERR_FOOBAR;
610 str = talloc_strdup(out->values, name);
611 W_ERROR_HAVE_NO_MEMORY(str);
613 out->values[i] = data_blob_string_const(str);
616 return WERR_OK;
619 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_schema *schema,
620 const struct dsdb_attribute *attr,
621 const struct ldb_message_element *in,
622 TALLOC_CTX *mem_ctx,
623 struct drsuapi_DsReplicaAttribute *out)
625 uint32_t i;
626 DATA_BLOB *blobs;
628 if (attr->attributeID_id == 0xFFFFFFFF) {
629 return WERR_FOOBAR;
632 switch (attr->attributeID_id) {
633 case DRSUAPI_ATTRIBUTE_objectClass:
634 case DRSUAPI_ATTRIBUTE_governsID:
635 case DRSUAPI_ATTRIBUTE_attributeID:
636 case DRSUAPI_ATTRIBUTE_attributeSyntax:
637 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(schema, attr, in, mem_ctx, out);
640 out->attid = attr->attributeID_id;
641 out->value_ctr.data_blob.num_values = in->num_values;
642 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
643 struct drsuapi_DsAttributeValueDataBlob,
644 in->num_values);
645 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
647 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
648 W_ERROR_HAVE_NO_MEMORY(blobs);
650 for (i=0; i < in->num_values; i++) {
651 uint32_t v;
653 out->value_ctr.data_blob.values[i].data = &blobs[i];
655 blobs[i] = data_blob_talloc(blobs, NULL, 4);
656 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
658 v = strtol((const char *)in->values[i].data, NULL, 10);
660 SIVAL(blobs[i].data, 0, v);
663 return WERR_OK;
666 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schema,
667 const struct dsdb_attribute *attr,
668 const struct drsuapi_DsReplicaAttribute *in,
669 TALLOC_CTX *mem_ctx,
670 struct ldb_message_element *out)
672 uint32_t i;
674 switch (attr->attributeID_id) {
675 case DRSUAPI_ATTRIBUTE_description:
676 case DRSUAPI_ATTRIBUTE_adminDisplayName:
677 case DRSUAPI_ATTRIBUTE_adminDescription:
678 case DRSUAPI_ATTRIBUTE_lDAPDisplayName:
679 case DRSUAPI_ATTRIBUTE_name:
680 case DRSUAPI_ATTRIBUTE_sAMAccountName:
681 case DRSUAPI_ATTRIBUTE_gPLink:
682 return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
685 out->flags = 0;
686 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
687 W_ERROR_HAVE_NO_MEMORY(out->name);
689 out->num_values = in->value_ctr.data_blob.num_values;
690 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
691 W_ERROR_HAVE_NO_MEMORY(out->values);
693 for (i=0; i < out->num_values; i++) {
694 ssize_t ret;
695 char *str;
697 if (in->value_ctr.data_blob.values[i].data == NULL) {
698 return WERR_FOOBAR;
701 if (in->value_ctr.data_blob.values[i].data->length == 0) {
702 return WERR_FOOBAR;
705 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
706 in->value_ctr.data_blob.values[i].data->data,
707 in->value_ctr.data_blob.values[i].data->length,
708 (void **)&str);
709 if (ret == -1) {
710 return WERR_FOOBAR;
713 out->values[i] = data_blob_string_const(str);
716 return WERR_OK;
719 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schema,
720 const struct dsdb_attribute *attr,
721 const struct ldb_message_element *in,
722 TALLOC_CTX *mem_ctx,
723 struct drsuapi_DsReplicaAttribute *out)
725 uint32_t i;
726 DATA_BLOB *blobs;
728 if (attr->attributeID_id == 0xFFFFFFFF) {
729 return WERR_FOOBAR;
732 out->attid = attr->attributeID_id;
733 out->value_ctr.data_blob.num_values = in->num_values;
734 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
735 struct drsuapi_DsAttributeValueDataBlob,
736 in->num_values);
737 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
739 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
740 W_ERROR_HAVE_NO_MEMORY(blobs);
742 for (i=0; i < in->num_values; i++) {
743 ssize_t ret;
745 out->value_ctr.data_blob.values[i].data = &blobs[i];
747 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
748 in->values[i].data,
749 in->values[i].length,
750 (void **)&blobs[i].data);
751 if (ret == -1) {
752 return WERR_FOOBAR;
754 blobs[i].length = ret;
757 return WERR_OK;
760 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
761 const struct dsdb_attribute *attr,
762 const struct drsuapi_DsReplicaAttribute *in,
763 TALLOC_CTX *mem_ctx,
764 struct ldb_message_element *out)
766 uint32_t i;
768 switch (attr->attributeID_id) {
769 case DRSUAPI_ATTRIBUTE_member:
770 case DRSUAPI_ATTRIBUTE_objectCategory:
771 case DRSUAPI_ATTRIBUTE_hasMasterNCs:
772 case DRSUAPI_ATTRIBUTE_dMDLocation:
773 case DRSUAPI_ATTRIBUTE_fSMORoleOwner:
774 case DRSUAPI_ATTRIBUTE_wellKnownObjects:
775 case DRSUAPI_ATTRIBUTE_serverReference:
776 case DRSUAPI_ATTRIBUTE_serverReferenceBL:
777 case DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs:
778 case DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs:
779 return dsdb_syntax_FOOBAR_drsuapi_to_ldb(schema,attr, in, mem_ctx, out);
782 out->flags = 0;
783 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
784 W_ERROR_HAVE_NO_MEMORY(out->name);
786 out->num_values = in->value_ctr.data_blob.num_values;
787 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
788 W_ERROR_HAVE_NO_MEMORY(out->values);
790 for (i=0; i < out->num_values; i++) {
791 struct drsuapi_DsReplicaObjectIdentifier3 id3;
792 NTSTATUS status;
794 if (in->value_ctr.data_blob.values[i].data == NULL) {
795 return WERR_FOOBAR;
798 if (in->value_ctr.data_blob.values[i].data->length == 0) {
799 return WERR_FOOBAR;
802 status = ndr_pull_struct_blob_all(in->value_ctr.data_blob.values[i].data,
803 out->values, &id3,
804 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
805 if (!NT_STATUS_IS_OK(status)) {
806 return ntstatus_to_werror(status);
809 /* TODO: handle id3.guid and id3.sid */
810 out->values[i] = data_blob_string_const(id3.dn);
813 return WERR_OK;
816 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
817 const struct dsdb_attribute *attr,
818 const struct ldb_message_element *in,
819 TALLOC_CTX *mem_ctx,
820 struct drsuapi_DsReplicaAttribute *out)
822 uint32_t i;
823 DATA_BLOB *blobs;
825 if (attr->attributeID_id == 0xFFFFFFFF) {
826 return WERR_FOOBAR;
829 out->attid = attr->attributeID_id;
830 out->value_ctr.data_blob.num_values = in->num_values;
831 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
832 struct drsuapi_DsAttributeValueDataBlob,
833 in->num_values);
834 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
836 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
837 W_ERROR_HAVE_NO_MEMORY(blobs);
839 for (i=0; i < in->num_values; i++) {
840 NTSTATUS status;
841 struct drsuapi_DsReplicaObjectIdentifier3 id3;
843 out->value_ctr.data_blob.values[i].data = &blobs[i];
845 /* TODO: handle id3.guid and id3.sid */
846 ZERO_STRUCT(id3);
847 id3.dn = (const char *)in->values[i].data;
849 status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
850 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
851 if (!NT_STATUS_IS_OK(status)) {
852 return ntstatus_to_werror(status);
856 return WERR_OK;
859 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
860 const struct dsdb_attribute *attr,
861 const struct drsuapi_DsReplicaAttribute *in,
862 TALLOC_CTX *mem_ctx,
863 struct ldb_message_element *out)
865 uint32_t i;
867 out->flags = 0;
868 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
869 W_ERROR_HAVE_NO_MEMORY(out->name);
871 out->num_values = in->value_ctr.data_blob.num_values;
872 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
873 W_ERROR_HAVE_NO_MEMORY(out->values);
875 for (i=0; i < out->num_values; i++) {
876 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
877 char *binary;
878 char *str;
879 NTSTATUS status;
881 if (in->value_ctr.data_blob.values[i].data == NULL) {
882 return WERR_FOOBAR;
885 if (in->value_ctr.data_blob.values[i].data->length == 0) {
886 return WERR_FOOBAR;
889 status = ndr_pull_struct_blob(in->value_ctr.data_blob.values[i].data,
890 out->values, &id3b,
891 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
892 if (!NT_STATUS_IS_OK(status)) {
893 return ntstatus_to_werror(status);
896 /* TODO: handle id3.guid and id3.sid */
897 binary = data_blob_hex_string(out->values, &id3b.binary);
898 W_ERROR_HAVE_NO_MEMORY(binary);
900 str = talloc_asprintf(out->values, "B:%u:%s:%s",
901 id3b.binary.length * 2, /* because of 2 hex chars per byte */
902 binary,
903 id3b.dn);
904 W_ERROR_HAVE_NO_MEMORY(str);
906 /* TODO: handle id3.guid and id3.sid */
907 out->values[i] = data_blob_string_const(str);
910 return WERR_OK;
913 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
914 const struct dsdb_attribute *attr,
915 const struct ldb_message_element *in,
916 TALLOC_CTX *mem_ctx,
917 struct drsuapi_DsReplicaAttribute *out)
919 uint32_t i;
920 DATA_BLOB *blobs;
922 if (attr->attributeID_id == 0xFFFFFFFF) {
923 return WERR_FOOBAR;
926 out->attid = attr->attributeID_id;
927 out->value_ctr.data_blob.num_values = in->num_values;
928 out->value_ctr.data_blob.values = talloc_array(mem_ctx,
929 struct drsuapi_DsAttributeValueDataBlob,
930 in->num_values);
931 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.data_blob.values);
933 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
934 W_ERROR_HAVE_NO_MEMORY(blobs);
936 for (i=0; i < in->num_values; i++) {
937 NTSTATUS status;
938 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
940 out->value_ctr.data_blob.values[i].data = &blobs[i];
942 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
943 ZERO_STRUCT(id3b);
944 id3b.dn = (const char *)in->values[i].data;
945 id3b.binary = data_blob(NULL, 0);
947 status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
948 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
949 if (!NT_STATUS_IS_OK(status)) {
950 return ntstatus_to_werror(status);
954 return WERR_OK;
957 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
959 static const struct dsdb_syntax dsdb_syntaxes[] = {
961 .name = "Boolean",
962 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
963 .oMSyntax = 1,
964 .attributeSyntax_oid = "2.5.5.8",
965 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
966 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
968 .name = "Integer",
969 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
970 .oMSyntax = 2,
971 .attributeSyntax_oid = "2.5.5.9",
972 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
973 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
975 .name = "String(Octet)",
976 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
977 .oMSyntax = 4,
978 .attributeSyntax_oid = "2.5.5.10",
979 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
980 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
982 .name = "String(Sid)",
983 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
984 .oMSyntax = 4,
985 .attributeSyntax_oid = "2.5.5.17",
986 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
987 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
989 .name = "String(Object-Identifier)",
990 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
991 .oMSyntax = 6,
992 .attributeSyntax_oid = "2.5.5.2",
993 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
994 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
996 .name = "Enumeration",
997 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.27",
998 .oMSyntax = 10,
999 .attributeSyntax_oid = "2.5.5.9",
1000 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1001 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1003 /* not used in w2k3 forest */
1004 .name = "String(Numeric)",
1005 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1006 .oMSyntax = 18,
1007 .attributeSyntax_oid = "2.5.5.6",
1008 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1009 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1011 /* not used in w2k3 forest */
1012 .name = "String(Printable)",
1013 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1014 .oMSyntax = 19,
1015 .attributeSyntax_oid = "2.5.5.5",
1016 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1017 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1019 /* not used in w2k3 forest */
1020 .name = "String(Teletex)",
1021 .ldap_oid = "1.2.840.113556.1.4.905",
1022 .oMSyntax = 20,
1023 .attributeSyntax_oid = "2.5.5.4",
1024 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1025 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1027 /* not used in w2k3 forest */
1028 .name = "String(IA5)",
1029 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1030 .oMSyntax = 22,
1031 .attributeSyntax_oid = "2.5.5.5",
1032 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1033 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1035 /* not used in w2k3 forest */
1036 .name = "String(UTC-Time)",
1037 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1038 .oMSyntax = 23,
1039 .attributeSyntax_oid = "2.5.5.11",
1040 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1041 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1043 .name = "String(Generalized-Time)",
1044 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1045 .oMSyntax = 24,
1046 .attributeSyntax_oid = "2.5.5.11",
1047 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1048 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1050 /* not used in w2k3 forest */
1051 .name = "String(Case Sensitive)",
1052 .ldap_oid = "1.2.840.113556.1.4.1362",
1053 .oMSyntax = 27,
1054 .attributeSyntax_oid = "2.5.5.3",
1055 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1056 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1058 .name = "String(Unicode)",
1059 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.15",
1060 .oMSyntax = 64,
1061 .attributeSyntax_oid = "2.5.5.12",
1062 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1063 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1065 .name = "Interval/LargeInteger",
1066 .ldap_oid = "1.2.840.113556.1.4.906",
1067 .oMSyntax = 65,
1068 .attributeSyntax_oid = "2.5.5.16",
1069 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1070 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1072 .name = "String(NT-Sec-Desc)",
1073 .ldap_oid = "1.2.840.113556.1.4.907",
1074 .oMSyntax = 66,
1075 .attributeSyntax_oid = "2.5.5.15",
1076 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1077 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1079 .name = "Object(DS-DN)",
1080 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.12",
1081 .oMSyntax = 127,
1082 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1083 .attributeSyntax_oid = "2.5.5.1",
1084 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1085 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1087 .name = "Object(DN-Binary)",
1088 .ldap_oid = "1.2.840.113556.1.4.903",
1089 .oMSyntax = 127,
1090 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1091 .attributeSyntax_oid = "2.5.5.7",
1092 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1093 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1095 /* not used in w2k3 forest */
1096 .name = "Object(OR-Name)",
1097 .ldap_oid = "1.2.840.113556.1.4.1221",
1098 .oMSyntax = 127,
1099 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1100 .attributeSyntax_oid = "2.5.5.7",
1101 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1102 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1104 .name = "Object(Replica-Link)",
1105 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1106 .oMSyntax = 127,
1107 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1108 .attributeSyntax_oid = "2.5.5.10",
1109 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1110 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1112 /* not used in w2k3 forest */
1113 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1114 .oMSyntax = 127,
1115 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1116 .attributeSyntax_oid = "2.5.5.13",
1117 .name = "Object(Presentation-Address)",
1118 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1119 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1121 /* not used in w2k3 forest */
1122 .name = "Object(Access-Point)",
1123 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1124 .oMSyntax = 127,
1125 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1126 .attributeSyntax_oid = "2.5.5.14",
1127 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1128 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1130 /* not used in w2k3 forest */
1131 .name = "Object(DN-String)",
1132 .ldap_oid = "1.2.840.113556.1.4.904",
1133 .oMSyntax = 127,
1134 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1135 .attributeSyntax_oid = "2.5.5.14",
1136 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1137 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1141 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1143 uint32_t i;
1145 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1146 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1148 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1150 if (attr->oMObjectClass.length) {
1151 int ret;
1152 ret = memcmp(attr->oMObjectClass.data,
1153 dsdb_syntaxes[i].oMObjectClass.data,
1154 attr->oMObjectClass.length);
1155 if (ret != 0) continue;
1158 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1160 return &dsdb_syntaxes[i];
1163 return NULL;
1166 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1167 const struct drsuapi_DsReplicaAttribute *in,
1168 TALLOC_CTX *mem_ctx,
1169 struct ldb_message_element *out)
1171 const struct dsdb_attribute *sa;
1173 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1174 if (!sa) {
1175 return WERR_FOOBAR;
1178 return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1181 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1182 const struct ldb_message_element *in,
1183 TALLOC_CTX *mem_ctx,
1184 struct drsuapi_DsReplicaAttribute *out)
1186 const struct dsdb_attribute *sa;
1188 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1189 if (!sa) {
1190 return WERR_FOOBAR;
1193 return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);