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