/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dsdb_syntax_FOOBAR_drsuapi_to_ldb
- dsdb_syntax_FOOBAR_ldb_to_drsuapi
- dsdb_syntax_BOOL_drsuapi_to_ldb
- dsdb_syntax_BOOL_ldb_to_drsuapi
- dsdb_syntax_INT32_drsuapi_to_ldb
- dsdb_syntax_INT32_ldb_to_drsuapi
- dsdb_syntax_INT64_drsuapi_to_ldb
- dsdb_syntax_INT64_ldb_to_drsuapi
- dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb
- dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi
- dsdb_syntax_NTTIME_drsuapi_to_ldb
- dsdb_syntax_NTTIME_ldb_to_drsuapi
- dsdb_syntax_DATA_BLOB_drsuapi_to_ldb
- dsdb_syntax_DATA_BLOB_ldb_to_drsuapi
- _dsdb_syntax_OID_obj_drsuapi_to_ldb
- _dsdb_syntax_OID_oid_drsuapi_to_ldb
- dsdb_syntax_OID_drsuapi_to_ldb
- dsdb_syntax_OID_ldb_to_drsuapi
- dsdb_syntax_UNICODE_drsuapi_to_ldb
- dsdb_syntax_UNICODE_ldb_to_drsuapi
- dsdb_syntax_DN_drsuapi_to_ldb
- dsdb_syntax_DN_ldb_to_drsuapi
- dsdb_syntax_DN_BINARY_drsuapi_to_ldb
- dsdb_syntax_DN_BINARY_ldb_to_drsuapi
- dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb
- dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi
- find_syntax_map_by_ad_oid
- find_syntax_map_by_ad_syntax
- find_syntax_map_by_standard_oid
- dsdb_syntax_for_attribute
- dsdb_attribute_drsuapi_to_ldb
- dsdb_attribute_ldb_to_drsuapi
1 /*
2 Unix SMB/CIFS mplementation.
3 DSDB schema syntaxes
4
5 Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
6 Copyright (C) Simo Sorce 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 */
23 #include "includes.h"
24 #include "dsdb/samdb/samdb.h"
25 #include "librpc/gen_ndr/ndr_drsuapi.h"
26 #include "librpc/gen_ndr/ndr_security.h"
27 #include "librpc/gen_ndr/ndr_misc.h"
28 #include "lib/ldb/include/ldb.h"
29 #include "lib/ldb/include/ldb_errors.h"
30 #include "system/time.h"
31 #include "../lib/util/charset/charset.h"
32 #include "librpc/ndr/libndr.h"
33
34 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
35 const struct dsdb_schema *schema,
36 const struct dsdb_attribute *attr,
37 const struct drsuapi_DsReplicaAttribute *in,
38 TALLOC_CTX *mem_ctx,
39 struct ldb_message_element *out)
40 {
41 uint32_t i;
42
43 out->flags = 0;
44 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
45 W_ERROR_HAVE_NO_MEMORY(out->name);
46
47 out->num_values = in->value_ctr.num_values;
48 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
49 W_ERROR_HAVE_NO_MEMORY(out->values);
50
51 for (i=0; i < out->num_values; i++) {
52 char *str;
53
54 if (in->value_ctr.values[i].blob == NULL) {
55 return WERR_FOOBAR;
56 }
57
58 str = talloc_asprintf(out->values, "%s: not implemented",
59 attr->syntax->name);
60 W_ERROR_HAVE_NO_MEMORY(str);
61
62 out->values[i] = data_blob_string_const(str);
63 }
64
65 return WERR_OK;
66 }
67
68 static WERROR dsdb_syntax_FOOBAR_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
69 const struct dsdb_schema *schema,
70 const struct dsdb_attribute *attr,
71 const struct ldb_message_element *in,
72 TALLOC_CTX *mem_ctx,
73 struct drsuapi_DsReplicaAttribute *out)
74 {
75 return WERR_FOOBAR;
76 }
77
78 static WERROR dsdb_syntax_BOOL_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
79 const struct dsdb_schema *schema,
80 const struct dsdb_attribute *attr,
81 const struct drsuapi_DsReplicaAttribute *in,
82 TALLOC_CTX *mem_ctx,
83 struct ldb_message_element *out)
84 {
85 uint32_t i;
86
87 out->flags = 0;
88 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
89 W_ERROR_HAVE_NO_MEMORY(out->name);
90
91 out->num_values = in->value_ctr.num_values;
92 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
93 W_ERROR_HAVE_NO_MEMORY(out->values);
94
95 for (i=0; i < out->num_values; i++) {
96 uint32_t v;
97 char *str;
98
99 if (in->value_ctr.values[i].blob == NULL) {
100 return WERR_FOOBAR;
101 }
102
103 if (in->value_ctr.values[i].blob->length != 4) {
104 return WERR_FOOBAR;
105 }
106
107 v = IVAL(in->value_ctr.values[i].blob->data, 0);
108
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);
115 }
116
117 out->values[i] = data_blob_string_const(str);
118 }
119
120 return WERR_OK;
121 }
122
123 static WERROR dsdb_syntax_BOOL_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
124 const struct dsdb_schema *schema,
125 const struct dsdb_attribute *attr,
126 const struct ldb_message_element *in,
127 TALLOC_CTX *mem_ctx,
128 struct drsuapi_DsReplicaAttribute *out)
129 {
130 uint32_t i;
131 DATA_BLOB *blobs;
132
133 if (attr->attributeID_id == 0xFFFFFFFF) {
134 return WERR_FOOBAR;
135 }
136
137 out->attid = attr->attributeID_id;
138 out->value_ctr.num_values = in->num_values;
139 out->value_ctr.values = talloc_array(mem_ctx,
140 struct drsuapi_DsAttributeValue,
141 in->num_values);
142 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
143
144 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
145 W_ERROR_HAVE_NO_MEMORY(blobs);
146
147 for (i=0; i < in->num_values; i++) {
148 out->value_ctr.values[i].blob = &blobs[i];
149
150 blobs[i] = data_blob_talloc(blobs, NULL, 4);
151 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
152
153 if (strcmp("TRUE", (const char *)in->values[i].data) == 0) {
154 SIVAL(blobs[i].data, 0, 0x00000001);
155 } else if (strcmp("FALSE", (const char *)in->values[i].data) == 0) {
156 SIVAL(blobs[i].data, 0, 0x00000000);
157 } else {
158 return WERR_FOOBAR;
159 }
160 }
161
162 return WERR_OK;
163 }
164
165 static WERROR dsdb_syntax_INT32_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
166 const struct dsdb_schema *schema,
167 const struct dsdb_attribute *attr,
168 const struct drsuapi_DsReplicaAttribute *in,
169 TALLOC_CTX *mem_ctx,
170 struct ldb_message_element *out)
171 {
172 uint32_t i;
173
174 out->flags = 0;
175 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
176 W_ERROR_HAVE_NO_MEMORY(out->name);
177
178 out->num_values = in->value_ctr.num_values;
179 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
180 W_ERROR_HAVE_NO_MEMORY(out->values);
181
182 for (i=0; i < out->num_values; i++) {
183 int32_t v;
184 char *str;
185
186 if (in->value_ctr.values[i].blob == NULL) {
187 return WERR_FOOBAR;
188 }
189
190 if (in->value_ctr.values[i].blob->length != 4) {
191 return WERR_FOOBAR;
192 }
193
194 v = IVALS(in->value_ctr.values[i].blob->data, 0);
195
196 str = talloc_asprintf(out->values, "%d", v);
197 W_ERROR_HAVE_NO_MEMORY(str);
198
199 out->values[i] = data_blob_string_const(str);
200 }
201
202 return WERR_OK;
203 }
204
205 static WERROR dsdb_syntax_INT32_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
206 const struct dsdb_schema *schema,
207 const struct dsdb_attribute *attr,
208 const struct ldb_message_element *in,
209 TALLOC_CTX *mem_ctx,
210 struct drsuapi_DsReplicaAttribute *out)
211 {
212 uint32_t i;
213 DATA_BLOB *blobs;
214
215 if (attr->attributeID_id == 0xFFFFFFFF) {
216 return WERR_FOOBAR;
217 }
218
219 out->attid = attr->attributeID_id;
220 out->value_ctr.num_values = in->num_values;
221 out->value_ctr.values = talloc_array(mem_ctx,
222 struct drsuapi_DsAttributeValue,
223 in->num_values);
224 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
225
226 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
227 W_ERROR_HAVE_NO_MEMORY(blobs);
228
229 for (i=0; i < in->num_values; i++) {
230 int32_t v;
231
232 out->value_ctr.values[i].blob = &blobs[i];
233
234 blobs[i] = data_blob_talloc(blobs, NULL, 4);
235 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
236
237 v = strtol((const char *)in->values[i].data, NULL, 10);
238
239 SIVALS(blobs[i].data, 0, v);
240 }
241
242 return WERR_OK;
243 }
244
245 static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
246 const struct dsdb_schema *schema,
247 const struct dsdb_attribute *attr,
248 const struct drsuapi_DsReplicaAttribute *in,
249 TALLOC_CTX *mem_ctx,
250 struct ldb_message_element *out)
251 {
252 uint32_t i;
253
254 out->flags = 0;
255 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
256 W_ERROR_HAVE_NO_MEMORY(out->name);
257
258 out->num_values = in->value_ctr.num_values;
259 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
260 W_ERROR_HAVE_NO_MEMORY(out->values);
261
262 for (i=0; i < out->num_values; i++) {
263 int64_t v;
264 char *str;
265
266 if (in->value_ctr.values[i].blob == NULL) {
267 return WERR_FOOBAR;
268 }
269
270 if (in->value_ctr.values[i].blob->length != 8) {
271 return WERR_FOOBAR;
272 }
273
274 v = BVALS(in->value_ctr.values[i].blob->data, 0);
275
276 str = talloc_asprintf(out->values, "%lld", (long long int)v);
277 W_ERROR_HAVE_NO_MEMORY(str);
278
279 out->values[i] = data_blob_string_const(str);
280 }
281
282 return WERR_OK;
283 }
284
285 static WERROR dsdb_syntax_INT64_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
286 const struct dsdb_schema *schema,
287 const struct dsdb_attribute *attr,
288 const struct ldb_message_element *in,
289 TALLOC_CTX *mem_ctx,
290 struct drsuapi_DsReplicaAttribute *out)
291 {
292 uint32_t i;
293 DATA_BLOB *blobs;
294
295 if (attr->attributeID_id == 0xFFFFFFFF) {
296 return WERR_FOOBAR;
297 }
298
299 out->attid = attr->attributeID_id;
300 out->value_ctr.num_values = in->num_values;
301 out->value_ctr.values = talloc_array(mem_ctx,
302 struct drsuapi_DsAttributeValue,
303 in->num_values);
304 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
305
306 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
307 W_ERROR_HAVE_NO_MEMORY(blobs);
308
309 for (i=0; i < in->num_values; i++) {
310 int64_t v;
311
312 out->value_ctr.values[i].blob = &blobs[i];
313
314 blobs[i] = data_blob_talloc(blobs, NULL, 8);
315 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
316
317 v = strtoll((const char *)in->values[i].data, NULL, 10);
318
319 SBVALS(blobs[i].data, 0, v);
320 }
321
322 return WERR_OK;
323 }
324
325 static WERROR dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
326 const struct dsdb_schema *schema,
327 const struct dsdb_attribute *attr,
328 const struct drsuapi_DsReplicaAttribute *in,
329 TALLOC_CTX *mem_ctx,
330 struct ldb_message_element *out)
331 {
332 uint32_t i;
333
334 out->flags = 0;
335 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
336 W_ERROR_HAVE_NO_MEMORY(out->name);
337
338 out->num_values = in->value_ctr.num_values;
339 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
340 W_ERROR_HAVE_NO_MEMORY(out->values);
341
342 for (i=0; i < out->num_values; i++) {
343 NTTIME v;
344 time_t t;
345 char *str;
346
347 if (in->value_ctr.values[i].blob == NULL) {
348 return WERR_FOOBAR;
349 }
350
351 if (in->value_ctr.values[i].blob->length != 8) {
352 return WERR_FOOBAR;
353 }
354
355 v = BVAL(in->value_ctr.values[i].blob->data, 0);
356 v *= 10000000;
357 t = nt_time_to_unix(v);
358
359 /*
360 * NOTE: On a w2k3 server you can set a GeneralizedTime string
361 * via LDAP, but you get back an UTCTime string,
362 * but via DRSUAPI you get back the NTTIME_1sec value
363 * that represents the GeneralizedTime value!
364 *
365 * So if we store the UTCTime string in our ldb
366 * we'll loose information!
367 */
368 str = ldb_timestring_utc(out->values, t);
369 W_ERROR_HAVE_NO_MEMORY(str);
370 out->values[i] = data_blob_string_const(str);
371 }
372
373 return WERR_OK;
374 }
375
376 static WERROR dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
377 const struct dsdb_schema *schema,
378 const struct dsdb_attribute *attr,
379 const struct ldb_message_element *in,
380 TALLOC_CTX *mem_ctx,
381 struct drsuapi_DsReplicaAttribute *out)
382 {
383 uint32_t i;
384 DATA_BLOB *blobs;
385
386 if (attr->attributeID_id == 0xFFFFFFFF) {
387 return WERR_FOOBAR;
388 }
389
390 out->attid = attr->attributeID_id;
391 out->value_ctr.num_values = in->num_values;
392 out->value_ctr.values = talloc_array(mem_ctx,
393 struct drsuapi_DsAttributeValue,
394 in->num_values);
395 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
396
397 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
398 W_ERROR_HAVE_NO_MEMORY(blobs);
399
400 for (i=0; i < in->num_values; i++) {
401 NTTIME v;
402 time_t t;
403
404 out->value_ctr.values[i].blob = &blobs[i];
405
406 blobs[i] = data_blob_talloc(blobs, NULL, 8);
407 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
408
409 t = ldb_string_utc_to_time((const char *)in->values[i].data);
410 unix_to_nt_time(&v, t);
411 v /= 10000000;
412
413 SBVAL(blobs[i].data, 0, v);
414 }
415
416 return WERR_OK;
417 }
418
419 static WERROR dsdb_syntax_NTTIME_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
420 const struct dsdb_schema *schema,
421 const struct dsdb_attribute *attr,
422 const struct drsuapi_DsReplicaAttribute *in,
423 TALLOC_CTX *mem_ctx,
424 struct ldb_message_element *out)
425 {
426 uint32_t i;
427
428 out->flags = 0;
429 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
430 W_ERROR_HAVE_NO_MEMORY(out->name);
431
432 out->num_values = in->value_ctr.num_values;
433 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
434 W_ERROR_HAVE_NO_MEMORY(out->values);
435
436 for (i=0; i < out->num_values; i++) {
437 NTTIME v;
438 time_t t;
439 char *str;
440
441 if (in->value_ctr.values[i].blob == NULL) {
442 return WERR_FOOBAR;
443 }
444
445 if (in->value_ctr.values[i].blob->length != 8) {
446 return WERR_FOOBAR;
447 }
448
449 v = BVAL(in->value_ctr.values[i].blob->data, 0);
450 v *= 10000000;
451 t = nt_time_to_unix(v);
452
453 str = ldb_timestring(out->values, t);
454 W_ERROR_HAVE_NO_MEMORY(str);
455
456 out->values[i] = data_blob_string_const(str);
457 }
458
459 return WERR_OK;
460 }
461
462 static WERROR dsdb_syntax_NTTIME_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
463 const struct dsdb_schema *schema,
464 const struct dsdb_attribute *attr,
465 const struct ldb_message_element *in,
466 TALLOC_CTX *mem_ctx,
467 struct drsuapi_DsReplicaAttribute *out)
468 {
469 uint32_t i;
470 DATA_BLOB *blobs;
471
472 if (attr->attributeID_id == 0xFFFFFFFF) {
473 return WERR_FOOBAR;
474 }
475
476 out->attid = attr->attributeID_id;
477 out->value_ctr.num_values = in->num_values;
478 out->value_ctr.values = talloc_array(mem_ctx,
479 struct drsuapi_DsAttributeValue,
480 in->num_values);
481 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
482
483 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
484 W_ERROR_HAVE_NO_MEMORY(blobs);
485
486 for (i=0; i < in->num_values; i++) {
487 NTTIME v;
488 time_t t;
489
490 out->value_ctr.values[i].blob = &blobs[i];
491
492 blobs[i] = data_blob_talloc(blobs, NULL, 8);
493 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
494
495 t = ldb_string_to_time((const char *)in->values[i].data);
496 unix_to_nt_time(&v, t);
497 v /= 10000000;
498
499 SBVAL(blobs[i].data, 0, v);
500 }
501
502 return WERR_OK;
503 }
504
505 static WERROR dsdb_syntax_DATA_BLOB_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
506 const struct dsdb_schema *schema,
507 const struct dsdb_attribute *attr,
508 const struct drsuapi_DsReplicaAttribute *in,
509 TALLOC_CTX *mem_ctx,
510 struct ldb_message_element *out)
511 {
512 uint32_t i;
513
514 out->flags = 0;
515 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
516 W_ERROR_HAVE_NO_MEMORY(out->name);
517
518 out->num_values = in->value_ctr.num_values;
519 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
520 W_ERROR_HAVE_NO_MEMORY(out->values);
521
522 for (i=0; i < out->num_values; i++) {
523 if (in->value_ctr.values[i].blob == NULL) {
524 return WERR_FOOBAR;
525 }
526
527 if (in->value_ctr.values[i].blob->length == 0) {
528 return WERR_FOOBAR;
529 }
530
531 out->values[i] = data_blob_dup_talloc(out->values,
532 in->value_ctr.values[i].blob);
533 W_ERROR_HAVE_NO_MEMORY(out->values[i].data);
534 }
535
536 return WERR_OK;
537 }
538
539 static WERROR dsdb_syntax_DATA_BLOB_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
540 const struct dsdb_schema *schema,
541 const struct dsdb_attribute *attr,
542 const struct ldb_message_element *in,
543 TALLOC_CTX *mem_ctx,
544 struct drsuapi_DsReplicaAttribute *out)
545 {
546 uint32_t i;
547 DATA_BLOB *blobs;
548
549 if (attr->attributeID_id == 0xFFFFFFFF) {
550 return WERR_FOOBAR;
551 }
552
553 out->attid = attr->attributeID_id;
554 out->value_ctr.num_values = in->num_values;
555 out->value_ctr.values = talloc_array(mem_ctx,
556 struct drsuapi_DsAttributeValue,
557 in->num_values);
558 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
559
560 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
561 W_ERROR_HAVE_NO_MEMORY(blobs);
562
563 for (i=0; i < in->num_values; i++) {
564 out->value_ctr.values[i].blob = &blobs[i];
565
566 blobs[i] = data_blob_dup_talloc(blobs, &in->values[i]);
567 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
568 }
569
570 return WERR_OK;
571 }
572
573 static WERROR _dsdb_syntax_OID_obj_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
574 const struct dsdb_schema *schema,
575 const struct dsdb_attribute *attr,
576 const struct drsuapi_DsReplicaAttribute *in,
577 TALLOC_CTX *mem_ctx,
578 struct ldb_message_element *out)
579 {
580 uint32_t i;
581
582 out->flags = 0;
583 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
584 W_ERROR_HAVE_NO_MEMORY(out->name);
585
586 out->num_values = in->value_ctr.num_values;
587 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
588 W_ERROR_HAVE_NO_MEMORY(out->values);
589
590 for (i=0; i < out->num_values; i++) {
591 uint32_t v;
592 const struct dsdb_class *c;
593 const char *str;
594
595 if (in->value_ctr.values[i].blob == NULL) {
596 return WERR_FOOBAR;
597 }
598
599 if (in->value_ctr.values[i].blob->length != 4) {
600 return WERR_FOOBAR;
601 }
602
603 v = IVAL(in->value_ctr.values[i].blob->data, 0);
604
605 c = dsdb_class_by_governsID_id(schema, v);
606 if (!c) {
607 return WERR_FOOBAR;
608 }
609
610 str = talloc_strdup(out->values, c->lDAPDisplayName);
611 W_ERROR_HAVE_NO_MEMORY(str);
612
613 /* the values need to be reversed */
614 out->values[out->num_values - (i + 1)] = data_blob_string_const(str);
615 }
616
617 return WERR_OK;
618 }
619
620 static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
621 const struct dsdb_schema *schema,
622 const struct dsdb_attribute *attr,
623 const struct drsuapi_DsReplicaAttribute *in,
624 TALLOC_CTX *mem_ctx,
625 struct ldb_message_element *out)
626 {
627 uint32_t i;
628
629 out->flags = 0;
630 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
631 W_ERROR_HAVE_NO_MEMORY(out->name);
632
633 out->num_values = in->value_ctr.num_values;
634 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
635 W_ERROR_HAVE_NO_MEMORY(out->values);
636
637 for (i=0; i < out->num_values; i++) {
638 uint32_t v;
639 WERROR status;
640 const char *str;
641
642 if (in->value_ctr.values[i].blob == NULL) {
643 return WERR_FOOBAR;
644 }
645
646 if (in->value_ctr.values[i].blob->length != 4) {
647 return WERR_FOOBAR;
648 }
649
650 v = IVAL(in->value_ctr.values[i].blob->data, 0);
651
652 status = dsdb_map_int2oid(schema, v, out->values, &str);
653 W_ERROR_NOT_OK_RETURN(status);
654
655 out->values[i] = data_blob_string_const(str);
656 }
657
658 return WERR_OK;
659 }
660
661 static WERROR dsdb_syntax_OID_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
662 const struct dsdb_schema *schema,
663 const struct dsdb_attribute *attr,
664 const struct drsuapi_DsReplicaAttribute *in,
665 TALLOC_CTX *mem_ctx,
666 struct ldb_message_element *out)
667 {
668 uint32_t i;
669
670 switch (attr->attributeID_id) {
671 case DRSUAPI_ATTRIBUTE_objectClass:
672 return _dsdb_syntax_OID_obj_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
673 case DRSUAPI_ATTRIBUTE_governsID:
674 case DRSUAPI_ATTRIBUTE_attributeID:
675 case DRSUAPI_ATTRIBUTE_attributeSyntax:
676 return _dsdb_syntax_OID_oid_drsuapi_to_ldb(ldb, schema, attr, in, mem_ctx, out);
677 }
678
679 out->flags = 0;
680 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
681 W_ERROR_HAVE_NO_MEMORY(out->name);
682
683 out->num_values = in->value_ctr.num_values;
684 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
685 W_ERROR_HAVE_NO_MEMORY(out->values);
686
687 for (i=0; i < out->num_values; i++) {
688 uint32_t v;
689 const char *name;
690 char *str;
691
692 if (in->value_ctr.values[i].blob == NULL) {
693 return WERR_FOOBAR;
694 }
695
696 if (in->value_ctr.values[i].blob->length != 4) {
697 return WERR_FOOBAR;
698 }
699
700 v = IVAL(in->value_ctr.values[i].blob->data, 0);
701
702 name = dsdb_lDAPDisplayName_by_id(schema, v);
703 if (!name) {
704 return WERR_FOOBAR;
705 }
706
707 str = talloc_strdup(out->values, name);
708 W_ERROR_HAVE_NO_MEMORY(str);
709
710 out->values[i] = data_blob_string_const(str);
711 }
712
713 return WERR_OK;
714 }
715
716 static WERROR dsdb_syntax_OID_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
717 const struct dsdb_schema *schema,
718 const struct dsdb_attribute *attr,
719 const struct ldb_message_element *in,
720 TALLOC_CTX *mem_ctx,
721 struct drsuapi_DsReplicaAttribute *out)
722 {
723 uint32_t i;
724 DATA_BLOB *blobs;
725
726 if (attr->attributeID_id == 0xFFFFFFFF) {
727 return WERR_FOOBAR;
728 }
729
730 switch (attr->attributeID_id) {
731 case DRSUAPI_ATTRIBUTE_objectClass:
732 case DRSUAPI_ATTRIBUTE_governsID:
733 case DRSUAPI_ATTRIBUTE_attributeID:
734 case DRSUAPI_ATTRIBUTE_attributeSyntax:
735 return dsdb_syntax_FOOBAR_ldb_to_drsuapi(ldb, schema, attr, in, mem_ctx, out);
736 }
737
738 out->attid = attr->attributeID_id;
739 out->value_ctr.num_values = in->num_values;
740 out->value_ctr.values = talloc_array(mem_ctx,
741 struct drsuapi_DsAttributeValue,
742 in->num_values);
743 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
744
745 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
746 W_ERROR_HAVE_NO_MEMORY(blobs);
747
748 for (i=0; i < in->num_values; i++) {
749 uint32_t v;
750
751 out->value_ctr.values[i].blob = &blobs[i];
752
753 blobs[i] = data_blob_talloc(blobs, NULL, 4);
754 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
755
756 v = strtol((const char *)in->values[i].data, NULL, 10);
757
758 SIVAL(blobs[i].data, 0, v);
759 }
760
761 return WERR_OK;
762 }
763
764 static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
765 const struct dsdb_schema *schema,
766 const struct dsdb_attribute *attr,
767 const struct drsuapi_DsReplicaAttribute *in,
768 TALLOC_CTX *mem_ctx,
769 struct ldb_message_element *out)
770 {
771 uint32_t i;
772
773 out->flags = 0;
774 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
775 W_ERROR_HAVE_NO_MEMORY(out->name);
776
777 out->num_values = in->value_ctr.num_values;
778 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
779 W_ERROR_HAVE_NO_MEMORY(out->values);
780
781 for (i=0; i < out->num_values; i++) {
782 char *str;
783
784 if (in->value_ctr.values[i].blob == NULL) {
785 return WERR_FOOBAR;
786 }
787
788 if (in->value_ctr.values[i].blob->length == 0) {
789 return WERR_FOOBAR;
790 }
791
792 if (!convert_string_talloc_convenience(out->values,
793 schema->iconv_convenience,
794 CH_UTF16, CH_UNIX,
795 in->value_ctr.values[i].blob->data,
796 in->value_ctr.values[i].blob->length,
797 (void **)&str, NULL, false)) {
798 return WERR_FOOBAR;
799 }
800
801 out->values[i] = data_blob_string_const(str);
802 }
803
804 return WERR_OK;
805 }
806
807 static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
808 const struct dsdb_schema *schema,
809 const struct dsdb_attribute *attr,
810 const struct ldb_message_element *in,
811 TALLOC_CTX *mem_ctx,
812 struct drsuapi_DsReplicaAttribute *out)
813 {
814 uint32_t i;
815 DATA_BLOB *blobs;
816
817 if (attr->attributeID_id == 0xFFFFFFFF) {
818 return WERR_FOOBAR;
819 }
820
821 out->attid = attr->attributeID_id;
822 out->value_ctr.num_values = in->num_values;
823 out->value_ctr.values = talloc_array(mem_ctx,
824 struct drsuapi_DsAttributeValue,
825 in->num_values);
826 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
827
828 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
829 W_ERROR_HAVE_NO_MEMORY(blobs);
830
831 for (i=0; i < in->num_values; i++) {
832 ssize_t ret;
833
834 out->value_ctr.values[i].blob = &blobs[i];
835
836 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
837 in->values[i].data,
838 in->values[i].length,
839 (void **)&blobs[i].data, NULL, false)) {
840 return WERR_FOOBAR;
841 }
842 blobs[i].length = ret;
843 }
844
845 return WERR_OK;
846 }
847
848 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
849 const struct dsdb_schema *schema,
850 const struct dsdb_attribute *attr,
851 const struct drsuapi_DsReplicaAttribute *in,
852 TALLOC_CTX *mem_ctx,
853 struct ldb_message_element *out)
854 {
855 uint32_t i;
856 int ret;
857
858 out->flags = 0;
859 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
860 W_ERROR_HAVE_NO_MEMORY(out->name);
861
862 out->num_values = in->value_ctr.num_values;
863 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
864 W_ERROR_HAVE_NO_MEMORY(out->values);
865
866 for (i=0; i < out->num_values; i++) {
867 struct drsuapi_DsReplicaObjectIdentifier3 id3;
868 enum ndr_err_code ndr_err;
869 DATA_BLOB guid_blob;
870 struct ldb_dn *dn;
871 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
872 if (!tmp_ctx) {
873 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
874 }
875
876 if (in->value_ctr.values[i].blob == NULL) {
877 talloc_free(tmp_ctx);
878 return WERR_FOOBAR;
879 }
880
881 if (in->value_ctr.values[i].blob->length == 0) {
882 talloc_free(tmp_ctx);
883 return WERR_FOOBAR;
884 }
885
886
887
888 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
889 tmp_ctx, schema->iconv_convenience, &id3,
890 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
891 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
892 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
893 talloc_free(tmp_ctx);
894 return ntstatus_to_werror(status);
895 }
896
897 dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
898 if (!dn) {
899 talloc_free(tmp_ctx);
900 /* If this fails, it must be out of memory, as it does not do much parsing */
901 W_ERROR_HAVE_NO_MEMORY(dn);
902 }
903
904 ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
905 (ndr_push_flags_fn_t)ndr_push_GUID);
906 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
907 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
908 talloc_free(tmp_ctx);
909 return ntstatus_to_werror(status);
910 }
911
912 ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
913 if (ret != LDB_SUCCESS) {
914 talloc_free(tmp_ctx);
915 return WERR_FOOBAR;
916 }
917
918 talloc_free(guid_blob.data);
919
920 if (id3.__ndr_size_sid) {
921 DATA_BLOB sid_blob;
922 ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
923 (ndr_push_flags_fn_t)ndr_push_dom_sid);
924 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
925 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
926 talloc_free(tmp_ctx);
927 return ntstatus_to_werror(status);
928 }
929
930 ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
931 if (ret != LDB_SUCCESS) {
932 talloc_free(tmp_ctx);
933 return WERR_FOOBAR;
934 }
935 }
936
937 out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
938 talloc_free(tmp_ctx);
939 }
940
941 return WERR_OK;
942 }
943
944 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
945 const struct dsdb_schema *schema,
946 const struct dsdb_attribute *attr,
947 const struct ldb_message_element *in,
948 TALLOC_CTX *mem_ctx,
949 struct drsuapi_DsReplicaAttribute *out)
950 {
951 uint32_t i;
952 DATA_BLOB *blobs;
953
954 if (attr->attributeID_id == 0xFFFFFFFF) {
955 return WERR_FOOBAR;
956 }
957
958 out->attid = attr->attributeID_id;
959 out->value_ctr.num_values = in->num_values;
960 out->value_ctr.values = talloc_array(mem_ctx,
961 struct drsuapi_DsAttributeValue,
962 in->num_values);
963 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
964
965 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
966 W_ERROR_HAVE_NO_MEMORY(blobs);
967
968 for (i=0; i < in->num_values; i++) {
969 struct drsuapi_DsReplicaObjectIdentifier3 id3;
970 enum ndr_err_code ndr_err;
971 const DATA_BLOB *guid_blob, *sid_blob;
972 struct ldb_dn *dn;
973 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
974 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
975
976 out->value_ctr.values[i].blob = &blobs[i];
977
978 dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
979
980 W_ERROR_HAVE_NO_MEMORY(dn);
981
982 guid_blob = ldb_dn_get_extended_component(dn, "GUID");
983
984 ZERO_STRUCT(id3);
985
986 if (guid_blob) {
987 ndr_err = ndr_pull_struct_blob_all(guid_blob,
988 tmp_ctx, schema->iconv_convenience, &id3.guid,
989 (ndr_pull_flags_fn_t)ndr_pull_GUID);
990 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
991 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
992 talloc_free(tmp_ctx);
993 return ntstatus_to_werror(status);
994 }
995 }
996
997 sid_blob = ldb_dn_get_extended_component(dn, "SID");
998 if (sid_blob) {
999
1000 ndr_err = ndr_pull_struct_blob_all(sid_blob,
1001 tmp_ctx, schema->iconv_convenience, &id3.sid,
1002 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1003 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1004 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1005 talloc_free(tmp_ctx);
1006 return ntstatus_to_werror(status);
1007 }
1008 }
1009
1010 id3.dn = ldb_dn_get_linearized(dn);
1011
1012 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
1013 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1014 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1015 talloc_free(tmp_ctx);
1016 return ntstatus_to_werror(status);
1017 }
1018 talloc_free(tmp_ctx);
1019 }
1020
1021 return WERR_OK;
1022 }
1023
1024 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1025 const struct dsdb_schema *schema,
1026 const struct dsdb_attribute *attr,
1027 const struct drsuapi_DsReplicaAttribute *in,
1028 TALLOC_CTX *mem_ctx,
1029 struct ldb_message_element *out)
1030 {
1031 uint32_t i;
1032
1033 out->flags = 0;
1034 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1035 W_ERROR_HAVE_NO_MEMORY(out->name);
1036
1037 out->num_values = in->value_ctr.num_values;
1038 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1039 W_ERROR_HAVE_NO_MEMORY(out->values);
1040
1041 for (i=0; i < out->num_values; i++) {
1042 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
1043 char *binary;
1044 char *str;
1045 enum ndr_err_code ndr_err;
1046
1047 if (in->value_ctr.values[i].blob == NULL) {
1048 return WERR_FOOBAR;
1049 }
1050
1051 if (in->value_ctr.values[i].blob->length == 0) {
1052 return WERR_FOOBAR;
1053 }
1054
1055 ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
1056 out->values, schema->iconv_convenience, &id3b,
1057 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
1058 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1059 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1060 return ntstatus_to_werror(status);
1061 }
1062
1063 /* TODO: handle id3.guid and id3.sid */
1064 binary = data_blob_hex_string(out->values, &id3b.binary);
1065 W_ERROR_HAVE_NO_MEMORY(binary);
1066
1067 str = talloc_asprintf(out->values, "B:%u:%s:%s",
1068 (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
1069 binary,
1070 id3b.dn);
1071 W_ERROR_HAVE_NO_MEMORY(str);
1072
1073 /* TODO: handle id3.guid and id3.sid */
1074 out->values[i] = data_blob_string_const(str);
1075 }
1076
1077 return WERR_OK;
1078 }
1079
1080 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1081 const struct dsdb_schema *schema,
1082 const struct dsdb_attribute *attr,
1083 const struct ldb_message_element *in,
1084 TALLOC_CTX *mem_ctx,
1085 struct drsuapi_DsReplicaAttribute *out)
1086 {
1087 uint32_t i;
1088 DATA_BLOB *blobs;
1089
1090 if (attr->attributeID_id == 0xFFFFFFFF) {
1091 return WERR_FOOBAR;
1092 }
1093
1094 out->attid = attr->attributeID_id;
1095 out->value_ctr.num_values = in->num_values;
1096 out->value_ctr.values = talloc_array(mem_ctx,
1097 struct drsuapi_DsAttributeValue,
1098 in->num_values);
1099 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1100
1101 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1102 W_ERROR_HAVE_NO_MEMORY(blobs);
1103
1104 for (i=0; i < in->num_values; i++) {
1105 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
1106 enum ndr_err_code ndr_err;
1107
1108 out->value_ctr.values[i].blob = &blobs[i];
1109
1110 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
1111 ZERO_STRUCT(id3b);
1112 id3b.dn = (const char *)in->values[i].data;
1113 id3b.binary = data_blob(NULL, 0);
1114
1115 ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
1116 (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1118 NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
1119 return ntstatus_to_werror(status);
1120 }
1121 }
1122
1123 return WERR_OK;
1124 }
1125
1126 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1127 const struct dsdb_schema *schema,
1128 const struct dsdb_attribute *attr,
1129 const struct drsuapi_DsReplicaAttribute *in,
1130 TALLOC_CTX *mem_ctx,
1131 struct ldb_message_element *out)
1132 {
1133 uint32_t i;
1134
1135 out->flags = 0;
1136 out->name = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1137 W_ERROR_HAVE_NO_MEMORY(out->name);
1138
1139 out->num_values = in->value_ctr.num_values;
1140 out->values = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1141 W_ERROR_HAVE_NO_MEMORY(out->values);
1142
1143 for (i=0; i < out->num_values; i++) {
1144 uint32_t len;
1145 char *str;
1146
1147 if (in->value_ctr.values[i].blob == NULL) {
1148 return WERR_FOOBAR;
1149 }
1150
1151 if (in->value_ctr.values[i].blob->length < 4) {
1152 return WERR_FOOBAR;
1153 }
1154
1155 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1156
1157 if (len != in->value_ctr.values[i].blob->length) {
1158 return WERR_FOOBAR;
1159 }
1160
1161 if (!convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
1162 in->value_ctr.values[i].blob->data+4,
1163 in->value_ctr.values[i].blob->length-4,
1164 (void **)&str, NULL, false)) {
1165 return WERR_FOOBAR;
1166 }
1167
1168 out->values[i] = data_blob_string_const(str);
1169 }
1170
1171 return WERR_OK;
1172 }
1173
1174 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1175 const struct dsdb_schema *schema,
1176 const struct dsdb_attribute *attr,
1177 const struct ldb_message_element *in,
1178 TALLOC_CTX *mem_ctx,
1179 struct drsuapi_DsReplicaAttribute *out)
1180 {
1181 uint32_t i;
1182 DATA_BLOB *blobs;
1183
1184 if (attr->attributeID_id == 0xFFFFFFFF) {
1185 return WERR_FOOBAR;
1186 }
1187
1188 out->attid = attr->attributeID_id;
1189 out->value_ctr.num_values = in->num_values;
1190 out->value_ctr.values = talloc_array(mem_ctx,
1191 struct drsuapi_DsAttributeValue,
1192 in->num_values);
1193 W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1194
1195 blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1196 W_ERROR_HAVE_NO_MEMORY(blobs);
1197
1198 for (i=0; i < in->num_values; i++) {
1199 uint8_t *data;
1200 size_t ret;
1201
1202 out->value_ctr.values[i].blob = &blobs[i];
1203
1204 if (!convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
1205 in->values[i].data,
1206 in->values[i].length,
1207 (void **)&data, &ret, false)) {
1208 return WERR_FOOBAR;
1209 }
1210
1211 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1212 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1213
1214 SIVAL(blobs[i].data, 0, 4 + ret);
1215
1216 if (ret > 0) {
1217 memcpy(blobs[i].data + 4, data, ret);
1218 talloc_free(data);
1219 }
1220 }
1221
1222 return WERR_OK;
1223 }
1224
1225 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1226
1227 static const struct dsdb_syntax dsdb_syntaxes[] = {
1228 {
1229 .name = "Boolean",
1230 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.7",
1231 .oMSyntax = 1,
1232 .attributeSyntax_oid = "2.5.5.8",
1233 .drsuapi_to_ldb = dsdb_syntax_BOOL_drsuapi_to_ldb,
1234 .ldb_to_drsuapi = dsdb_syntax_BOOL_ldb_to_drsuapi,
1235 .equality = "booleanMatch",
1236 .comment = "Boolean"
1237 },{
1238 .name = "Integer",
1239 .ldap_oid = LDB_SYNTAX_INTEGER,
1240 .oMSyntax = 2,
1241 .attributeSyntax_oid = "2.5.5.9",
1242 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1243 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1244 .equality = "integerMatch",
1245 .comment = "Integer",
1246 },{
1247 .name = "String(Octet)",
1248 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1249 .oMSyntax = 4,
1250 .attributeSyntax_oid = "2.5.5.10",
1251 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1252 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1253 .equality = "octetStringMatch",
1254 .comment = "Octet String",
1255 },{
1256 .name = "String(Sid)",
1257 .ldap_oid = LDB_SYNTAX_OCTET_STRING,
1258 .oMSyntax = 4,
1259 .attributeSyntax_oid = "2.5.5.17",
1260 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1261 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1262 .equality = "octetStringMatch",
1263 .comment = "Octet String - Security Identifier (SID)",
1264 .ldb_syntax = LDB_SYNTAX_SAMBA_SID
1265 },{
1266 .name = "String(Object-Identifier)",
1267 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.38",
1268 .oMSyntax = 6,
1269 .attributeSyntax_oid = "2.5.5.2",
1270 .drsuapi_to_ldb = dsdb_syntax_OID_drsuapi_to_ldb,
1271 .ldb_to_drsuapi = dsdb_syntax_OID_ldb_to_drsuapi,
1272 .equality = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
1273 .comment = "OID String",
1274 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING
1275 },{
1276 .name = "Enumeration",
1277 .ldap_oid = LDB_SYNTAX_INTEGER,
1278 .oMSyntax = 10,
1279 .attributeSyntax_oid = "2.5.5.9",
1280 .drsuapi_to_ldb = dsdb_syntax_INT32_drsuapi_to_ldb,
1281 .ldb_to_drsuapi = dsdb_syntax_INT32_ldb_to_drsuapi,
1282 },{
1283 /* not used in w2k3 forest */
1284 .name = "String(Numeric)",
1285 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.36",
1286 .oMSyntax = 18,
1287 .attributeSyntax_oid = "2.5.5.6",
1288 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1289 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1290 .equality = "numericStringMatch",
1291 .substring = "numericStringSubstringsMatch",
1292 .comment = "Numeric String"
1293 },{
1294 .name = "String(Printable)",
1295 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.44",
1296 .oMSyntax = 19,
1297 .attributeSyntax_oid = "2.5.5.5",
1298 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1299 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1300 },{
1301 .name = "String(Teletex)",
1302 .ldap_oid = "1.2.840.113556.1.4.905",
1303 .oMSyntax = 20,
1304 .attributeSyntax_oid = "2.5.5.4",
1305 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1306 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1307 .equality = "caseIgnoreMatch",
1308 .substring = "caseIgnoreSubstringsMatch",
1309 .comment = "Case Insensitive String",
1310 .ldb_syntax = LDB_SYNTAX_DIRECTORY_STRING,
1311 },{
1312 .name = "String(IA5)",
1313 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.26",
1314 .oMSyntax = 22,
1315 .attributeSyntax_oid = "2.5.5.5",
1316 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1317 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1318 .equality = "caseExactIA5Match",
1319 .comment = "Printable String"
1320 },{
1321 .name = "String(UTC-Time)",
1322 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.53",
1323 .oMSyntax = 23,
1324 .attributeSyntax_oid = "2.5.5.11",
1325 .drsuapi_to_ldb = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1326 .ldb_to_drsuapi = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1327 .equality = "generalizedTimeMatch",
1328 .comment = "UTC Time",
1329 },{
1330 .name = "String(Generalized-Time)",
1331 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.24",
1332 .oMSyntax = 24,
1333 .attributeSyntax_oid = "2.5.5.11",
1334 .drsuapi_to_ldb = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1335 .ldb_to_drsuapi = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1336 .equality = "generalizedTimeMatch",
1337 .comment = "Generalized Time",
1338 .ldb_syntax = LDB_SYNTAX_UTC_TIME,
1339 },{
1340 /* not used in w2k3 schema */
1341 .name = "String(Case Sensitive)",
1342 .ldap_oid = "1.2.840.113556.1.4.1362",
1343 .oMSyntax = 27,
1344 .attributeSyntax_oid = "2.5.5.3",
1345 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1346 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1347 },{
1348 .name = "String(Unicode)",
1349 .ldap_oid = LDB_SYNTAX_DIRECTORY_STRING,
1350 .oMSyntax = 64,
1351 .attributeSyntax_oid = "2.5.5.12",
1352 .drsuapi_to_ldb = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1353 .ldb_to_drsuapi = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1354 .equality = "caseIgnoreMatch",
1355 .substring = "caseIgnoreSubstringsMatch",
1356 .comment = "Directory String",
1357 },{
1358 .name = "Interval/LargeInteger",
1359 .ldap_oid = "1.2.840.113556.1.4.906",
1360 .oMSyntax = 65,
1361 .attributeSyntax_oid = "2.5.5.16",
1362 .drsuapi_to_ldb = dsdb_syntax_INT64_drsuapi_to_ldb,
1363 .ldb_to_drsuapi = dsdb_syntax_INT64_ldb_to_drsuapi,
1364 .equality = "integerMatch",
1365 .comment = "Large Integer",
1366 .ldb_syntax = LDB_SYNTAX_INTEGER,
1367 },{
1368 .name = "String(NT-Sec-Desc)",
1369 .ldap_oid = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
1370 .oMSyntax = 66,
1371 .attributeSyntax_oid = "2.5.5.15",
1372 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1373 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1374 },{
1375 .name = "Object(DS-DN)",
1376 .ldap_oid = LDB_SYNTAX_DN,
1377 .oMSyntax = 127,
1378 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1379 .attributeSyntax_oid = "2.5.5.1",
1380 .drsuapi_to_ldb = dsdb_syntax_DN_drsuapi_to_ldb,
1381 .ldb_to_drsuapi = dsdb_syntax_DN_ldb_to_drsuapi,
1382 .equality = "distinguishedNameMatch",
1383 .comment = "Object(DS-DN) == a DN",
1384 },{
1385 .name = "Object(DN-Binary)",
1386 .ldap_oid = "1.2.840.113556.1.4.903",
1387 .oMSyntax = 127,
1388 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1389 .attributeSyntax_oid = "2.5.5.7",
1390 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1391 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1392 .equality = "octetStringMatch",
1393 .comment = "OctetString: Binary+DN",
1394 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1395 },{
1396 /* not used in w2k3 schema */
1397 .name = "Object(OR-Name)",
1398 .ldap_oid = "1.2.840.113556.1.4.1221",
1399 .oMSyntax = 127,
1400 .oMObjectClass = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1401 .attributeSyntax_oid = "2.5.5.7",
1402 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1403 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1404 },{
1405 /*
1406 * TODO: verify if DATA_BLOB is correct here...!
1407 *
1408 * repsFrom and repsTo are the only attributes using
1409 * this attribute syntax, but they're not replicated...
1410 */
1411 .name = "Object(Replica-Link)",
1412 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.40",
1413 .oMSyntax = 127,
1414 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1415 .attributeSyntax_oid = "2.5.5.10",
1416 .drsuapi_to_ldb = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1417 .ldb_to_drsuapi = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1418 },{
1419 .name = "Object(Presentation-Address)",
1420 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.43",
1421 .oMSyntax = 127,
1422 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1423 .attributeSyntax_oid = "2.5.5.13",
1424 .drsuapi_to_ldb = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1425 .ldb_to_drsuapi = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1426 .comment = "Presentation Address"
1427 },{
1428 /* not used in w2k3 schema */
1429 .name = "Object(Access-Point)",
1430 .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2",
1431 .oMSyntax = 127,
1432 .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1433 .attributeSyntax_oid = "2.5.5.14",
1434 .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1435 .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1436 },{
1437 /* not used in w2k3 schema */
1438 .name = "Object(DN-String)",
1439 .ldap_oid = "1.2.840.113556.1.4.904",
1440 .oMSyntax = 127,
1441 .oMObjectClass = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1442 .attributeSyntax_oid = "2.5.5.14",
1443 .drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1444 .ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1445 .equality = "octetStringMatch",
1446 .comment = "OctetString: String+DN",
1447 .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
1448 }
1449 };
1450
1451 const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid)
/* [<][>][^][v][top][bottom][index][help] */
1452 {
1453 int i;
1454 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1455 if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
1456 return &dsdb_syntaxes[i];
1457 }
1458 }
1459 return NULL;
1460 }
1461
1462 const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax)
/* [<][>][^][v][top][bottom][index][help] */
1463 {
1464 int i;
1465 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1466 if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
1467 return &dsdb_syntaxes[i];
1468 }
1469 }
1470 return NULL;
1471 }
1472
1473 const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid)
/* [<][>][^][v][top][bottom][index][help] */
1474 {
1475 int i;
1476 for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
1477 if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
1478 return &dsdb_syntaxes[i];
1479 }
1480 }
1481 return NULL;
1482 }
1483 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
/* [<][>][^][v][top][bottom][index][help] */
1484 {
1485 uint32_t i;
1486
1487 for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1488 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1489
1490 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1491
1492 if (attr->oMObjectClass.length) {
1493 int ret;
1494 ret = memcmp(attr->oMObjectClass.data,
1495 dsdb_syntaxes[i].oMObjectClass.data,
1496 attr->oMObjectClass.length);
1497 if (ret != 0) continue;
1498 }
1499
1500 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1501
1502 return &dsdb_syntaxes[i];
1503 }
1504
1505 return NULL;
1506 }
1507
1508 WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1509 const struct dsdb_schema *schema,
1510 const struct drsuapi_DsReplicaAttribute *in,
1511 TALLOC_CTX *mem_ctx,
1512 struct ldb_message_element *out)
1513 {
1514 const struct dsdb_attribute *sa;
1515
1516 sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1517 if (!sa) {
1518 return WERR_FOOBAR;
1519 }
1520
1521 return sa->syntax->drsuapi_to_ldb(ldb, schema, sa, in, mem_ctx, out);
1522 }
1523
1524 WERROR dsdb_attribute_ldb_to_drsuapi(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
1525 const struct dsdb_schema *schema,
1526 const struct ldb_message_element *in,
1527 TALLOC_CTX *mem_ctx,
1528 struct drsuapi_DsReplicaAttribute *out)
1529 {
1530 const struct dsdb_attribute *sa;
1531
1532 sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1533 if (!sa) {
1534 return WERR_FOOBAR;
1535 }
1536
1537 return sa->syntax->ldb_to_drsuapi(ldb, schema, sa, in, mem_ctx, out);
1538 }