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