root/source4/libcli/ldap/ldap_controls.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. decode_server_sort_response
  2. decode_server_sort_request
  3. decode_extended_dn_request
  4. decode_sd_flags_request
  5. decode_search_options_request
  6. decode_paged_results_request
  7. decode_dirsync_request
  8. decode_asq_control
  9. decode_domain_scope_request
  10. decode_notification_request
  11. decode_show_deleted_request
  12. decode_permissive_modify_request
  13. decode_manageDSAIT_request
  14. decode_vlv_request
  15. decode_vlv_response
  16. encode_server_sort_response
  17. encode_server_sort_request
  18. encode_extended_dn_request
  19. encode_sd_flags_request
  20. encode_search_options_request
  21. encode_paged_results_request
  22. encode_asq_control
  23. encode_dirsync_request
  24. encode_domain_scope_request
  25. encode_notification_request
  26. encode_show_deleted_request
  27. encode_permissive_modify_request
  28. encode_manageDSAIT_request
  29. encode_vlv_request
  30. encode_vlv_response
  31. encode_openldap_dereference
  32. decode_openldap_dereference
  33. samba_ldap_control_handlers

   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 
  29 static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
  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 
  75 static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
  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_BOOLEAN)) {
 130                         bool reverse;
 131                         if (!asn1_read_BOOLEAN(data, &reverse)) {
 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 
 155 static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 196 static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 230 static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 264 static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 313 static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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  */
 369 static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 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 
 430 static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 431 {
 432         if (in.length != 0) {
 433                 return false;
 434         }
 435 
 436         return true;
 437 }
 438 
 439 static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 440 {
 441         if (in.length != 0) {
 442                 return false;
 443         }
 444 
 445         return true;
 446 }
 447 
 448 static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 449 {
 450         if (in.length != 0) {
 451                 return false;
 452         }
 453 
 454         return true;
 455 }
 456 
 457 static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 458 {
 459         if (in.length != 0) {
 460                 return false;
 461         }
 462 
 463         return true;
 464 }
 465 
 466 static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 467 {
 468         if (in.length != 0) {
 469                 return false;
 470         }
 471 
 472         return true;
 473 }
 474 
 475 static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 476 {
 477         void **out = (void **)_out;
 478         DATA_BLOB assertion_value, context_id;
 479         struct asn1_data *data = asn1_init(mem_ctx);
 480         struct ldb_vlv_req_control *lvrc;
 481 
 482         if (!data) return false;
 483 
 484         if (!asn1_load(data, in)) {
 485                 return false;
 486         }
 487 
 488         lvrc = talloc(mem_ctx, struct ldb_vlv_req_control);
 489         if (!lvrc) {
 490                 return false;
 491         }
 492 
 493         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 494                 return false;
 495         }
 496 
 497         if (!asn1_read_Integer(data, &(lvrc->beforeCount))) {
 498                 return false;
 499         }
 500         
 501         if (!asn1_read_Integer(data, &(lvrc->afterCount))) {
 502                 return false;
 503         }
 504 
 505         if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
 506 
 507                 lvrc->type = 0;
 508                 
 509                 if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
 510                         return false;
 511                 }
 512 
 513                 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 514                         return false;
 515                 }
 516 
 517                 if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) {
 518                         return false;
 519                 }
 520 
 521                 if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) {
 522                         return false;
 523                 }
 524 
 525                 if (!asn1_end_tag(data)) { /*SEQUENCE*/
 526                         return false;
 527                 }
 528 
 529                 if (!asn1_end_tag(data)) { /*CONTEXT*/
 530                         return false;
 531                 }
 532 
 533         } else {
 534 
 535                 lvrc->type = 1;
 536 
 537                 if (!asn1_start_tag(data, ASN1_CONTEXT(1))) {
 538                         return false;
 539                 }
 540 
 541                 if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) {
 542                         return false;
 543                 }
 544                 lvrc->match.gtOrEq.value_len = assertion_value.length;
 545                 if (lvrc->match.gtOrEq.value_len) {
 546                         lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length);
 547 
 548                         if (!(lvrc->match.gtOrEq.value)) {
 549                                 return false;
 550                         }
 551                 } else {
 552                         lvrc->match.gtOrEq.value = NULL;
 553                 }
 554 
 555                 if (!asn1_end_tag(data)) { /*CONTEXT*/
 556                         return false;
 557                 }
 558         }
 559 
 560         if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 561                 if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
 562                         return false;
 563                 }
 564                 lvrc->ctxid_len = context_id.length;
 565                 if (lvrc->ctxid_len) {
 566                         lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length);
 567 
 568                         if (!(lvrc->contextId)) {
 569                                 return false;
 570                         }
 571                 } else {
 572                         lvrc->contextId = NULL;
 573                 }
 574         } else {
 575                 lvrc->contextId = NULL;
 576                 lvrc->ctxid_len = 0;
 577         }
 578 
 579         if (!asn1_end_tag(data)) {
 580                 return false;
 581         }
 582 
 583         *out = lvrc;
 584 
 585         return true;
 586 }
 587 
 588 static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
 589 {
 590         void **out = (void **)_out;
 591         DATA_BLOB context_id;
 592         struct asn1_data *data = asn1_init(mem_ctx);
 593         struct ldb_vlv_resp_control *lvrc;
 594 
 595         if (!data) return false;
 596 
 597         if (!asn1_load(data, in)) {
 598                 return false;
 599         }
 600 
 601         lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control);
 602         if (!lvrc) {
 603                 return false;
 604         }
 605 
 606         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 607                 return false;
 608         }
 609 
 610         if (!asn1_read_Integer(data, &(lvrc->targetPosition))) {
 611                 return false;
 612         }
 613         
 614         if (!asn1_read_Integer(data, &(lvrc->contentCount))) {
 615                 return false;
 616         }
 617         
 618         if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) {
 619                 return false;
 620         }
 621 
 622         if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 623                 if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
 624                         return false;
 625                 }
 626                 lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length);
 627                 if (!lvrc->contextId) {
 628                         return false;
 629                 }
 630                 lvrc->ctxid_len = context_id.length;
 631         } else {
 632                 lvrc->contextId = NULL;
 633                 lvrc->ctxid_len = 0;
 634         }
 635 
 636         if (!asn1_end_tag(data)) {
 637                 return false;
 638         }
 639 
 640         *out = lvrc;
 641 
 642         return true;
 643 }
 644 
 645 static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 646 {
 647         struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control);
 648         struct asn1_data *data = asn1_init(mem_ctx);
 649 
 650         if (!data) return false;
 651 
 652         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 653                 return false;
 654         }
 655 
 656         if (!asn1_write_enumerated(data, lsrc->result)) {
 657                 return false;
 658         }
 659 
 660         if (lsrc->attr_desc) {
 661                 if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) {
 662                         return false;
 663                 }
 664         }
 665 
 666         if (!asn1_pop_tag(data)) {
 667                 return false;
 668         }
 669 
 670         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 671         if (out->data == NULL) {
 672                 return false;
 673         }
 674         talloc_free(data);
 675 
 676         return true;
 677 }
 678 
 679 static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 680 {
 681         struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *);
 682         struct asn1_data *data = asn1_init(mem_ctx);
 683         int num;
 684 
 685         if (!data) return false;
 686 
 687         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 688                 return false;
 689         }
 690 
 691         for (num = 0; lssc[num]; num++) {
 692                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 693                         return false;
 694                 }
 695                 
 696                 if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) {
 697                         return false;
 698                 }
 699 
 700                 if (lssc[num]->orderingRule) {
 701                         if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) {
 702                                 return false;
 703                         }
 704                 }
 705 
 706                 if (lssc[num]->reverse) {
 707                         if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) {
 708                                 return false;
 709                         }
 710                 }
 711 
 712                 if (!asn1_pop_tag(data)) {
 713                         return false;
 714                 }
 715         }
 716 
 717         if (!asn1_pop_tag(data)) {
 718                 return false;
 719         }
 720 
 721         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 722         if (out->data == NULL) {
 723                 return false;
 724         }
 725         talloc_free(data);
 726 
 727         return true;
 728 }
 729 
 730 static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 731 {
 732         struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control);
 733         struct asn1_data *data;
 734 
 735         if (!in) {
 736                 *out = data_blob(NULL, 0);
 737                 return true;
 738         }
 739 
 740         data = asn1_init(mem_ctx);
 741 
 742         if (!data) return false;
 743 
 744         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 745                 return false;
 746         }
 747 
 748         if (!asn1_write_Integer(data, ledc->type)) {
 749                 return false;
 750         }
 751 
 752         if (!asn1_pop_tag(data)) {
 753                 return false;
 754         }
 755 
 756         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 757         if (out->data == NULL) {
 758                 return false;
 759         }
 760         talloc_free(data);
 761 
 762         return true;
 763 }
 764 
 765 static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 766 {
 767         struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control);
 768         struct asn1_data *data = asn1_init(mem_ctx);
 769 
 770         if (!data) return false;
 771 
 772         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 773                 return false;
 774         }
 775 
 776         if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) {
 777                 return false;
 778         }
 779 
 780         if (!asn1_pop_tag(data)) {
 781                 return false;
 782         }
 783 
 784         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 785         if (out->data == NULL) {
 786                 return false;
 787         }
 788         talloc_free(data);
 789 
 790         return true;
 791 }
 792 
 793 static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 794 {
 795         struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control);
 796         struct asn1_data *data = asn1_init(mem_ctx);
 797 
 798         if (!data) return false;
 799 
 800         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 801                 return false;
 802         }
 803 
 804         if (!asn1_write_Integer(data, lsoc->search_options)) {
 805                 return false;
 806         }
 807 
 808         if (!asn1_pop_tag(data)) {
 809                 return false;
 810         }
 811 
 812         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 813         if (out->data == NULL) {
 814                 return false;
 815         }
 816         talloc_free(data);
 817 
 818         return true;
 819 }
 820 
 821 static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 822 {
 823         struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control);
 824         struct asn1_data *data = asn1_init(mem_ctx);
 825 
 826         if (!data) return false;
 827 
 828         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 829                 return false;
 830         }
 831 
 832         if (!asn1_write_Integer(data, lprc->size)) {
 833                 return false;
 834         }
 835 
 836         if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) {
 837                 return false;
 838         }       
 839 
 840         if (!asn1_pop_tag(data)) {
 841                 return false;
 842         }
 843 
 844         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 845         if (out->data == NULL) {
 846                 return false;
 847         }
 848         talloc_free(data);
 849 
 850         return true;
 851 }
 852 
 853 /* seem that this controls has 2 forms one in case it is used with
 854  * a Search Request and another when used ina Search Response
 855  */
 856 static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 857 {
 858         struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control);
 859         struct asn1_data *data = asn1_init(mem_ctx);
 860 
 861         if (!data) return false;
 862 
 863         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 864                 return false;
 865         }
 866 
 867         if (lac->request) {
 868 
 869                 if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) {
 870                         return false;
 871                 }
 872         } else {
 873                 if (!asn1_write_enumerated(data, lac->result)) {
 874                         return false;
 875                 }
 876         }
 877 
 878         if (!asn1_pop_tag(data)) {
 879                 return false;
 880         }
 881 
 882         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 883         if (out->data == NULL) {
 884                 return false;
 885         }
 886         talloc_free(data);
 887 
 888         return true;
 889 }
 890 
 891 static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 892 {
 893         struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control);
 894         struct asn1_data *data = asn1_init(mem_ctx);
 895 
 896         if (!data) return false;
 897 
 898         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 899                 return false;
 900         }
 901 
 902         if (!asn1_write_Integer(data, ldc->flags)) {
 903                 return false;
 904         }
 905 
 906         if (!asn1_write_Integer(data, ldc->max_attributes)) {
 907                 return false;
 908         }
 909 
 910         if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) {
 911                 return false;
 912         }       
 913 
 914         if (!asn1_pop_tag(data)) {
 915                 return false;
 916         }
 917 
 918         *out = data_blob_talloc(mem_ctx, data->data, data->length);
 919         if (out->data == NULL) {
 920                 return false;
 921         }
 922         talloc_free(data);
 923 
 924         return true;
 925 }
 926 
 927 static bool encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 928 {
 929         if (in) {
 930                 return false;
 931         }
 932 
 933         *out = data_blob(NULL, 0);
 934         return true;
 935 }
 936 
 937 static bool encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 938 {
 939         if (in) {
 940                 return false;
 941         }
 942 
 943         *out = data_blob(NULL, 0);
 944         return true;
 945 }
 946 
 947 static bool encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 948 {
 949         if (in) {
 950                 return false;
 951         }
 952 
 953         *out = data_blob(NULL, 0);
 954         return true;
 955 }
 956 
 957 static bool encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 958 {
 959         if (in) {
 960                 return false;
 961         }
 962 
 963         *out = data_blob(NULL, 0);
 964         return true;
 965 }
 966 
 967 static bool encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 968 {
 969         if (in) {
 970                 return false;
 971         }
 972 
 973         *out = data_blob(NULL, 0);
 974         return true;
 975 }
 976 
 977 static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
 978 {
 979         struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control);
 980         struct asn1_data *data = asn1_init(mem_ctx);
 981 
 982         if (!data) return false;
 983 
 984         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 985                 return false;
 986         }
 987 
 988         if (!asn1_write_Integer(data, lvrc->beforeCount)) {
 989                 return false;
 990         }
 991 
 992         if (!asn1_write_Integer(data, lvrc->afterCount)) {
 993                 return false;
 994         }
 995 
 996         if (lvrc->type == 0) {
 997                 if (!asn1_push_tag(data, ASN1_CONTEXT(0))) {
 998                         return false;
 999                 }
1000                 
1001                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
1002                         return false;
1003                 }
1004                 
1005                 if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) {
1006                         return false;
1007                 }
1008 
1009                 if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) {
1010                         return false;
1011                 }
1012 
1013                 if (!asn1_pop_tag(data)) { /*SEQUENCE*/
1014                         return false;
1015                 }
1016 
1017                 if (!asn1_pop_tag(data)) { /*CONTEXT*/
1018                         return false;
1019                 }
1020         } else {
1021                 if (!asn1_push_tag(data, ASN1_CONTEXT(1))) {
1022                         return false;
1023                 }
1024                 
1025                 if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) {
1026                         return false;
1027                 }
1028 
1029                 if (!asn1_pop_tag(data)) { /*CONTEXT*/
1030                         return false;
1031                 }
1032         }
1033 
1034         if (lvrc->ctxid_len) {
1035                 if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
1036                         return false;
1037                 }
1038         }
1039 
1040         if (!asn1_pop_tag(data)) {
1041                 return false;
1042         }
1043 
1044         *out = data_blob_talloc(mem_ctx, data->data, data->length);
1045         if (out->data == NULL) {
1046                 return false;
1047         }
1048         talloc_free(data);
1049 
1050         return true;
1051 }
1052 
1053 static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
1054 {
1055         struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control);
1056         struct asn1_data *data = asn1_init(mem_ctx);
1057 
1058         if (!data) return false;
1059 
1060         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
1061                 return false;
1062         }
1063 
1064         if (!asn1_write_Integer(data, lvrc->targetPosition)) {
1065                 return false;
1066         }
1067 
1068         if (!asn1_write_Integer(data, lvrc->contentCount)) {
1069                 return false;
1070         }
1071 
1072         if (!asn1_write_enumerated(data, lvrc->vlv_result)) {
1073                 return false;
1074         }
1075 
1076         if (lvrc->ctxid_len) {
1077                 if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
1078                         return false;
1079                 }
1080         }
1081 
1082         if (!asn1_pop_tag(data)) {
1083                 return false;
1084         }
1085 
1086         *out = data_blob_talloc(mem_ctx, data->data, data->length);
1087         if (out->data == NULL) {
1088                 return false;
1089         }
1090         talloc_free(data);
1091 
1092         return true;
1093 }
1094 
1095 static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
     /* [<][>][^][v][top][bottom][index][help] */
1096 {
1097         struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
1098         int i,j;
1099         struct asn1_data *data = asn1_init(mem_ctx);
1100 
1101         if (!data) return false;
1102         
1103         if (!control) return false;
1104         
1105         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
1106                 return false;
1107         }
1108         
1109         for (i=0; control->dereference && control->dereference[i]; i++) {
1110                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
1111                         return false;
1112                 }
1113                 if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) {
1114                         return false;
1115                 }
1116                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
1117                         return false;
1118                 }
1119                 for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) {
1120                         if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j], 
1121                                                     strlen(control->dereference[i]->dereference_attribute[j]))) {
1122                                 return false;
1123                         }
1124                 }
1125                 
1126                 asn1_pop_tag(data);
1127                 asn1_pop_tag(data);
1128         }
1129         asn1_pop_tag(data);
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         return true;
1137 }
1138 
1139 static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
     /* [<][>][^][v][top][bottom][index][help] */
1140 {
1141         void **out = (void **)_out;
1142         struct asn1_data *data = asn1_init(mem_ctx);
1143         struct dsdb_openldap_dereference_result_control *control;
1144         struct dsdb_openldap_dereference_result **r = NULL;
1145         int i = 0;
1146         if (!data) return false;
1147 
1148         control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
1149         if (!control) return false;
1150 
1151         if (!asn1_load(data, in)) {
1152                 return false;
1153         }
1154 
1155         control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
1156         if (!control) {
1157                 return false;
1158         }
1159 
1160         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
1161                 return false;
1162         }
1163 
1164         while (asn1_tag_remaining(data) > 0) {                                  
1165                 r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2);
1166                 if (!r) {
1167                         return false;
1168                 }
1169                 r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result);
1170                 if (!r[i]) {
1171                         return false;
1172                 }
1173 
1174                 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
1175                         return false;
1176                 }
1177                 
1178                 asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
1179                 asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
1180                 if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
1181                         if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
1182                                 return false;
1183                         }
1184                         
1185                         ldap_decode_attribs_bare(r, data, &r[i]->attributes,
1186                                                  &r[i]->num_attributes);
1187                         
1188                         if (!asn1_end_tag(data)) {
1189                                 return false;
1190                         }
1191                 }
1192                 if (!asn1_end_tag(data)) {
1193                         return false;
1194                 }
1195                 i++;
1196                 r[i] = NULL;
1197         }
1198 
1199         if (!asn1_end_tag(data)) {
1200                 return false;
1201         }
1202 
1203         control->attributes = r;
1204         *out = control;
1205 
1206         return true;
1207 }
1208 
1209 static const struct ldap_control_handler ldap_known_controls[] = {
1210         { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
1211         { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
1212         { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request },
1213         { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response },
1214         { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control },
1215         { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request },
1216         { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request },
1217         { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request },
1218         { "1.2.840.113556.1.4.1413", decode_permissive_modify_request, encode_permissive_modify_request },
1219         { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request },
1220         { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request },
1221         { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request },
1222         { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request },
1223         { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request },
1224         { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response },
1225 /* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */
1226         { "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
1227 /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
1228         { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
1229         { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
1230         { NULL, NULL, NULL }
1231 };
1232 
1233 const struct ldap_control_handler *samba_ldap_control_handlers(void)
     /* [<][>][^][v][top][bottom][index][help] */
1234 {
1235         return ldap_known_controls;
1236 }
1237 

/* [<][>][^][v][top][bottom][index][help] */