1/* 2 Unix SMB/CIFS mplementation. 3 LDAP protocol helper functions for SAMBA 4 5 Copyright (C) Simo Sorce 2005 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20*/ 21 22#include "includes.h" 23#include "../lib/util/asn1.h" 24#include "libcli/ldap/ldap.h" 25#include "lib/ldb/include/ldb.h" 26#include "libcli/ldap/ldap_proto.h" 27#include "dsdb/samdb/samdb.h" 28 29static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) 30{ 31 void **out = (void **)_out; 32 DATA_BLOB attr; 33 struct asn1_data *data = asn1_init(mem_ctx); 34 struct ldb_sort_resp_control *lsrc; 35 36 if (!data) return false; 37 38 if (!asn1_load(data, in)) { 39 return false; 40 } 41 42 lsrc = talloc(mem_ctx, struct ldb_sort_resp_control); 43 if (!lsrc) { 44 return false; 45 } 46 47 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 48 return false; 49 } 50 51 if (!asn1_read_enumerated(data, &(lsrc->result))) { 52 return false; 53 } 54 55 lsrc->attr_desc = NULL; 56 if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { 57 if (!asn1_read_OctetString(data, mem_ctx, &attr)) { 58 return false; 59 } 60 lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length); 61 if (!lsrc->attr_desc) { 62 return false; 63 } 64 } 65 66 if (!asn1_end_tag(data)) { 67 return false; 68 } 69 70 *out = lsrc; 71 72 return true; 73} 74 75static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out) 76{ 77 void **out = (void **)_out; 78 DATA_BLOB attr; 79 DATA_BLOB rule; 80 struct asn1_data *data = asn1_init(mem_ctx); 81 struct ldb_server_sort_control **lssc; 82 int num; 83 84 if (!data) return false; 85 86 if (!asn1_load(data, in)) { 87 return false; 88 } 89 90 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 91 return false; 92 } 93 94 lssc = NULL; 95 96 for (num = 0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); num++) { 97 lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2); 98 if (!lssc) { 99 return false; 100 } 101 lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control); 102 if (!lssc[num]) { 103 return false; 104 } 105 106 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 107 return false; 108 } 109 110 if (!asn1_read_OctetString(data, mem_ctx, &attr)) { 111 return false; 112 } 113 114 lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length); 115 if (!lssc [num]->attributeName) { 116 return false; 117 } 118 119 if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { 120 if (!asn1_read_OctetString(data, mem_ctx, &rule)) { 121 return false; 122 } 123 lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length); 124 if (!lssc[num]->orderingRule) { 125 return false; 126 } 127 } 128 129 if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { 130 bool reverse; 131 if (!asn1_read_BOOLEAN_context(data, &reverse, 1)) { 132 return false; 133 } 134 lssc[num]->reverse = reverse; 135 } 136 137 if (!asn1_end_tag(data)) { 138 return false; 139 } 140 } 141 142 if (lssc != NULL) { 143 lssc[num] = NULL; 144 } 145 146 if (!asn1_end_tag(data)) { 147 return false; 148 } 149 150 *out = lssc; 151 152 return true; 153} 154 155static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) 156{ 157 void **out = (void **)_out; 158 struct asn1_data *data; 159 struct ldb_extended_dn_control *ledc; 160 161 /* The content of this control is optional */ 162 if (in.length == 0) { 163 *out = NULL; 164 return true; 165 } 166 167 data = asn1_init(mem_ctx); 168 if (!data) return false; 169 170 if (!asn1_load(data, in)) { 171 return false; 172 } 173 174 ledc = talloc(mem_ctx, struct ldb_extended_dn_control); 175 if (!ledc) { 176 return false; 177 } 178 179 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 180 return false; 181 } 182 183 if (!asn1_read_Integer(data, &(ledc->type))) { 184 return false; 185 } 186 187 if (!asn1_end_tag(data)) { 188 return false; 189 } 190 191 *out = ledc; 192 193 return true; 194} 195 196static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) 197{ 198 void **out = (void **)_out; 199 struct asn1_data *data = asn1_init(mem_ctx); 200 struct ldb_sd_flags_control *lsdfc; 201 202 if (!data) return false; 203 204 if (!asn1_load(data, in)) { 205 return false; 206 } 207 208 lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control); 209 if (!lsdfc) { 210 return false; 211 } 212 213 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 214 return false; 215 } 216 217 if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) { 218 return false; 219 } 220 221 if (!asn1_end_tag(data)) { 222 return false; 223 } 224 225 *out = lsdfc; 226 227 return true; 228} 229 230static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out) 231{ 232 void **out = (void **)_out; 233 struct asn1_data *data = asn1_init(mem_ctx); 234 struct ldb_search_options_control *lsoc; 235 236 if (!data) return false; 237 238 if (!asn1_load(data, in)) { 239 return false; 240 } 241 242 lsoc = talloc(mem_ctx, struct ldb_search_options_control); 243 if (!lsoc) { 244 return false; 245 } 246 247 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 248 return false; 249 } 250 251 if (!asn1_read_Integer(data, &(lsoc->search_options))) { 252 return false; 253 } 254 255 if (!asn1_end_tag(data)) { 256 return false; 257 } 258 259 *out = lsoc; 260 261 return true; 262} 263 264static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out) 265{ 266 void **out = (void **)_out; 267 DATA_BLOB cookie; 268 struct asn1_data *data = asn1_init(mem_ctx); 269 struct ldb_paged_control *lprc; 270 271 if (!data) return false; 272 273 if (!asn1_load(data, in)) { 274 return false; 275 } 276 277 lprc = talloc(mem_ctx, struct ldb_paged_control); 278 if (!lprc) { 279 return false; 280 } 281 282 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 283 return false; 284 } 285 286 if (!asn1_read_Integer(data, &(lprc->size))) { 287 return false; 288 } 289 290 if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { 291 return false; 292 } 293 lprc->cookie_len = cookie.length; 294 if (lprc->cookie_len) { 295 lprc->cookie = talloc_memdup(lprc, cookie.data, cookie.length); 296 297 if (!(lprc->cookie)) { 298 return false; 299 } 300 } else { 301 lprc->cookie = NULL; 302 } 303 304 if (!asn1_end_tag(data)) { 305 return false; 306 } 307 308 *out = lprc; 309 310 return true; 311} 312 313static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out) 314{ 315 void **out = (void **)_out; 316 DATA_BLOB cookie; 317 struct asn1_data *data = asn1_init(mem_ctx); 318 struct ldb_dirsync_control *ldc; 319 320 if (!data) return false; 321 322 if (!asn1_load(data, in)) { 323 return false; 324 } 325 326 ldc = talloc(mem_ctx, struct ldb_dirsync_control); 327 if (!ldc) { 328 return false; 329 } 330 331 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 332 return false; 333 } 334 335 if (!asn1_read_Integer(data, &(ldc->flags))) { 336 return false; 337 } 338 339 if (!asn1_read_Integer(data, &(ldc->max_attributes))) { 340 return false; 341 } 342 343 if (!asn1_read_OctetString(data, mem_ctx, &cookie)) { 344 return false; 345 } 346 ldc->cookie_len = cookie.length; 347 if (ldc->cookie_len) { 348 ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length); 349 350 if (!(ldc->cookie)) { 351 return false; 352 } 353 } else { 354 ldc->cookie = NULL; 355 } 356 357 if (!asn1_end_tag(data)) { 358 return false; 359 } 360 361 *out = ldc; 362 363 return true; 364} 365 366/* seem that this controls has 2 forms one in case it is used with 367 * a Search Request and another when used ina Search Response 368 */ 369static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) 370{ 371 void **out = (void **)_out; 372 DATA_BLOB source_attribute; 373 struct asn1_data *data = asn1_init(mem_ctx); 374 struct ldb_asq_control *lac; 375 376 if (!data) return false; 377 378 if (!asn1_load(data, in)) { 379 return false; 380 } 381 382 lac = talloc(mem_ctx, struct ldb_asq_control); 383 if (!lac) { 384 return false; 385 } 386 387 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 388 return false; 389 } 390 391 if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { 392 393 if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) { 394 return false; 395 } 396 lac->src_attr_len = source_attribute.length; 397 if (lac->src_attr_len) { 398 lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length); 399 400 if (!(lac->source_attribute)) { 401 return false; 402 } 403 } else { 404 lac->source_attribute = NULL; 405 } 406 407 lac->request = 1; 408 409 } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) { 410 411 if (!asn1_read_enumerated(data, &(lac->result))) { 412 return false; 413 } 414 415 lac->request = 0; 416 417 } else { 418 return false; 419 } 420 421 if (!asn1_end_tag(data)) { 422 return false; 423 } 424 425 *out = lac; 426 427 return true; 428} 429 430static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) 431{ 432 if (in.length != 0) { 433 return false; 434 } 435 436 return true; 437} 438 439static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) 440{ 441 if (in.length != 0) { 442 return false; 443 } 444 445 return true; 446} 447 448static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) 449{ 450 if (in.length != 0) { 451 return false; 452 } 453 454 return true; 455} 456 457static bool decode_show_recycled_request(void *mem_ctx, DATA_BLOB in, void *_out) 458{ 459 if (in.length != 0) { 460 return false; 461 } 462 463 return true; 464} 465 466static bool decode_show_deactivated_link_request(void *mem_ctx, DATA_BLOB in, void *_out) 467{ 468 if (in.length != 0) { 469 return false; 470 } 471 472 return true; 473} 474 475static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) 476{ 477 if (in.length != 0) { 478 return false; 479 } 480 481 return true; 482} 483 484static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) 485{ 486 if (in.length != 0) { 487 return false; 488 } 489 490 return true; 491} 492 493static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) 494{ 495 void **out = (void **)_out; 496 DATA_BLOB assertion_value, context_id; 497 struct asn1_data *data = asn1_init(mem_ctx); 498 struct ldb_vlv_req_control *lvrc; 499 500 if (!data) return false; 501 502 if (!asn1_load(data, in)) { 503 return false; 504 } 505 506 lvrc = talloc(mem_ctx, struct ldb_vlv_req_control); 507 if (!lvrc) { 508 return false; 509 } 510 511 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 512 return false; 513 } 514 515 if (!asn1_read_Integer(data, &(lvrc->beforeCount))) { 516 return false; 517 } 518 519 if (!asn1_read_Integer(data, &(lvrc->afterCount))) { 520 return false; 521 } 522 523 if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { 524 525 lvrc->type = 0; 526 527 if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { 528 return false; 529 } 530 531 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 532 return false; 533 } 534 535 if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) { 536 return false; 537 } 538 539 if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) { 540 return false; 541 } 542 543 if (!asn1_end_tag(data)) { /*SEQUENCE*/ 544 return false; 545 } 546 547 if (!asn1_end_tag(data)) { /*CONTEXT*/ 548 return false; 549 } 550 551 } else { 552 553 lvrc->type = 1; 554 555 if (!asn1_start_tag(data, ASN1_CONTEXT(1))) { 556 return false; 557 } 558 559 if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) { 560 return false; 561 } 562 lvrc->match.gtOrEq.value_len = assertion_value.length; 563 if (lvrc->match.gtOrEq.value_len) { 564 lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length); 565 566 if (!(lvrc->match.gtOrEq.value)) { 567 return false; 568 } 569 } else { 570 lvrc->match.gtOrEq.value = NULL; 571 } 572 573 if (!asn1_end_tag(data)) { /*CONTEXT*/ 574 return false; 575 } 576 } 577 578 if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { 579 if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { 580 return false; 581 } 582 lvrc->ctxid_len = context_id.length; 583 if (lvrc->ctxid_len) { 584 lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length); 585 586 if (!(lvrc->contextId)) { 587 return false; 588 } 589 } else { 590 lvrc->contextId = NULL; 591 } 592 } else { 593 lvrc->contextId = NULL; 594 lvrc->ctxid_len = 0; 595 } 596 597 if (!asn1_end_tag(data)) { 598 return false; 599 } 600 601 *out = lvrc; 602 603 return true; 604} 605 606static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) 607{ 608 void **out = (void **)_out; 609 DATA_BLOB context_id; 610 struct asn1_data *data = asn1_init(mem_ctx); 611 struct ldb_vlv_resp_control *lvrc; 612 613 if (!data) return false; 614 615 if (!asn1_load(data, in)) { 616 return false; 617 } 618 619 lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control); 620 if (!lvrc) { 621 return false; 622 } 623 624 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 625 return false; 626 } 627 628 if (!asn1_read_Integer(data, &(lvrc->targetPosition))) { 629 return false; 630 } 631 632 if (!asn1_read_Integer(data, &(lvrc->contentCount))) { 633 return false; 634 } 635 636 if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) { 637 return false; 638 } 639 640 if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { 641 if (!asn1_read_OctetString(data, mem_ctx, &context_id)) { 642 return false; 643 } 644 lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length); 645 if (!lvrc->contextId) { 646 return false; 647 } 648 lvrc->ctxid_len = context_id.length; 649 } else { 650 lvrc->contextId = NULL; 651 lvrc->ctxid_len = 0; 652 } 653 654 if (!asn1_end_tag(data)) { 655 return false; 656 } 657 658 *out = lvrc; 659 660 return true; 661} 662 663static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out) 664{ 665 struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control); 666 struct asn1_data *data = asn1_init(mem_ctx); 667 668 if (!data) return false; 669 670 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 671 return false; 672 } 673 674 if (!asn1_write_enumerated(data, lsrc->result)) { 675 return false; 676 } 677 678 if (lsrc->attr_desc) { 679 if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) { 680 return false; 681 } 682 } 683 684 if (!asn1_pop_tag(data)) { 685 return false; 686 } 687 688 *out = data_blob_talloc(mem_ctx, data->data, data->length); 689 if (out->data == NULL) { 690 return false; 691 } 692 talloc_free(data); 693 694 return true; 695} 696 697static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out) 698{ 699 struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *); 700 struct asn1_data *data = asn1_init(mem_ctx); 701 int num; 702 703 if (!data) return false; 704 705 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 706 return false; 707 } 708 709 /* 710 RFC2891 section 1.1: 711 SortKeyList ::= SEQUENCE OF SEQUENCE { 712 attributeType AttributeDescription, 713 orderingRule [0] MatchingRuleId OPTIONAL, 714 reverseOrder [1] BOOLEAN DEFAULT FALSE } 715 */ 716 for (num = 0; lssc[num]; num++) { 717 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 718 return false; 719 } 720 721 if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) { 722 return false; 723 } 724 725 if (lssc[num]->orderingRule) { 726 if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) { 727 return false; 728 } 729 } 730 731 if (lssc[num]->reverse) { 732 if (!asn1_write_BOOLEAN_context(data, lssc[num]->reverse, 1)) { 733 return false; 734 } 735 } 736 737 if (!asn1_pop_tag(data)) { 738 return false; 739 } 740 } 741 742 if (!asn1_pop_tag(data)) { 743 return false; 744 } 745 746 *out = data_blob_talloc(mem_ctx, data->data, data->length); 747 if (out->data == NULL) { 748 return false; 749 } 750 talloc_free(data); 751 752 return true; 753} 754 755static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out) 756{ 757 struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control); 758 struct asn1_data *data; 759 760 if (!in) { 761 *out = data_blob(NULL, 0); 762 return true; 763 } 764 765 data = asn1_init(mem_ctx); 766 767 if (!data) return false; 768 769 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 770 return false; 771 } 772 773 if (!asn1_write_Integer(data, ledc->type)) { 774 return false; 775 } 776 777 if (!asn1_pop_tag(data)) { 778 return false; 779 } 780 781 *out = data_blob_talloc(mem_ctx, data->data, data->length); 782 if (out->data == NULL) { 783 return false; 784 } 785 talloc_free(data); 786 787 return true; 788} 789 790static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out) 791{ 792 struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control); 793 struct asn1_data *data = asn1_init(mem_ctx); 794 795 if (!data) return false; 796 797 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 798 return false; 799 } 800 801 if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) { 802 return false; 803 } 804 805 if (!asn1_pop_tag(data)) { 806 return false; 807 } 808 809 *out = data_blob_talloc(mem_ctx, data->data, data->length); 810 if (out->data == NULL) { 811 return false; 812 } 813 talloc_free(data); 814 815 return true; 816} 817 818static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out) 819{ 820 struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control); 821 struct asn1_data *data = asn1_init(mem_ctx); 822 823 if (!data) return false; 824 825 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 826 return false; 827 } 828 829 if (!asn1_write_Integer(data, lsoc->search_options)) { 830 return false; 831 } 832 833 if (!asn1_pop_tag(data)) { 834 return false; 835 } 836 837 *out = data_blob_talloc(mem_ctx, data->data, data->length); 838 if (out->data == NULL) { 839 return false; 840 } 841 talloc_free(data); 842 843 return true; 844} 845 846static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out) 847{ 848 struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control); 849 struct asn1_data *data = asn1_init(mem_ctx); 850 851 if (!data) return false; 852 853 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 854 return false; 855 } 856 857 if (!asn1_write_Integer(data, lprc->size)) { 858 return false; 859 } 860 861 if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) { 862 return false; 863 } 864 865 if (!asn1_pop_tag(data)) { 866 return false; 867 } 868 869 *out = data_blob_talloc(mem_ctx, data->data, data->length); 870 if (out->data == NULL) { 871 return false; 872 } 873 talloc_free(data); 874 875 return true; 876} 877 878/* seem that this controls has 2 forms one in case it is used with 879 * a Search Request and another when used ina Search Response 880 */ 881static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out) 882{ 883 struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control); 884 struct asn1_data *data = asn1_init(mem_ctx); 885 886 if (!data) return false; 887 888 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 889 return false; 890 } 891 892 if (lac->request) { 893 894 if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) { 895 return false; 896 } 897 } else { 898 if (!asn1_write_enumerated(data, lac->result)) { 899 return false; 900 } 901 } 902 903 if (!asn1_pop_tag(data)) { 904 return false; 905 } 906 907 *out = data_blob_talloc(mem_ctx, data->data, data->length); 908 if (out->data == NULL) { 909 return false; 910 } 911 talloc_free(data); 912 913 return true; 914} 915 916static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out) 917{ 918 struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control); 919 struct asn1_data *data = asn1_init(mem_ctx); 920 921 if (!data) return false; 922 923 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 924 return false; 925 } 926 927 if (!asn1_write_Integer(data, ldc->flags)) { 928 return false; 929 } 930 931 if (!asn1_write_Integer(data, ldc->max_attributes)) { 932 return false; 933 } 934 935 if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) { 936 return false; 937 } 938 939 if (!asn1_pop_tag(data)) { 940 return false; 941 } 942 943 *out = data_blob_talloc(mem_ctx, data->data, data->length); 944 if (out->data == NULL) { 945 return false; 946 } 947 talloc_free(data); 948 949 return true; 950} 951 952static bool encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out) 953{ 954 if (in) { 955 return false; 956 } 957 958 *out = data_blob(NULL, 0); 959 return true; 960} 961 962static bool encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out) 963{ 964 if (in) { 965 return false; 966 } 967 968 *out = data_blob(NULL, 0); 969 return true; 970} 971 972static bool encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out) 973{ 974 if (in) { 975 return false; 976 } 977 978 *out = data_blob(NULL, 0); 979 return true; 980} 981 982static bool encode_show_recycled_request(void *mem_ctx, void *in, DATA_BLOB *out) 983{ 984 if (in) { 985 return false; 986 } 987 988 *out = data_blob(NULL, 0); 989 return true; 990} 991 992static bool encode_show_deactivated_link_request(void *mem_ctx, void *in, DATA_BLOB *out) 993{ 994 if (in) { 995 return false; 996 } 997 998 *out = data_blob(NULL, 0); 999 return true; 1000} 1001 1002static bool encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out) 1003{ 1004 if (in) { 1005 return false; 1006 } 1007 1008 *out = data_blob(NULL, 0); 1009 return true; 1010} 1011 1012static bool encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out) 1013{ 1014 if (in) { 1015 return false; 1016 } 1017 1018 *out = data_blob(NULL, 0); 1019 return true; 1020} 1021 1022static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out) 1023{ 1024 struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control); 1025 struct asn1_data *data = asn1_init(mem_ctx); 1026 1027 if (!data) return false; 1028 1029 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1030 return false; 1031 } 1032 1033 if (!asn1_write_Integer(data, lvrc->beforeCount)) { 1034 return false; 1035 } 1036 1037 if (!asn1_write_Integer(data, lvrc->afterCount)) { 1038 return false; 1039 } 1040 1041 if (lvrc->type == 0) { 1042 if (!asn1_push_tag(data, ASN1_CONTEXT(0))) { 1043 return false; 1044 } 1045 1046 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1047 return false; 1048 } 1049 1050 if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) { 1051 return false; 1052 } 1053 1054 if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) { 1055 return false; 1056 } 1057 1058 if (!asn1_pop_tag(data)) { /*SEQUENCE*/ 1059 return false; 1060 } 1061 1062 if (!asn1_pop_tag(data)) { /*CONTEXT*/ 1063 return false; 1064 } 1065 } else { 1066 if (!asn1_push_tag(data, ASN1_CONTEXT(1))) { 1067 return false; 1068 } 1069 1070 if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) { 1071 return false; 1072 } 1073 1074 if (!asn1_pop_tag(data)) { /*CONTEXT*/ 1075 return false; 1076 } 1077 } 1078 1079 if (lvrc->ctxid_len) { 1080 if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { 1081 return false; 1082 } 1083 } 1084 1085 if (!asn1_pop_tag(data)) { 1086 return false; 1087 } 1088 1089 *out = data_blob_talloc(mem_ctx, data->data, data->length); 1090 if (out->data == NULL) { 1091 return false; 1092 } 1093 talloc_free(data); 1094 1095 return true; 1096} 1097 1098static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out) 1099{ 1100 struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control); 1101 struct asn1_data *data = asn1_init(mem_ctx); 1102 1103 if (!data) return false; 1104 1105 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1106 return false; 1107 } 1108 1109 if (!asn1_write_Integer(data, lvrc->targetPosition)) { 1110 return false; 1111 } 1112 1113 if (!asn1_write_Integer(data, lvrc->contentCount)) { 1114 return false; 1115 } 1116 1117 if (!asn1_write_enumerated(data, lvrc->vlv_result)) { 1118 return false; 1119 } 1120 1121 if (lvrc->ctxid_len) { 1122 if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) { 1123 return false; 1124 } 1125 } 1126 1127 if (!asn1_pop_tag(data)) { 1128 return false; 1129 } 1130 1131 *out = data_blob_talloc(mem_ctx, data->data, data->length); 1132 if (out->data == NULL) { 1133 return false; 1134 } 1135 talloc_free(data); 1136 1137 return true; 1138} 1139 1140static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) 1141{ 1142 struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control); 1143 int i,j; 1144 struct asn1_data *data = asn1_init(mem_ctx); 1145 1146 if (!data) return false; 1147 1148 if (!control) return false; 1149 1150 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1151 return false; 1152 } 1153 1154 for (i=0; control->dereference && control->dereference[i]; i++) { 1155 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1156 return false; 1157 } 1158 if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) { 1159 return false; 1160 } 1161 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 1162 return false; 1163 } 1164 for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) { 1165 if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j], 1166 strlen(control->dereference[i]->dereference_attribute[j]))) { 1167 return false; 1168 } 1169 } 1170 1171 asn1_pop_tag(data); 1172 asn1_pop_tag(data); 1173 } 1174 asn1_pop_tag(data); 1175 1176 *out = data_blob_talloc(mem_ctx, data->data, data->length); 1177 if (out->data == NULL) { 1178 return false; 1179 } 1180 talloc_free(data); 1181 return true; 1182} 1183 1184static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) 1185{ 1186 void **out = (void **)_out; 1187 struct asn1_data *data = asn1_init(mem_ctx); 1188 struct dsdb_openldap_dereference_result_control *control; 1189 struct dsdb_openldap_dereference_result **r = NULL; 1190 int i = 0; 1191 if (!data) return false; 1192 1193 control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control); 1194 if (!control) return false; 1195 1196 if (!asn1_load(data, in)) { 1197 return false; 1198 } 1199 1200 control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control); 1201 if (!control) { 1202 return false; 1203 } 1204 1205 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 1206 return false; 1207 } 1208 1209 while (asn1_tag_remaining(data) > 0) { 1210 r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2); 1211 if (!r) { 1212 return false; 1213 } 1214 r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result); 1215 if (!r[i]) { 1216 return false; 1217 } 1218 1219 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 1220 return false; 1221 } 1222 1223 asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute); 1224 asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn); 1225 if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { 1226 if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { 1227 return false; 1228 } 1229 1230 ldap_decode_attribs_bare(r, data, &r[i]->attributes, 1231 &r[i]->num_attributes); 1232 1233 if (!asn1_end_tag(data)) { 1234 return false; 1235 } 1236 } 1237 if (!asn1_end_tag(data)) { 1238 return false; 1239 } 1240 i++; 1241 r[i] = NULL; 1242 } 1243 1244 if (!asn1_end_tag(data)) { 1245 return false; 1246 } 1247 1248 control->attributes = r; 1249 *out = control; 1250 1251 return true; 1252} 1253 1254static const struct ldap_control_handler ldap_known_controls[] = { 1255 { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, 1256 { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, 1257 { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, 1258 { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response }, 1259 { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control }, 1260 { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request }, 1261 { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request }, 1262 { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request }, 1263 { "1.2.840.113556.1.4.2064", decode_show_recycled_request, encode_show_recycled_request }, 1264 { "1.2.840.113556.1.4.2065", decode_show_deactivated_link_request, encode_show_deactivated_link_request }, 1265 { "1.2.840.113556.1.4.1413", decode_permissive_modify_request, encode_permissive_modify_request }, 1266 { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request }, 1267 { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request }, 1268 { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request }, 1269 { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request }, 1270 { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request }, 1271 { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response }, 1272/* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */ 1273 { "1.3.6.1.4.1.7165.4.3.2", NULL, NULL }, 1274/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */ 1275 { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL }, 1276 { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference}, 1277 { NULL, NULL, NULL } 1278}; 1279 1280const struct ldap_control_handler *samba_ldap_control_handlers(void) 1281{ 1282 return ldap_known_controls; 1283} 1284 1285