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