fe6d129787f6c5d4cfbd437b9d3256d3cf601438
[jelmer/samba4-debian.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 2 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, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 */
22 #include "includes.h"
23 #include "dsdb/samdb/samdb.h"
24 #include "librpc/gen_ndr/ndr_drsuapi.h"
25 #include "lib/ldb/include/ldb.h"
26 #include "system/time.h"
27 #include "lib/charset/charset.h"
28 #include "librpc/ndr/libndr.h"
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", 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, 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, 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                 NTSTATUS status;
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                 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
854                                                   out->values, &id3,
855                                                   (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
856                 if (!NT_STATUS_IS_OK(status)) {
857                         return ntstatus_to_werror(status);
858                 }
859
860                 /* TODO: handle id3.guid and id3.sid */
861                 out->values[i] = data_blob_string_const(id3.dn);
862         }
863
864         return WERR_OK;
865 }
866
867 static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
868                                             const struct dsdb_attribute *attr,
869                                             const struct ldb_message_element *in,
870                                             TALLOC_CTX *mem_ctx,
871                                             struct drsuapi_DsReplicaAttribute *out)
872 {
873         uint32_t i;
874         DATA_BLOB *blobs;
875
876         if (attr->attributeID_id == 0xFFFFFFFF) {
877                 return WERR_FOOBAR;
878         }
879
880         out->attid                      = attr->attributeID_id;
881         out->value_ctr.num_values       = in->num_values;
882         out->value_ctr.values           = talloc_array(mem_ctx,
883                                                        struct drsuapi_DsAttributeValue,
884                                                        in->num_values);
885         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
886
887         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
888         W_ERROR_HAVE_NO_MEMORY(blobs);
889
890         for (i=0; i < in->num_values; i++) {
891                 NTSTATUS status;
892                 struct drsuapi_DsReplicaObjectIdentifier3 id3;
893
894                 out->value_ctr.values[i].blob   = &blobs[i];
895
896                 /* TODO: handle id3.guid and id3.sid */
897                 ZERO_STRUCT(id3);
898                 id3.dn = (const char *)in->values[i].data;
899
900                 status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
901                                               (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
902                 if (!NT_STATUS_IS_OK(status)) {
903                         return ntstatus_to_werror(status);
904                 }
905         }
906
907         return WERR_OK;
908 }
909
910 static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *schema,
911                                                    const struct dsdb_attribute *attr,
912                                                    const struct drsuapi_DsReplicaAttribute *in,
913                                                    TALLOC_CTX *mem_ctx,
914                                                    struct ldb_message_element *out)
915 {
916         uint32_t i;
917
918         out->flags      = 0;
919         out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
920         W_ERROR_HAVE_NO_MEMORY(out->name);
921
922         out->num_values = in->value_ctr.num_values;
923         out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
924         W_ERROR_HAVE_NO_MEMORY(out->values);
925
926         for (i=0; i < out->num_values; i++) {
927                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
928                 char *binary;
929                 char *str;
930                 NTSTATUS status;
931
932                 if (in->value_ctr.values[i].blob == NULL) {
933                         return WERR_FOOBAR;
934                 }
935
936                 if (in->value_ctr.values[i].blob->length == 0) {
937                         return WERR_FOOBAR;
938                 }
939
940                 status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
941                                                   out->values, &id3b,
942                                                   (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
943                 if (!NT_STATUS_IS_OK(status)) {
944                         return ntstatus_to_werror(status);
945                 }
946
947                 /* TODO: handle id3.guid and id3.sid */
948                 binary = data_blob_hex_string(out->values, &id3b.binary);
949                 W_ERROR_HAVE_NO_MEMORY(binary);
950
951                 str = talloc_asprintf(out->values, "B:%u:%s:%s",
952                                       id3b.binary.length * 2, /* because of 2 hex chars per byte */
953                                       binary,
954                                       id3b.dn);
955                 W_ERROR_HAVE_NO_MEMORY(str);
956
957                 /* TODO: handle id3.guid and id3.sid */
958                 out->values[i] = data_blob_string_const(str);
959         }
960
961         return WERR_OK;
962 }
963
964 static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *schema,
965                                                    const struct dsdb_attribute *attr,
966                                                    const struct ldb_message_element *in,
967                                                    TALLOC_CTX *mem_ctx,
968                                                    struct drsuapi_DsReplicaAttribute *out)
969 {
970         uint32_t i;
971         DATA_BLOB *blobs;
972
973         if (attr->attributeID_id == 0xFFFFFFFF) {
974                 return WERR_FOOBAR;
975         }
976
977         out->attid                      = attr->attributeID_id;
978         out->value_ctr.num_values       = in->num_values;
979         out->value_ctr.values           = talloc_array(mem_ctx,
980                                                        struct drsuapi_DsAttributeValue,
981                                                        in->num_values);
982         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
983
984         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
985         W_ERROR_HAVE_NO_MEMORY(blobs);
986
987         for (i=0; i < in->num_values; i++) {
988                 NTSTATUS status;
989                 struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
990
991                 out->value_ctr.values[i].blob   = &blobs[i];
992
993                 /* TODO: handle id3b.guid and id3b.sid, id3.binary */
994                 ZERO_STRUCT(id3b);
995                 id3b.dn         = (const char *)in->values[i].data;
996                 id3b.binary     = data_blob(NULL, 0);
997
998                 status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
999                                               (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
1000                 if (!NT_STATUS_IS_OK(status)) {
1001                         return ntstatus_to_werror(status);
1002                 }
1003         }
1004
1005         return WERR_OK;
1006 }
1007
1008 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_schema *schema,
1009                                                               const struct dsdb_attribute *attr,
1010                                                               const struct drsuapi_DsReplicaAttribute *in,
1011                                                               TALLOC_CTX *mem_ctx,
1012                                                               struct ldb_message_element *out)
1013 {
1014         uint32_t i;
1015
1016         out->flags      = 0;
1017         out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
1018         W_ERROR_HAVE_NO_MEMORY(out->name);
1019
1020         out->num_values = in->value_ctr.num_values;
1021         out->values     = talloc_array(mem_ctx, struct ldb_val, out->num_values);
1022         W_ERROR_HAVE_NO_MEMORY(out->values);
1023
1024         for (i=0; i < out->num_values; i++) {
1025                 uint32_t len;
1026                 ssize_t ret;
1027                 char *str;
1028
1029                 if (in->value_ctr.values[i].blob == NULL) {
1030                         return WERR_FOOBAR;
1031                 }
1032
1033                 if (in->value_ctr.values[i].blob->length < 4) {
1034                         return WERR_FOOBAR;
1035                 }
1036
1037                 len = IVAL(in->value_ctr.values[i].blob->data, 0);
1038
1039                 if (len != in->value_ctr.values[i].blob->length) {
1040                         return WERR_FOOBAR;
1041                 }
1042
1043                 ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
1044                                             in->value_ctr.values[i].blob->data+4,
1045                                             in->value_ctr.values[i].blob->length-4,
1046                                             (void **)&str);
1047                 if (ret == -1) {
1048                         return WERR_FOOBAR;
1049                 }
1050
1051                 out->values[i] = data_blob_string_const(str);
1052         }
1053
1054         return WERR_OK;
1055 }
1056
1057 static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_schema *schema,
1058                                                               const struct dsdb_attribute *attr,
1059                                                               const struct ldb_message_element *in,
1060                                                               TALLOC_CTX *mem_ctx,
1061                                                               struct drsuapi_DsReplicaAttribute *out)
1062 {
1063         uint32_t i;
1064         DATA_BLOB *blobs;
1065
1066         if (attr->attributeID_id == 0xFFFFFFFF) {
1067                 return WERR_FOOBAR;
1068         }
1069
1070         out->attid                      = attr->attributeID_id;
1071         out->value_ctr.num_values       = in->num_values;
1072         out->value_ctr.values           = talloc_array(mem_ctx,
1073                                                        struct drsuapi_DsAttributeValue,
1074                                                        in->num_values);
1075         W_ERROR_HAVE_NO_MEMORY(out->value_ctr.values);
1076
1077         blobs = talloc_array(mem_ctx, DATA_BLOB, in->num_values);
1078         W_ERROR_HAVE_NO_MEMORY(blobs);
1079
1080         for (i=0; i < in->num_values; i++) {
1081                 uint8_t *data;
1082                 ssize_t ret;
1083
1084                 out->value_ctr.values[i].blob   = &blobs[i];
1085
1086                 ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
1087                                             in->values[i].data,
1088                                             in->values[i].length,
1089                                             (void **)&data);
1090                 if (ret == -1) {
1091                         return WERR_FOOBAR;
1092                 }
1093
1094                 blobs[i] = data_blob_talloc(blobs, NULL, 4 + ret);
1095                 W_ERROR_HAVE_NO_MEMORY(blobs[i].data);
1096
1097                 SIVAL(blobs[i].data, 0, 4 + ret);
1098
1099                 if (ret > 0) {
1100                         memcpy(blobs[i].data + 4, data, ret);
1101                         talloc_free(data);
1102                 }
1103         }
1104
1105         return WERR_OK;
1106 }
1107
1108
1109 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
1110
1111 static const struct dsdb_syntax dsdb_syntaxes[] = {
1112         {
1113                 .name                   = "Boolean",
1114                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.7",
1115                 .oMSyntax               = 1,
1116                 .attributeSyntax_oid    = "2.5.5.8",
1117                 .drsuapi_to_ldb         = dsdb_syntax_BOOL_drsuapi_to_ldb,
1118                 .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
1119         },{
1120                 .name                   = "Integer",
1121                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
1122                 .oMSyntax               = 2,
1123                 .attributeSyntax_oid    = "2.5.5.9",
1124                 .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
1125                 .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
1126         },{
1127                 .name                   = "String(Octet)",
1128                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
1129                 .oMSyntax               = 4,
1130                 .attributeSyntax_oid    = "2.5.5.10",
1131                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1132                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1133         },{
1134                 .name                   = "String(Sid)",
1135                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
1136                 .oMSyntax               = 4,
1137                 .attributeSyntax_oid    = "2.5.5.17",
1138                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1139                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1140         },{
1141                 .name                   = "String(Object-Identifier)",
1142                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.38",
1143                 .oMSyntax               = 6,
1144                 .attributeSyntax_oid    = "2.5.5.2",
1145                 .drsuapi_to_ldb         = dsdb_syntax_OID_drsuapi_to_ldb,
1146                 .ldb_to_drsuapi         = dsdb_syntax_OID_ldb_to_drsuapi,
1147         },{
1148                 .name                   = "Enumeration",
1149                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
1150                 .oMSyntax               = 10,
1151                 .attributeSyntax_oid    = "2.5.5.9",
1152                 .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
1153                 .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
1154         },{
1155         /* not used in w2k3 forest */
1156                 .name                   = "String(Numeric)",
1157                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.36",
1158                 .oMSyntax               = 18,
1159                 .attributeSyntax_oid    = "2.5.5.6",
1160                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1161                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1162         },{
1163                 .name                   = "String(Printable)",
1164                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.44",
1165                 .oMSyntax               = 19,
1166                 .attributeSyntax_oid    = "2.5.5.5",
1167                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1168                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1169         },{
1170                 .name                   = "String(Teletex)",
1171                 .ldap_oid               = "1.2.840.113556.1.4.905",
1172                 .oMSyntax               = 20,
1173                 .attributeSyntax_oid    = "2.5.5.4",
1174                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1175                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1176         },{
1177                 .name                   = "String(IA5)",
1178                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.26",
1179                 .oMSyntax               = 22,
1180                 .attributeSyntax_oid    = "2.5.5.5",
1181                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1182                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1183         },{
1184                 .name                   = "String(UTC-Time)",
1185                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.53",
1186                 .oMSyntax               = 23,
1187                 .attributeSyntax_oid    = "2.5.5.11",
1188                 .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
1189                 .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
1190         },{
1191                 .name                   = "String(Generalized-Time)",
1192                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
1193                 .oMSyntax               = 24,
1194                 .attributeSyntax_oid    = "2.5.5.11",
1195                 .drsuapi_to_ldb         = dsdb_syntax_NTTIME_drsuapi_to_ldb,
1196                 .ldb_to_drsuapi         = dsdb_syntax_NTTIME_ldb_to_drsuapi,
1197         },{
1198         /* not used in w2k3 schema */
1199                 .name                   = "String(Case Sensitive)",
1200                 .ldap_oid               = "1.2.840.113556.1.4.1362",
1201                 .oMSyntax               = 27,
1202                 .attributeSyntax_oid    = "2.5.5.3",
1203                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1204                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1205         },{
1206                 .name                   = "String(Unicode)",
1207                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.15",
1208                 .oMSyntax               = 64,
1209                 .attributeSyntax_oid    = "2.5.5.12",
1210                 .drsuapi_to_ldb         = dsdb_syntax_UNICODE_drsuapi_to_ldb,
1211                 .ldb_to_drsuapi         = dsdb_syntax_UNICODE_ldb_to_drsuapi,
1212         },{
1213                 .name                   = "Interval/LargeInteger",
1214                 .ldap_oid               = "1.2.840.113556.1.4.906",
1215                 .oMSyntax               = 65,
1216                 .attributeSyntax_oid    = "2.5.5.16",
1217                 .drsuapi_to_ldb         = dsdb_syntax_INT64_drsuapi_to_ldb,
1218                 .ldb_to_drsuapi         = dsdb_syntax_INT64_ldb_to_drsuapi,
1219         },{
1220                 .name                   = "String(NT-Sec-Desc)",
1221                 .ldap_oid               = "1.2.840.113556.1.4.907",
1222                 .oMSyntax               = 66,
1223                 .attributeSyntax_oid    = "2.5.5.15",
1224                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1225                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1226         },{
1227                 .name                   = "Object(DS-DN)",
1228                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.12",
1229                 .oMSyntax               = 127,
1230                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
1231                 .attributeSyntax_oid    = "2.5.5.1",
1232                 .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
1233                 .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
1234         },{
1235                 .name                   = "Object(DN-Binary)",
1236                 .ldap_oid               = "1.2.840.113556.1.4.903",
1237                 .oMSyntax               = 127,
1238                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
1239                 .attributeSyntax_oid    = "2.5.5.7",
1240                 .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
1241                 .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
1242         },{
1243         /* not used in w2k3 schema */
1244                 .name                   = "Object(OR-Name)",
1245                 .ldap_oid               = "1.2.840.113556.1.4.1221",
1246                 .oMSyntax               = 127,
1247                 .oMObjectClass          = OMOBJECTCLASS("\x56\x06\x01\x02\x05\x0b\x1D"),
1248                 .attributeSyntax_oid    = "2.5.5.7",
1249                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1250                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1251         },{
1252         /* 
1253          * TODO: verify if DATA_BLOB is correct here...!
1254          *
1255          *       repsFrom and repsTo are the only attributes using
1256          *       this attribute syntax, but they're not replicated... 
1257          */
1258                 .name                   = "Object(Replica-Link)",
1259                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
1260                 .oMSyntax               = 127,
1261                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06"),
1262                 .attributeSyntax_oid    = "2.5.5.10",
1263                 .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
1264                 .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
1265         },{
1266                 .name                   = "Object(Presentation-Address)",
1267                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.43",
1268                 .oMSyntax               = 127,
1269                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c"),
1270                 .attributeSyntax_oid    = "2.5.5.13",
1271                 .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
1272                 .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
1273         },{
1274         /* not used in w2k3 schema */
1275                 .name                   = "Object(Access-Point)",
1276                 .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.2",
1277                 .oMSyntax               = 127,
1278                 .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"),
1279                 .attributeSyntax_oid    = "2.5.5.14",
1280                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1281                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1282         },{
1283         /* not used in w2k3 schema */
1284                 .name                   = "Object(DN-String)",
1285                 .ldap_oid               = "1.2.840.113556.1.4.904",
1286                 .oMSyntax               = 127,
1287                 .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
1288                 .attributeSyntax_oid    = "2.5.5.14",
1289                 .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
1290                 .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
1291         }
1292 };
1293
1294 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
1295 {
1296         uint32_t i;
1297
1298         for (i=0; i < ARRAY_SIZE(dsdb_syntaxes); i++) {
1299                 if (attr->oMSyntax != dsdb_syntaxes[i].oMSyntax) continue;
1300
1301                 if (attr->oMObjectClass.length != dsdb_syntaxes[i].oMObjectClass.length) continue;
1302
1303                 if (attr->oMObjectClass.length) {
1304                         int ret;
1305                         ret = memcmp(attr->oMObjectClass.data,
1306                                      dsdb_syntaxes[i].oMObjectClass.data,
1307                                      attr->oMObjectClass.length);
1308                         if (ret != 0) continue;
1309                 }
1310
1311                 if (strcmp(attr->attributeSyntax_oid, dsdb_syntaxes[i].attributeSyntax_oid) != 0) continue;
1312
1313                 return &dsdb_syntaxes[i];
1314         }
1315
1316         return NULL;
1317 }
1318
1319 WERROR dsdb_attribute_drsuapi_to_ldb(const struct dsdb_schema *schema,
1320                                      const struct drsuapi_DsReplicaAttribute *in,
1321                                      TALLOC_CTX *mem_ctx,
1322                                      struct ldb_message_element *out)
1323 {
1324         const struct dsdb_attribute *sa;
1325
1326         sa = dsdb_attribute_by_attributeID_id(schema, in->attid);
1327         if (!sa) {
1328                 return WERR_FOOBAR;
1329         }
1330
1331         return sa->syntax->drsuapi_to_ldb(schema, sa, in, mem_ctx, out);
1332 }
1333
1334 WERROR dsdb_attribute_ldb_to_drsuapi(const struct dsdb_schema *schema,
1335                                      const struct ldb_message_element *in,
1336                                      TALLOC_CTX *mem_ctx,
1337                                      struct drsuapi_DsReplicaAttribute *out)
1338 {
1339         const struct dsdb_attribute *sa;
1340
1341         sa = dsdb_attribute_by_lDAPDisplayName(schema, in->name);
1342         if (!sa) {
1343                 return WERR_FOOBAR;
1344         }
1345
1346         return sa->syntax->ldb_to_drsuapi(schema, sa, in, mem_ctx, out);
1347 }