Changeset 988 for vendor/current/librpc/rpc
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/librpc/rpc
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/librpc/rpc/binding.c
r740 r988 8 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 9 9 Copyright (C) Rafal Szczesniak 2006 10 Copyright (C) Stefan Metzmacher 2014 10 11 11 12 This program is free software; you can redistribute it and/or modify … … 34 35 35 36 #define MAX_PROTSEQ 10 37 38 struct dcerpc_binding { 39 enum dcerpc_transport_t transport; 40 struct GUID object; 41 const char *object_string; 42 const char *host; 43 const char *target_hostname; 44 const char *target_principal; 45 const char *endpoint; 46 const char **options; 47 uint32_t flags; 48 uint32_t assoc_group_id; 49 char assoc_group_string[11]; /* 0x3456789a + '\0' */ 50 }; 36 51 37 52 static const struct { … … 74 89 }; 75 90 76 static const struct {91 static const struct ncacn_option { 77 92 const char *name; 78 93 uint32_t flag; … … 84 99 {"ntlm", DCERPC_AUTH_NTLM}, 85 100 {"krb5", DCERPC_AUTH_KRB5}, 101 {"schannel", DCERPC_SCHANNEL}, 86 102 {"validate", DCERPC_DEBUG_VALIDATE_BOTH}, 87 103 {"print", DCERPC_DEBUG_PRINT_BOTH}, … … 89 105 {"bigendian", DCERPC_PUSH_BIGENDIAN}, 90 106 {"smb2", DCERPC_SMB2}, 91 {"hdrsign", DCERPC_HEADER_SIGNING},92 107 {"ndr64", DCERPC_NDR64}, 93 {"localaddress", DCERPC_LOCALADDRESS}94 108 }; 109 110 static const struct ncacn_option *ncacn_option_by_name(const char *name) 111 { 112 size_t i; 113 114 for (i=0; i<ARRAY_SIZE(ncacn_options); i++) { 115 int ret; 116 117 ret = strcasecmp(ncacn_options[i].name, name); 118 if (ret != 0) { 119 continue; 120 } 121 122 return &ncacn_options[i]; 123 } 124 125 return NULL; 126 } 95 127 96 128 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) … … 106 138 char *uuidstr; 107 139 108 if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax .uuid)) {140 if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr.uuid)) { 109 141 return "NDR"; 110 142 } 111 143 112 if (GUID_equal(&syntax.uuid, &ndr 64_transfer_syntax.uuid)) {144 if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr64.uuid)) { 113 145 return "NDR64"; 114 146 } … … 179 211 { 180 212 char *s = talloc_strdup(mem_ctx, ""); 213 char *o = s; 181 214 int i; 182 215 const char *t_name = NULL; 216 bool option_section = false; 217 const char *target_hostname = NULL; 183 218 184 219 if (b->transport != NCA_UNKNOWN) { 185 220 t_name = derpc_transport_string_by_transport(b->transport); 186 221 if (!t_name) { 187 return NULL; 188 } 189 } 190 191 if (!GUID_all_zero(&b->object.uuid)) { 192 s = talloc_asprintf(s, "%s@", 193 GUID_string(mem_ctx, &b->object.uuid)); 222 talloc_free(o); 223 return NULL; 224 } 225 } 226 227 if (!GUID_all_zero(&b->object)) { 228 o = s; 229 s = talloc_asprintf_append_buffer(s, "%s@", 230 GUID_string(mem_ctx, &b->object)); 231 if (s == NULL) { 232 talloc_free(o); 233 return NULL; 234 } 194 235 } 195 236 196 237 if (t_name != NULL) { 238 o = s; 197 239 s = talloc_asprintf_append_buffer(s, "%s:", t_name); 198 240 if (s == NULL) { 241 talloc_free(o); 199 242 return NULL; 200 243 } … … 202 245 203 246 if (b->host) { 247 o = s; 204 248 s = talloc_asprintf_append_buffer(s, "%s", b->host); 205 } 206 207 if (!b->endpoint && !b->options && !b->flags) { 249 if (s == NULL) { 250 talloc_free(o); 251 return NULL; 252 } 253 } 254 255 target_hostname = b->target_hostname; 256 if (target_hostname != NULL && b->host != NULL) { 257 if (strcmp(target_hostname, b->host) == 0) { 258 target_hostname = NULL; 259 } 260 } 261 262 if (b->endpoint) { 263 option_section = true; 264 } else if (target_hostname) { 265 option_section = true; 266 } else if (b->target_principal) { 267 option_section = true; 268 } else if (b->assoc_group_id != 0) { 269 option_section = true; 270 } else if (b->options) { 271 option_section = true; 272 } else if (b->flags) { 273 option_section = true; 274 } 275 276 if (!option_section) { 208 277 return s; 209 278 } 210 279 280 o = s; 211 281 s = talloc_asprintf_append_buffer(s, "["); 282 if (s == NULL) { 283 talloc_free(o); 284 return NULL; 285 } 212 286 213 287 if (b->endpoint) { 288 o = s; 214 289 s = talloc_asprintf_append_buffer(s, "%s", b->endpoint); 215 } 216 217 /* this is a *really* inefficent way of dealing with strings, 218 but this is rarely called and the strings are always short, 219 so I don't care */ 290 if (s == NULL) { 291 talloc_free(o); 292 return NULL; 293 } 294 } 295 296 for (i=0;i<ARRAY_SIZE(ncacn_options);i++) { 297 if (!(b->flags & ncacn_options[i].flag)) { 298 continue; 299 } 300 301 o = s; 302 s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name); 303 if (s == NULL) { 304 talloc_free(o); 305 return NULL; 306 } 307 } 308 309 if (target_hostname) { 310 o = s; 311 s = talloc_asprintf_append_buffer(s, ",target_hostname=%s", 312 b->target_hostname); 313 if (s == NULL) { 314 talloc_free(o); 315 return NULL; 316 } 317 } 318 319 if (b->target_principal) { 320 o = s; 321 s = talloc_asprintf_append_buffer(s, ",target_principal=%s", 322 b->target_principal); 323 if (s == NULL) { 324 talloc_free(o); 325 return NULL; 326 } 327 } 328 329 if (b->assoc_group_id != 0) { 330 o = s; 331 s = talloc_asprintf_append_buffer(s, ",assoc_group_id=0x%08x", 332 b->assoc_group_id); 333 if (s == NULL) { 334 talloc_free(o); 335 return NULL; 336 } 337 } 338 220 339 for (i=0;b->options && b->options[i];i++) { 340 o = s; 221 341 s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]); 222 if (!s) return NULL; 223 } 224 225 for (i=0;i<ARRAY_SIZE(ncacn_options);i++) { 226 if (b->flags & ncacn_options[i].flag) { 227 if (ncacn_options[i].flag == DCERPC_LOCALADDRESS && b->localaddress) { 228 s = talloc_asprintf_append_buffer(s, ",%s=%s", ncacn_options[i].name, 229 b->localaddress); 230 } else { 231 s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name); 232 } 233 if (!s) return NULL; 234 } 235 } 236 342 if (s == NULL) { 343 talloc_free(o); 344 return NULL; 345 } 346 } 347 348 o = s; 237 349 s = talloc_asprintf_append_buffer(s, "]"); 350 if (s == NULL) { 351 talloc_free(o); 352 return NULL; 353 } 238 354 239 355 return s; … … 243 359 parse a binding string into a dcerpc_binding structure 244 360 */ 245 _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) 246 { 361 _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *_s, struct dcerpc_binding **b_out) 362 { 363 char *_t; 247 364 struct dcerpc_binding *b; 248 char *options; 365 char *s; 366 char *options = NULL; 249 367 char *p; 250 int i, j, comma_count; 368 size_t i; 369 NTSTATUS status; 251 370 252 371 b = talloc_zero(mem_ctx, struct dcerpc_binding); … … 255 374 } 256 375 376 _t = talloc_strdup(b, _s); 377 if (_t == NULL) { 378 talloc_free(b); 379 return NT_STATUS_NO_MEMORY; 380 } 381 382 s = _t; 383 384 p = strchr(s, '['); 385 if (p) { 386 *p = '\0'; 387 options = p + 1; 388 if (options[strlen(options)-1] != ']') { 389 talloc_free(b); 390 return NT_STATUS_INVALID_PARAMETER_MIX; 391 } 392 options[strlen(options)-1] = 0; 393 } 394 257 395 p = strchr(s, '@'); 258 396 259 397 if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ 260 NTSTATUS status; 261 DATA_BLOB blob = data_blob(s, 36); 262 status = GUID_from_data_blob(&blob, &b->object.uuid); 263 264 if (NT_STATUS_IS_ERR(status)) { 265 DEBUG(0, ("Failed parsing UUID\n")); 398 *p = '\0'; 399 400 status = dcerpc_binding_set_string_option(b, "object", s); 401 if (!NT_STATUS_IS_OK(status)) { 402 talloc_free(b); 266 403 return status; 267 404 } 268 405 269 406 s = p + 1; 270 } else { 271 ZERO_STRUCT(b->object); 272 } 273 274 b->object.if_version = 0; 407 } 275 408 276 409 p = strchr(s, ':'); … … 278 411 if (p == NULL) { 279 412 b->transport = NCA_UNKNOWN; 413 } else if (is_ipaddress_v6(s)) { 414 b->transport = NCA_UNKNOWN; 280 415 } else { 281 char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); 282 if (!type) { 416 *p = '\0'; 417 418 status = dcerpc_binding_set_string_option(b, "transport", s); 419 if (!NT_STATUS_IS_OK(status)) { 420 talloc_free(b); 421 return status; 422 } 423 424 s = p + 1; 425 } 426 427 if (strlen(s) > 0) { 428 status = dcerpc_binding_set_string_option(b, "host", s); 429 if (!NT_STATUS_IS_OK(status)) { 430 talloc_free(b); 431 return status; 432 } 433 434 b->target_hostname = talloc_strdup(b, b->host); 435 if (b->target_hostname == NULL) { 436 talloc_free(b); 283 437 return NT_STATUS_NO_MEMORY; 284 438 } 285 286 for (i=0;i<ARRAY_SIZE(transports);i++) { 287 if (strcasecmp(type, transports[i].name) == 0) { 288 b->transport = transports[i].transport; 289 break; 439 } 440 441 for (i=0; options != NULL; i++) { 442 const char *name = options; 443 const char *value = NULL; 444 445 p = strchr(options, ','); 446 if (p != NULL) { 447 *p = '\0'; 448 options = p+1; 449 } else { 450 options = NULL; 451 } 452 453 p = strchr(name, '='); 454 if (p != NULL) { 455 *p = '\0'; 456 value = p + 1; 457 } 458 459 if (value == NULL) { 460 /* 461 * If it's not a key=value pair 462 * it might be a ncacn_option 463 * or if it's the first option 464 * it's the endpoint. 465 */ 466 const struct ncacn_option *no = NULL; 467 468 value = name; 469 470 no = ncacn_option_by_name(name); 471 if (no == NULL) { 472 if (i > 0) { 473 /* 474 * we don't allow unknown options 475 */ 476 return NT_STATUS_INVALID_PARAMETER_MIX; 477 } 478 479 /* 480 * This is the endpoint 481 */ 482 name = "endpoint"; 483 if (strlen(value) == 0) { 484 value = NULL; 485 } 290 486 } 291 487 } 292 488 293 if (i==ARRAY_SIZE(transports)) { 294 DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); 295 return NT_STATUS_INVALID_PARAMETER; 296 } 297 298 talloc_free(type); 299 300 s = p+1; 301 } 302 303 p = strchr(s, '['); 304 if (p) { 305 b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); 306 options = talloc_strdup(mem_ctx, p+1); 307 if (options[strlen(options)-1] != ']') { 308 return NT_STATUS_INVALID_PARAMETER; 309 } 310 options[strlen(options)-1] = 0; 489 status = dcerpc_binding_set_string_option(b, name, value); 490 if (!NT_STATUS_IS_OK(status)) { 491 talloc_free(b); 492 return status; 493 } 494 } 495 496 talloc_free(_t); 497 *b_out = b; 498 return NT_STATUS_OK; 499 } 500 501 _PUBLIC_ struct GUID dcerpc_binding_get_object(const struct dcerpc_binding *b) 502 { 503 return b->object; 504 } 505 506 _PUBLIC_ NTSTATUS dcerpc_binding_set_object(struct dcerpc_binding *b, 507 struct GUID object) 508 { 509 char *tmp = discard_const_p(char, b->object_string); 510 511 if (GUID_all_zero(&object)) { 512 talloc_free(tmp); 513 b->object_string = NULL; 514 ZERO_STRUCT(b->object); 515 return NT_STATUS_OK; 516 } 517 518 b->object_string = GUID_string(b, &object); 519 if (b->object_string == NULL) { 520 b->object_string = tmp; 521 return NT_STATUS_NO_MEMORY; 522 } 523 talloc_free(tmp); 524 525 b->object = object; 526 return NT_STATUS_OK; 527 } 528 529 _PUBLIC_ enum dcerpc_transport_t dcerpc_binding_get_transport(const struct dcerpc_binding *b) 530 { 531 return b->transport; 532 } 533 534 _PUBLIC_ NTSTATUS dcerpc_binding_set_transport(struct dcerpc_binding *b, 535 enum dcerpc_transport_t transport) 536 { 537 NTSTATUS status; 538 539 /* 540 * TODO: we may want to check the transport value is 541 * wellknown. 542 */ 543 if (b->transport == transport) { 544 return NT_STATUS_OK; 545 } 546 547 /* 548 * This implicitly resets the endpoint 549 * as the endpoint is transport specific. 550 * 551 * It also resets the assoc group as it's 552 * also endpoint specific. 553 * 554 * TODO: in future we may reset more options 555 * here. 556 */ 557 status = dcerpc_binding_set_string_option(b, "endpoint", NULL); 558 if (!NT_STATUS_IS_OK(status)) { 559 return status; 560 } 561 562 b->assoc_group_id = 0; 563 564 b->transport = transport; 565 return NT_STATUS_OK; 566 } 567 568 _PUBLIC_ void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b, 569 enum dcerpc_AuthType *_auth_type, 570 enum dcerpc_AuthLevel *_auth_level) 571 { 572 enum dcerpc_AuthType auth_type; 573 enum dcerpc_AuthLevel auth_level; 574 575 if (b->flags & DCERPC_AUTH_SPNEGO) { 576 auth_type = DCERPC_AUTH_TYPE_SPNEGO; 577 } else if (b->flags & DCERPC_AUTH_KRB5) { 578 auth_type = DCERPC_AUTH_TYPE_KRB5; 579 } else if (b->flags & DCERPC_SCHANNEL) { 580 auth_type = DCERPC_AUTH_TYPE_SCHANNEL; 581 } else if (b->flags & DCERPC_AUTH_NTLM) { 582 auth_type = DCERPC_AUTH_TYPE_NTLMSSP; 311 583 } else { 312 b->host = talloc_strdup(b, s); 313 options = NULL; 314 } 315 if (!b->host) { 584 auth_type = DCERPC_AUTH_TYPE_NONE; 585 } 586 587 if (b->flags & DCERPC_SEAL) { 588 auth_level = DCERPC_AUTH_LEVEL_PRIVACY; 589 } else if (b->flags & DCERPC_SIGN) { 590 auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; 591 } else if (b->flags & DCERPC_CONNECT) { 592 auth_level = DCERPC_AUTH_LEVEL_CONNECT; 593 } else if (auth_type != DCERPC_AUTH_TYPE_NONE) { 594 auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; 595 } else { 596 auth_level = DCERPC_AUTH_LEVEL_NONE; 597 } 598 599 if (_auth_type != NULL) { 600 *_auth_type = auth_type; 601 } 602 603 if (_auth_level != NULL) { 604 *_auth_level = auth_level; 605 } 606 } 607 608 _PUBLIC_ uint32_t dcerpc_binding_get_assoc_group_id(const struct dcerpc_binding *b) 609 { 610 return b->assoc_group_id; 611 } 612 613 _PUBLIC_ NTSTATUS dcerpc_binding_set_assoc_group_id(struct dcerpc_binding *b, 614 uint32_t assoc_group_id) 615 { 616 b->assoc_group_id = assoc_group_id; 617 return NT_STATUS_OK; 618 } 619 620 _PUBLIC_ struct ndr_syntax_id dcerpc_binding_get_abstract_syntax(const struct dcerpc_binding *b) 621 { 622 const char *s = dcerpc_binding_get_string_option(b, "abstract_syntax"); 623 bool ok; 624 struct ndr_syntax_id id; 625 626 if (s == NULL) { 627 return ndr_syntax_id_null; 628 } 629 630 ok = ndr_syntax_id_from_string(s, &id); 631 if (!ok) { 632 return ndr_syntax_id_null; 633 } 634 635 return id; 636 } 637 638 _PUBLIC_ NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b, 639 const struct ndr_syntax_id *syntax) 640 { 641 NTSTATUS status; 642 char *s = NULL; 643 644 if (syntax == NULL) { 645 status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL); 646 if (!NT_STATUS_IS_OK(status)) { 647 return status; 648 } 649 650 return NT_STATUS_OK; 651 } 652 653 if (ndr_syntax_id_equal(&ndr_syntax_id_null, syntax)) { 654 status = dcerpc_binding_set_string_option(b, "abstract_syntax", NULL); 655 if (!NT_STATUS_IS_OK(status)) { 656 return status; 657 } 658 659 return NT_STATUS_OK; 660 } 661 662 s = ndr_syntax_id_to_string(b, syntax); 663 if (s == NULL) { 316 664 return NT_STATUS_NO_MEMORY; 317 665 } 318 666 319 b->target_hostname = b->host; 320 321 b->options = NULL; 322 b->flags = 0; 323 b->assoc_group_id = 0; 324 b->endpoint = NULL; 325 b->localaddress = NULL; 326 327 if (!options) { 328 *b_out = b; 329 return NT_STATUS_OK; 330 } 331 332 comma_count = count_chars(options, ','); 333 334 b->options = talloc_array(b, const char *, comma_count+2); 335 if (!b->options) { 667 status = dcerpc_binding_set_string_option(b, "abstract_syntax", s); 668 TALLOC_FREE(s); 669 if (!NT_STATUS_IS_OK(status)) { 670 return status; 671 } 672 673 return NT_STATUS_OK; 674 } 675 676 _PUBLIC_ const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b, 677 const char *name) 678 { 679 struct { 680 const char *name; 681 const char *value; 682 #define _SPECIAL(x) { .name = #x, .value = b->x, } 683 } specials[] = { 684 { .name = "object", .value = b->object_string, }, 685 _SPECIAL(host), 686 _SPECIAL(endpoint), 687 _SPECIAL(target_hostname), 688 _SPECIAL(target_principal), 689 #undef _SPECIAL 690 }; 691 const struct ncacn_option *no = NULL; 692 size_t name_len = strlen(name); 693 size_t i; 694 int ret; 695 696 ret = strcmp(name, "transport"); 697 if (ret == 0) { 698 return derpc_transport_string_by_transport(b->transport); 699 } 700 701 ret = strcmp(name, "assoc_group_id"); 702 if (ret == 0) { 703 char *tmp = discard_const_p(char, b->assoc_group_string); 704 705 if (b->assoc_group_id == 0) { 706 return NULL; 707 } 708 709 snprintf(tmp, sizeof(b->assoc_group_string), 710 "0x%08x", b->assoc_group_id); 711 return (const char *)b->assoc_group_string; 712 } 713 714 for (i=0; i < ARRAY_SIZE(specials); i++) { 715 ret = strcmp(specials[i].name, name); 716 if (ret != 0) { 717 continue; 718 } 719 720 return specials[i].value; 721 } 722 723 no = ncacn_option_by_name(name); 724 if (no != NULL) { 725 if (b->flags & no->flag) { 726 return no->name; 727 } 728 729 return NULL; 730 } 731 732 if (b->options == NULL) { 733 return NULL; 734 } 735 736 for (i=0; b->options[i]; i++) { 737 const char *o = b->options[i]; 738 const char *vs = NULL; 739 740 ret = strncmp(name, o, name_len); 741 if (ret != 0) { 742 continue; 743 } 744 745 if (o[name_len] != '=') { 746 continue; 747 } 748 749 vs = &o[name_len + 1]; 750 751 return vs; 752 } 753 754 return NULL; 755 } 756 757 _PUBLIC_ char *dcerpc_binding_copy_string_option(TALLOC_CTX *mem_ctx, 758 const struct dcerpc_binding *b, 759 const char *name) 760 { 761 const char *c = dcerpc_binding_get_string_option(b, name); 762 char *v; 763 764 if (c == NULL) { 765 errno = ENOENT; 766 return NULL; 767 } 768 769 v = talloc_strdup(mem_ctx, c); 770 if (v == NULL) { 771 errno = ENOMEM; 772 return NULL; 773 } 774 775 return v; 776 } 777 778 _PUBLIC_ NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b, 779 const char *name, 780 const char *value) 781 { 782 struct { 783 const char *name; 784 const char **ptr; 785 #define _SPECIAL(x) { .name = #x, .ptr = &b->x, } 786 } specials[] = { 787 _SPECIAL(host), 788 _SPECIAL(endpoint), 789 _SPECIAL(target_hostname), 790 _SPECIAL(target_principal), 791 #undef _SPECIAL 792 }; 793 const struct ncacn_option *no = NULL; 794 size_t name_len = strlen(name); 795 const char *opt = NULL; 796 char *tmp; 797 size_t i; 798 int ret; 799 800 /* 801 * Note: value == NULL, means delete it. 802 * value != NULL means add or reset. 803 */ 804 805 ret = strcmp(name, "transport"); 806 if (ret == 0) { 807 enum dcerpc_transport_t t = dcerpc_transport_by_name(value); 808 809 if (t == NCA_UNKNOWN && value != NULL) { 810 return NT_STATUS_INVALID_PARAMETER_MIX; 811 } 812 813 return dcerpc_binding_set_transport(b, t); 814 } 815 816 ret = strcmp(name, "object"); 817 if (ret == 0) { 818 NTSTATUS status; 819 struct GUID uuid = GUID_zero(); 820 821 if (value != NULL) { 822 DATA_BLOB blob; 823 blob = data_blob_string_const(value); 824 if (blob.length != 36) { 825 return NT_STATUS_INVALID_PARAMETER_MIX; 826 } 827 828 status = GUID_from_data_blob(&blob, &uuid); 829 if (!NT_STATUS_IS_OK(status)) { 830 return status; 831 } 832 } 833 834 return dcerpc_binding_set_object(b, uuid); 835 } 836 837 ret = strcmp(name, "assoc_group_id"); 838 if (ret == 0) { 839 uint32_t assoc_group_id = 0; 840 841 if (value != NULL) { 842 char c; 843 844 ret = sscanf(value, "0x%08x%c", &assoc_group_id, &c); 845 if (ret != 1) { 846 return NT_STATUS_INVALID_PARAMETER_MIX; 847 } 848 } 849 850 return dcerpc_binding_set_assoc_group_id(b, assoc_group_id); 851 } 852 853 for (i=0; i < ARRAY_SIZE(specials); i++) { 854 ret = strcmp(specials[i].name, name); 855 if (ret != 0) { 856 continue; 857 } 858 859 tmp = discard_const_p(char, *specials[i].ptr); 860 861 if (value == NULL) { 862 talloc_free(tmp); 863 *specials[i].ptr = NULL; 864 return NT_STATUS_OK; 865 } 866 867 if (value[0] == '\0') { 868 return NT_STATUS_INVALID_PARAMETER_MIX; 869 } 870 871 *specials[i].ptr = talloc_strdup(b, value); 872 if (*specials[i].ptr == NULL) { 873 *specials[i].ptr = tmp; 874 return NT_STATUS_NO_MEMORY; 875 } 876 talloc_free(tmp); 877 878 return NT_STATUS_OK; 879 } 880 881 no = ncacn_option_by_name(name); 882 if (no != NULL) { 883 if (value == NULL) { 884 b->flags &= ~no->flag; 885 return NT_STATUS_OK; 886 } 887 888 ret = strcasecmp(no->name, value); 889 if (ret != 0) { 890 return NT_STATUS_INVALID_PARAMETER_MIX; 891 } 892 893 b->flags |= no->flag; 894 return NT_STATUS_OK; 895 } 896 897 for (i=0; b->options && b->options[i]; i++) { 898 const char *o = b->options[i]; 899 900 ret = strncmp(name, o, name_len); 901 if (ret != 0) { 902 continue; 903 } 904 905 if (o[name_len] != '=') { 906 continue; 907 } 908 909 opt = o; 910 break; 911 } 912 913 if (opt == NULL) { 914 const char **n; 915 916 if (value == NULL) { 917 return NT_STATUS_OK; 918 } 919 920 n = talloc_realloc(b, b->options, const char *, i + 2); 921 if (n == NULL) { 922 return NT_STATUS_NO_MEMORY; 923 } 924 n[i] = NULL; 925 n[i + 1] = NULL; 926 b->options = n; 927 } 928 929 tmp = discard_const_p(char, opt); 930 931 if (value == NULL) { 932 for (;b->options[i];i++) { 933 b->options[i] = b->options[i+1]; 934 } 935 talloc_free(tmp); 936 return NT_STATUS_OK; 937 } 938 939 b->options[i] = talloc_asprintf(b->options, "%s=%s", 940 name, value); 941 if (b->options[i] == NULL) { 942 b->options[i] = tmp; 336 943 return NT_STATUS_NO_MEMORY; 337 944 } 338 945 339 for (i=0; (p = strchr(options, ',')); i++) { 340 b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); 341 if (!b->options[i]) { 342 return NT_STATUS_NO_MEMORY; 343 } 344 options = p+1; 345 } 346 b->options[i] = options; 347 b->options[i+1] = NULL; 348 349 /* some options are pre-parsed for convenience */ 350 for (i=0;b->options[i];i++) { 351 for (j=0;j<ARRAY_SIZE(ncacn_options);j++) { 352 size_t opt_len = strlen(ncacn_options[j].name); 353 if (strncasecmp(ncacn_options[j].name, b->options[i], opt_len) == 0) { 354 int k; 355 char c = b->options[i][opt_len]; 356 357 if (ncacn_options[j].flag == DCERPC_LOCALADDRESS && c == '=') { 358 b->localaddress = talloc_strdup(b, &b->options[i][opt_len+1]); 359 } else if (c != 0) { 360 continue; 361 } 362 363 b->flags |= ncacn_options[j].flag; 364 for (k=i;b->options[k];k++) { 365 b->options[k] = b->options[k+1]; 366 } 367 i--; 368 break; 369 } 370 } 371 } 372 373 if (b->options[0]) { 374 /* Endpoint is first option */ 375 b->endpoint = b->options[0]; 376 if (strlen(b->endpoint) == 0) b->endpoint = NULL; 377 378 for (i=0;b->options[i];i++) { 379 b->options[i] = b->options[i+1]; 380 } 381 } 382 383 if (b->options[0] == NULL) 384 b->options = NULL; 385 386 *b_out = b; 946 return NT_STATUS_OK; 947 } 948 949 _PUBLIC_ uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b) 950 { 951 return b->flags; 952 } 953 954 _PUBLIC_ NTSTATUS dcerpc_binding_set_flags(struct dcerpc_binding *b, 955 uint32_t additional, 956 uint32_t clear) 957 { 958 /* 959 * TODO: in future we may want to reject invalid combinations 960 */ 961 b->flags &= ~clear; 962 b->flags |= additional; 963 387 964 return NT_STATUS_OK; 388 965 } … … 425 1002 { 426 1003 DATA_BLOB blob; 427 struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx); 1004 enum ndr_err_code ndr_err; 1005 struct ndr_push *ndr; 1006 1007 ndr = ndr_push_init_ctx(mem_ctx); 1008 if (ndr == NULL) { 1009 return data_blob_null; 1010 } 428 1011 429 1012 ndr->flags |= LIBNDR_FLAG_NOALIGN; 430 1013 431 ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); 432 ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); 1014 ndr_err = ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); 1015 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1016 return data_blob_null; 1017 } 1018 ndr_err = ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); 1019 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1020 return data_blob_null; 1021 } 433 1022 434 1023 blob = ndr_push_blob(ndr); … … 464 1053 } 465 1054 466 c onst char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)1055 char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) 467 1056 { 468 1057 switch (epm_floor->lhs.protocol) { … … 531 1120 const char *data) 532 1121 { 1122 if (data == NULL) { 1123 data = ""; 1124 } 1125 533 1126 switch (epm_floor->lhs.protocol) { 534 1127 case EPM_PROTOCOL_TCP: … … 545 1138 546 1139 case EPM_PROTOCOL_IP: 1140 if (!is_ipaddress_v4(data)) { 1141 data = "0.0.0.0"; 1142 } 547 1143 epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data); 548 1144 NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr); … … 631 1227 } 632 1228 633 for (j = 0; j < transports[i].num_protocols ; j++) {1229 for (j = 0; j < transports[i].num_protocols && j < MAX_PROTSEQ; j++) { 634 1230 if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) { 635 1231 break; … … 658 1254 } 659 1255 1256 _PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_name(const char *name) 1257 { 1258 size_t i; 1259 1260 if (name == NULL) { 1261 return NCA_UNKNOWN; 1262 } 1263 1264 for (i=0; i<ARRAY_SIZE(transports);i++) { 1265 if (strcasecmp(name, transports[i].name) == 0) { 1266 return transports[i].transport; 1267 } 1268 } 1269 1270 return NCA_UNKNOWN; 1271 } 1272 660 1273 _PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, 661 1274 struct epm_tower *tower, … … 663 1276 { 664 1277 NTSTATUS status; 665 struct dcerpc_binding *binding; 1278 struct dcerpc_binding *b; 1279 enum dcerpc_transport_t transport; 1280 struct ndr_syntax_id abstract_syntax; 1281 char *endpoint = NULL; 1282 char *host = NULL; 666 1283 667 1284 /* … … 674 1291 } 675 1292 676 binding = talloc_zero(mem_ctx, struct dcerpc_binding); 677 NT_STATUS_HAVE_NO_MEMORY(binding); 678 679 ZERO_STRUCT(binding->object); 680 binding->options = NULL; 681 binding->host = NULL; 682 binding->target_hostname = NULL; 683 binding->flags = 0; 684 binding->assoc_group_id = 0; 685 686 binding->transport = dcerpc_transport_by_tower(tower); 687 688 if (binding->transport == (unsigned int)-1) { 1293 status = dcerpc_parse_binding(mem_ctx, "", &b); 1294 if (!NT_STATUS_IS_OK(status)) { 1295 return status; 1296 } 1297 1298 transport = dcerpc_transport_by_tower(tower); 1299 if (transport == NCA_UNKNOWN) { 1300 talloc_free(b); 689 1301 return NT_STATUS_NOT_SUPPORTED; 690 1302 } 691 1303 692 /* Set object uuid */ 693 status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object); 694 1304 status = dcerpc_binding_set_transport(b, transport); 695 1305 if (!NT_STATUS_IS_OK(status)) { 696 DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status)));1306 talloc_free(b); 697 1307 return status; 698 1308 } 699 1309 1310 /* Set abstract syntax */ 1311 status = dcerpc_floor_get_lhs_data(&tower->floors[0], &abstract_syntax); 1312 if (!NT_STATUS_IS_OK(status)) { 1313 talloc_free(b); 1314 return status; 1315 } 1316 1317 status = dcerpc_binding_set_abstract_syntax(b, &abstract_syntax); 1318 if (!NT_STATUS_IS_OK(status)) { 1319 talloc_free(b); 1320 return status; 1321 } 1322 700 1323 /* Ignore floor 1, it contains the NDR version info */ 701 1324 702 binding->options = NULL;703 704 1325 /* Set endpoint */ 1326 errno = 0; 705 1327 if (tower->num_floors >= 4) { 706 binding->endpoint = dcerpc_floor_get_rhs_data(binding, &tower->floors[3]); 707 } else { 708 binding->endpoint = NULL; 709 } 1328 endpoint = dcerpc_floor_get_rhs_data(b, &tower->floors[3]); 1329 } 1330 if (errno != 0) { 1331 int saved_errno = errno; 1332 talloc_free(b); 1333 return map_nt_error_from_unix_common(saved_errno); 1334 } 1335 1336 status = dcerpc_binding_set_string_option(b, "endpoint", endpoint); 1337 if (!NT_STATUS_IS_OK(status)) { 1338 talloc_free(b); 1339 return status; 1340 } 1341 TALLOC_FREE(endpoint); 710 1342 711 1343 /* Set network address */ 1344 errno = 0; 712 1345 if (tower->num_floors >= 5) { 713 binding->host = dcerpc_floor_get_rhs_data(binding, &tower->floors[4]); 714 NT_STATUS_HAVE_NO_MEMORY(binding->host); 715 binding->target_hostname = binding->host; 716 } 717 *b_out = binding; 1346 host = dcerpc_floor_get_rhs_data(b, &tower->floors[4]); 1347 } 1348 if (errno != 0) { 1349 int saved_errno = errno; 1350 talloc_free(b); 1351 return map_nt_error_from_unix_common(saved_errno); 1352 } 1353 1354 status = dcerpc_binding_set_string_option(b, "host", host); 1355 if (!NT_STATUS_IS_OK(status)) { 1356 talloc_free(b); 1357 return status; 1358 } 1359 status = dcerpc_binding_set_string_option(b, "target_hostname", host); 1360 if (!NT_STATUS_IS_OK(status)) { 1361 talloc_free(b); 1362 return status; 1363 } 1364 TALLOC_FREE(host); 1365 1366 *b_out = b; 718 1367 return NT_STATUS_OK; 719 1368 } … … 735 1384 n->assoc_group_id = b->assoc_group_id; 736 1385 1386 if (b->object_string != NULL) { 1387 n->object_string = talloc_strdup(n, b->object_string); 1388 if (n->object_string == NULL) { 1389 talloc_free(n); 1390 return NULL; 1391 } 1392 } 737 1393 if (b->host != NULL) { 738 1394 n->host = talloc_strdup(n, b->host); … … 754 1410 n->target_principal = talloc_strdup(n, b->target_principal); 755 1411 if (n->target_principal == NULL) { 756 talloc_free(n);757 return NULL;758 }759 }760 761 if (b->localaddress != NULL) {762 n->localaddress = talloc_strdup(n, b->localaddress);763 if (n->localaddress == NULL) {764 1412 talloc_free(n); 765 1413 return NULL; … … 805 1453 const enum epm_protocol *protseq = NULL; 806 1454 int num_protocols = -1, i; 1455 struct ndr_syntax_id abstract_syntax; 807 1456 NTSTATUS status; 808 1457 … … 827 1476 tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; 828 1477 829 tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors, &binding->object); 1478 abstract_syntax = dcerpc_binding_get_abstract_syntax(binding); 1479 tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors, 1480 &abstract_syntax); 830 1481 831 1482 if (!dcerpc_floor_pack_rhs_if_version_data( 832 tower->floors, & binding->object,1483 tower->floors, &abstract_syntax, 833 1484 &tower->floors[0].rhs.uuid.unknown)) { 834 1485 return NT_STATUS_NO_MEMORY; … … 839 1490 840 1491 tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(tower->floors, 841 &ndr_transfer_syntax );1492 &ndr_transfer_syntax_ndr); 842 1493 843 1494 tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(tower->floors, 2); … … 846 1497 for (i = 0; i < num_protocols; i++) { 847 1498 tower->floors[2 + i].lhs.protocol = protseq[i]; 848 tower->floors[2 + i].lhs.lhs_data = data_blob_ talloc(tower->floors, NULL, 0);1499 tower->floors[2 + i].lhs.lhs_data = data_blob_null; 849 1500 ZERO_STRUCT(tower->floors[2 + i].rhs); 850 dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[2 + i], ""); 1501 status = dcerpc_floor_set_rhs_data(tower->floors, 1502 &tower->floors[2 + i], 1503 NULL); 1504 if (!NT_STATUS_IS_OK(status)) { 1505 return status; 1506 } 851 1507 } 852 1508 853 1509 /* The 4th floor contains the endpoint */ 854 1510 if (num_protocols >= 2 && binding->endpoint) { 855 status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[3], binding->endpoint); 856 if (NT_STATUS_IS_ERR(status)) { 1511 status = dcerpc_floor_set_rhs_data(tower->floors, 1512 &tower->floors[3], 1513 binding->endpoint); 1514 if (!NT_STATUS_IS_OK(status)) { 857 1515 return status; 858 1516 } … … 861 1519 /* The 5th contains the network address */ 862 1520 if (num_protocols >= 3 && binding->host) { 863 if (is_ipaddress(binding->host) || 864 (binding->host[0] == '\\' && binding->host[1] == '\\')) { 865 status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4], 866 binding->host); 867 } else { 868 /* note that we don't attempt to resolve the 869 name here - when we get a hostname here we 870 are in the client code, and want to put in 871 a wildcard all-zeros IP for the server to 872 fill in */ 873 status = dcerpc_floor_set_rhs_data(tower->floors, &tower->floors[4], 874 "0.0.0.0"); 875 } 876 if (NT_STATUS_IS_ERR(status)) { 1521 status = dcerpc_floor_set_rhs_data(tower->floors, 1522 &tower->floors[4], 1523 binding->host); 1524 if (!NT_STATUS_IS_OK(status)) { 877 1525 return status; 878 1526 } -
vendor/current/librpc/rpc/binding_handle.c
r740 r988 99 99 } 100 100 101 void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, 102 enum dcerpc_AuthType *auth_type, 103 enum dcerpc_AuthLevel *auth_level) 104 { 105 enum dcerpc_AuthType _auth_type; 106 enum dcerpc_AuthLevel _auth_level; 107 108 if (auth_type == NULL) { 109 auth_type = &_auth_type; 110 } 111 112 if (auth_level == NULL) { 113 auth_level = &_auth_level; 114 } 115 116 *auth_type = DCERPC_AUTH_TYPE_NONE; 117 *auth_level = DCERPC_AUTH_LEVEL_NONE; 118 119 if (h->ops->auth_info == NULL) { 120 return; 121 } 122 123 h->ops->auth_info(h, auth_type, auth_level); 124 } 125 101 126 struct dcerpc_binding_handle_raw_call_state { 102 127 const struct dcerpc_binding_handle_ops *ops; … … 156 181 &state->out_flags); 157 182 TALLOC_FREE(subreq); 158 if (!NT_STATUS_IS_OK(error)) { 159 tevent_req_nterror(req, error); 183 if (tevent_req_nterror(req, error)) { 160 184 return; 161 185 } … … 201 225 struct tevent_context *ev; 202 226 struct tevent_req *subreq; 203 NTSTATUS status ;227 NTSTATUS status = NT_STATUS_NO_MEMORY; 204 228 205 229 /* … … 210 234 ev = h->sync_ev; 211 235 } else { 212 ev = tevent_context_init(frame);236 ev = samba_tevent_context_init(frame); 213 237 } 214 238 if (ev == NULL) { 215 talloc_free(frame); 216 return NT_STATUS_NO_MEMORY; 239 goto fail; 217 240 } 218 241 … … 223 246 in_length); 224 247 if (subreq == NULL) { 225 talloc_free(frame); 226 return NT_STATUS_NO_MEMORY; 227 } 228 229 if (!tevent_req_poll(subreq, ev)) { 230 status = map_nt_error_from_unix(errno); 231 talloc_free(frame); 232 return status; 248 goto fail; 249 } 250 251 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) { 252 goto fail; 233 253 } 234 254 … … 238 258 out_length, 239 259 out_flags); 240 if (!NT_STATUS_IS_OK(status)) { 241 talloc_free(frame); 242 return status; 243 } 244 260 fail: 245 261 TALLOC_FREE(frame); 246 return NT_STATUS_OK;262 return status; 247 263 } 248 264 … … 289 305 error = state->ops->disconnect_recv(subreq); 290 306 TALLOC_FREE(subreq); 291 if (!NT_STATUS_IS_OK(error)) { 292 tevent_req_nterror(req, error); 307 if (tevent_req_nterror(req, error)) { 293 308 return; 294 309 } … … 442 457 &out_flags); 443 458 TALLOC_FREE(subreq); 444 if (!NT_STATUS_IS_OK(error)) { 445 tevent_req_nterror(req, error); 459 if (tevent_req_nterror(req, error)) { 446 460 return; 447 461 } … … 495 509 NTSTATUS dcerpc_binding_handle_call_recv(struct tevent_req *req) 496 510 { 497 NTSTATUS error; 498 499 if (tevent_req_is_nterror(req, &error)) { 500 tevent_req_received(req); 501 return error; 502 } 503 504 tevent_req_received(req); 505 return NT_STATUS_OK; 511 return tevent_req_simple_recv_ntstatus(req); 506 512 } 507 513 … … 516 522 struct tevent_context *ev; 517 523 struct tevent_req *subreq; 518 NTSTATUS status ;524 NTSTATUS status = NT_STATUS_NO_MEMORY; 519 525 520 526 /* … … 525 531 ev = h->sync_ev; 526 532 } else { 527 ev = tevent_context_init(frame);533 ev = samba_tevent_context_init(frame); 528 534 } 529 535 if (ev == NULL) { 530 talloc_free(frame); 531 return NT_STATUS_NO_MEMORY; 536 goto fail; 532 537 } 533 538 … … 536 541 opnum, r_mem, r_ptr); 537 542 if (subreq == NULL) { 538 talloc_free(frame); 539 return NT_STATUS_NO_MEMORY; 540 } 541 542 if (!tevent_req_poll(subreq, ev)) { 543 status = map_nt_error_from_unix(errno); 544 talloc_free(frame); 545 return status; 543 goto fail; 544 } 545 546 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) { 547 goto fail; 546 548 } 547 549 548 550 status = dcerpc_binding_handle_call_recv(subreq); 549 if (!NT_STATUS_IS_OK(status)) { 550 talloc_free(frame); 551 return status; 552 } 553 551 fail: 554 552 TALLOC_FREE(frame); 555 return NT_STATUS_OK;556 } 553 return status; 554 } -
vendor/current/librpc/rpc/dcerpc_error.c
r740 r988 27 27 const char *errstr; 28 28 uint32_t faultcode; 29 NTSTATUS nt_status; 29 30 }; 30 31 31 32 static const struct dcerpc_fault_table dcerpc_faults[] = 32 33 { 33 #define _FAULT_STR(x) { #x , x } 34 _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE), 35 _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR), 36 _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF), 37 _FAULT_STR(DCERPC_NCA_S_WRONG_BOOT_TIME), 38 _FAULT_STR(DCERPC_NCA_S_YOU_CRASHED), 39 _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR), 40 _FAULT_STR(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), 41 _FAULT_STR(DCERPC_NCA_S_SERVER_TOO_BUSY), 42 _FAULT_STR(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), 43 _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_TYPE), 44 _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO), 45 _FAULT_STR(DCERPC_NCA_S_FAULT_ADDR_ERROR), 46 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO), 47 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW), 48 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW), 49 _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG), 50 _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND), 51 _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH), 52 _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC_REJECT), 53 _FAULT_STR(DCERPC_NCA_S_FAULT_BAD_ACTID), 54 _FAULT_STR(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED), 55 _FAULT_STR(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED), 56 _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL), 57 _FAULT_STR(DCERPC_NCA_S_FAULT_ILL_INST), 58 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_ERROR), 59 _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW), 60 _FAULT_STR(DCERPC_NCA_S_UNUSED_1C000011), 61 _FAULT_STR(DCERPC_NCA_S_FAULT_UNSPEC), 62 _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE), 63 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_EMPTY), 64 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED), 65 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_ORDER), 66 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE), 67 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR), 68 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_MEMORY), 69 _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH), 70 _FAULT_STR(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY), 71 _FAULT_STR(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID), 72 _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL), 73 _FAULT_STR(DCERPC_NCA_S_UNUSED_1C00001E), 74 _FAULT_STR(DCERPC_NCA_S_INVALID_CHECKSUM), 75 _FAULT_STR(DCERPC_NCA_S_INVALID_CRC), 76 _FAULT_STR(DCERPC_NCA_S_FAULT_USER_DEFINED), 77 _FAULT_STR(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED), 78 _FAULT_STR(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR), 79 _FAULT_STR(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), 80 _FAULT_STR(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), 34 #define _FAULT_STR(x, s) { .errstr = #x , .faultcode = x, .nt_status = s } 35 #define _FAULT_STR_NO_NT_MAPPING(x) _FAULT_STR(x, NT_STATUS_RPC_NOT_RPC_ERROR) 36 _FAULT_STR(DCERPC_NCA_S_COMM_FAILURE, NT_STATUS_RPC_COMM_FAILURE), 37 _FAULT_STR(DCERPC_NCA_S_OP_RNG_ERROR, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE), 38 _FAULT_STR(DCERPC_NCA_S_UNKNOWN_IF, NT_STATUS_RPC_UNKNOWN_IF), 39 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_WRONG_BOOT_TIME), 40 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_YOU_CRASHED), 41 _FAULT_STR(DCERPC_NCA_S_PROTO_ERROR, NT_STATUS_RPC_PROTOCOL_ERROR), 42 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_OUT_ARGS_TOO_BIG), 43 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_SERVER_TOO_BUSY), 44 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_STRING_TOO_LARGE), 45 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNSUPPORTED_TYPE), 46 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ADDR_ERROR), 47 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO), 48 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_UNDERFLOW, NT_STATUS_RPC_FP_UNDERFLOW), 49 _FAULT_STR(DCERPC_NCA_S_FAULT_FP_OVERRFLOW, NT_STATUS_RPC_FP_OVERFLOW), 50 _FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO), 51 _FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW, NT_STATUS_RPC_FP_OVERFLOW), 52 /* 53 * What's the difference between NT_STATUS_RPC_INVALID_TAG 54 * and NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ??? 55 * 56 * Our callers expect NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE. 57 */ 58 _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE), 59 _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_INVALID_TAG), 60 _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND, NT_STATUS_RPC_INVALID_BOUND), 61 _FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH, NT_STATUS_RPC_PROTOCOL_ERROR), 62 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC_REJECT), 63 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_BAD_ACTID), 64 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_WHO_ARE_YOU_FAILED), 65 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_MANAGER_NOT_ENTERED), 66 _FAULT_STR(DCERPC_NCA_S_FAULT_CANCEL, NT_STATUS_RPC_CALL_CANCELLED), 67 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_ILL_INST), 68 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_FP_ERROR), 69 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C000011), 70 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_UNSPEC), 71 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_COMM_FAILURE), 72 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_EMPTY), 73 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_CLOSED, NT_STATUS_RPC_PIPE_CLOSED), 74 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_ORDER), 75 _FAULT_STR(DCERPC_NCA_S_FAULT_PIPE_DISCIPLINE, NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR), 76 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_COMM_ERROR), 77 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_PIPE_MEMORY), 78 _FAULT_STR(DCERPC_NCA_S_FAULT_CONTEXT_MISMATCH, NT_STATUS_RPC_SS_CONTEXT_MISMATCH), 79 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY), 80 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_PRES_CONTEXT_ID), 81 _FAULT_STR(DCERPC_NCA_S_UNSUPPORTED_AUTHN_LEVEL, NT_STATUS_RPC_UNSUPPORTED_AUTHN_LEVEL), 82 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_UNUSED_1C00001E), 83 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CHECKSUM), 84 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_INVALID_CRC), 85 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_USER_DEFINED), 86 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_TX_OPEN_FAILED), 87 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_CODESET_CONV_ERROR), 88 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_OBJECT_NOT_FOUND), 89 _FAULT_STR_NO_NT_MAPPING(DCERPC_NCA_S_FAULT_NO_CLIENT_STUB), 90 _FAULT_STR(DCERPC_FAULT_OTHER, NT_STATUS_RPC_CALL_FAILED), 91 _FAULT_STR(DCERPC_FAULT_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED), 92 _FAULT_STR(DCERPC_FAULT_NO_CALL_ACTIVE, NT_STATUS_RPC_NO_CALL_ACTIVE), 93 _FAULT_STR(DCERPC_FAULT_CANT_PERFORM, NT_STATUS_EPT_CANT_PERFORM_OP), 94 _FAULT_STR(DCERPC_FAULT_OUT_OF_RESOURCES, NT_STATUS_RPC_OUT_OF_RESOURCES), 95 _FAULT_STR(DCERPC_FAULT_BAD_STUB_DATA, NT_STATUS_RPC_BAD_STUB_DATA), 96 _FAULT_STR(DCERPC_FAULT_SEC_PKG_ERROR, NT_STATUS_RPC_SEC_PKG_ERROR), 81 97 { NULL, 0 } 82 98 #undef _FAULT_STR … … 100 116 _PUBLIC_ NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code) 101 117 { 102 /* TODO: add more mappings */ 103 switch (fault_code) { 104 case DCERPC_FAULT_OP_RNG_ERROR: 105 return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE; 106 case DCERPC_FAULT_UNK_IF: 107 return NT_STATUS_RPC_UNKNOWN_IF; 108 case DCERPC_FAULT_NDR: 109 return NT_STATUS_RPC_BAD_STUB_DATA; 110 case DCERPC_FAULT_INVALID_TAG: 111 return NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE; 112 case DCERPC_FAULT_CONTEXT_MISMATCH: 113 return NT_STATUS_RPC_SS_CONTEXT_MISMATCH; 114 case DCERPC_FAULT_OTHER: 115 return NT_STATUS_RPC_CALL_FAILED; 116 case DCERPC_FAULT_ACCESS_DENIED: 117 return NT_STATUS_ACCESS_DENIED; 118 case DCERPC_FAULT_SEC_PKG_ERROR: 119 return NT_STATUS_RPC_SEC_PKG_ERROR; 118 int idx = 0; 119 WERROR werr = W_ERROR(fault_code); 120 121 if (fault_code == 0) { 122 return NT_STATUS_RPC_PROTOCOL_ERROR; 120 123 } 121 124 122 return NT_STATUS_RPC_PROTOCOL_ERROR; 125 while (dcerpc_faults[idx].errstr != NULL) { 126 if (dcerpc_faults[idx].faultcode == fault_code) { 127 return dcerpc_faults[idx].nt_status; 128 } 129 idx++; 130 } 131 132 return werror_to_ntstatus(werr); 123 133 } 124 134 135 _PUBLIC_ uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status) 136 { 137 int idx = 0; 138 WERROR werr; 139 140 if (NT_STATUS_IS_OK(nt_status)) { 141 return DCERPC_NCA_S_PROTO_ERROR; 142 } 143 144 while (dcerpc_faults[idx].errstr != NULL) { 145 if (NT_STATUS_EQUAL(dcerpc_faults[idx].nt_status, nt_status)) { 146 return dcerpc_faults[idx].faultcode; 147 } 148 idx++; 149 } 150 151 werr = ntstatus_to_werror(nt_status); 152 153 return W_ERROR_V(werr); 154 } -
vendor/current/librpc/rpc/dcerpc_util.c
r919 r988 47 47 } else { 48 48 return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET); 49 }50 }51 52 uint32_t dcerpc_get_call_id(const DATA_BLOB *blob)53 {54 if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {55 return IVAL(blob->data, DCERPC_CALL_ID_OFFSET);56 } else {57 return RIVAL(blob->data, DCERPC_CALL_ID_OFFSET);58 49 } 59 50 } … … 329 320 330 321 if (state->buffer.length == 0) { 331 /* first get enough to read the fragment length */ 322 /* 323 * first get enough to read the fragment length 324 * 325 * We read the full fixed ncacn_packet header 326 * in order to make wireshark happy with 327 * pcap files from socket_wrapper. 328 */ 332 329 ofs = 0; 333 state->buffer.length = DCERPC_ FRAG_LEN_OFFSET + 2;330 state->buffer.length = DCERPC_NCACN_PAYLOAD_OFFSET; 334 331 state->buffer.data = talloc_array(state, uint8_t, 335 332 state->buffer.length); … … 337 334 return -1; 338 335 } 339 } else if (state->buffer.length == (DCERPC_FRAG_LEN_OFFSET + 2)) {336 } else if (state->buffer.length == DCERPC_NCACN_PAYLOAD_OFFSET) { 340 337 /* now read the fragment length and allocate the full buffer */ 341 338 size_t frag_len = dcerpc_get_frag_length(&state->buffer); … … 395 392 TALLOC_FREE(subreq); 396 393 if (ret == -1) { 397 status = map_nt_error_from_unix (sys_errno);394 status = map_nt_error_from_unix_common(sys_errno); 398 395 tevent_req_nterror(req, status); 399 396 return; … … 451 448 tevent_req_received(req); 452 449 return NT_STATUS_OK; 450 } 451 452 const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, 453 enum dcerpc_transport_t transport, 454 const struct ndr_interface_table *table) 455 { 456 NTSTATUS status; 457 const char *p = NULL; 458 const char *endpoint = NULL; 459 int i; 460 struct dcerpc_binding *default_binding = NULL; 461 TALLOC_CTX *frame = talloc_stackframe(); 462 463 /* Find one of the default pipes for this interface */ 464 465 for (i = 0; i < table->endpoints->count; i++) { 466 enum dcerpc_transport_t dtransport; 467 const char *dendpoint; 468 469 status = dcerpc_parse_binding(frame, table->endpoints->names[i], 470 &default_binding); 471 if (!NT_STATUS_IS_OK(status)) { 472 continue; 473 } 474 475 dtransport = dcerpc_binding_get_transport(default_binding); 476 dendpoint = dcerpc_binding_get_string_option(default_binding, 477 "endpoint"); 478 if (dendpoint == NULL) { 479 TALLOC_FREE(default_binding); 480 continue; 481 } 482 483 if (transport == NCA_UNKNOWN) { 484 transport = dtransport; 485 } 486 487 if (transport != dtransport) { 488 TALLOC_FREE(default_binding); 489 continue; 490 } 491 492 p = dendpoint; 493 break; 494 } 495 496 if (p == NULL) { 497 goto done; 498 } 499 500 /* 501 * extract the pipe name without \\pipe from for example 502 * ncacn_np:[\\pipe\\epmapper] 503 */ 504 if (transport == NCACN_NP) { 505 if (strncasecmp(p, "\\pipe\\", 6) == 0) { 506 p += 6; 507 } 508 if (strncmp(p, "\\", 1) == 0) { 509 p += 1; 510 } 511 } 512 513 endpoint = talloc_strdup(mem_ctx, p); 514 515 done: 516 talloc_free(frame); 517 return endpoint; 453 518 } 454 519 … … 558 623 } 559 624 560 #define CHECK(msg, ok) \ 561 do { \ 562 if (!ok) { \ 563 DEBUG(10, ("SEC_VT check %s failed\n", msg)); \ 564 return false; \ 565 } \ 566 } while(0) 567 568 #define CHECK_SYNTAX(msg, s1, s2) \ 569 do { \ 570 if (!ndr_syntax_id_equal(&s1, &s2)) { \ 571 TALLOC_CTX *frame = talloc_stackframe(); \ 572 DEBUG(10, ("SEC_VT check %s failed: %s vs. %s\n", msg, \ 573 ndr_syntax_id_to_string(frame, &s1), \ 574 ndr_syntax_id_to_string(frame, &s1))); \ 575 TALLOC_FREE(frame); \ 576 return false; \ 577 } \ 578 } while(0) 579 625 static bool dcerpc_sec_vt_bitmask_check(const uint32_t *bitmask1, 626 struct dcerpc_sec_vt *c) 627 { 628 if (bitmask1 == NULL) { 629 if (c->command & DCERPC_SEC_VT_MUST_PROCESS) { 630 DEBUG(10, ("SEC_VT check Bitmask1 must_process_command " 631 "failed\n")); 632 return false; 633 } 634 635 return true; 636 } 637 638 if ((c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING) 639 && (!(*bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING))) { 640 DEBUG(10, ("SEC_VT check Bitmask1 client_header_signing " 641 "failed\n")); 642 return false; 643 } 644 return true; 645 } 646 647 static bool dcerpc_sec_vt_pctx_check(const struct dcerpc_sec_vt_pcontext *pcontext, 648 struct dcerpc_sec_vt *c) 649 { 650 TALLOC_CTX *mem_ctx; 651 bool ok; 652 653 if (pcontext == NULL) { 654 if (c->command & DCERPC_SEC_VT_MUST_PROCESS) { 655 DEBUG(10, ("SEC_VT check Pcontext must_process_command " 656 "failed\n")); 657 return false; 658 } 659 660 return true; 661 } 662 663 mem_ctx = talloc_stackframe(); 664 ok = ndr_syntax_id_equal(&pcontext->abstract_syntax, 665 &c->u.pcontext.abstract_syntax); 666 if (!ok) { 667 DEBUG(10, ("SEC_VT check pcontext abstract_syntax failed: " 668 "%s vs. %s\n", 669 ndr_syntax_id_to_string(mem_ctx, 670 &pcontext->abstract_syntax), 671 ndr_syntax_id_to_string(mem_ctx, 672 &c->u.pcontext.abstract_syntax))); 673 goto err_ctx_free; 674 } 675 ok = ndr_syntax_id_equal(&pcontext->transfer_syntax, 676 &c->u.pcontext.transfer_syntax); 677 if (!ok) { 678 DEBUG(10, ("SEC_VT check pcontext transfer_syntax failed: " 679 "%s vs. %s\n", 680 ndr_syntax_id_to_string(mem_ctx, 681 &pcontext->transfer_syntax), 682 ndr_syntax_id_to_string(mem_ctx, 683 &c->u.pcontext.transfer_syntax))); 684 goto err_ctx_free; 685 } 686 687 ok = true; 688 err_ctx_free: 689 talloc_free(mem_ctx); 690 return ok; 691 } 692 693 static bool dcerpc_sec_vt_hdr2_check(const struct dcerpc_sec_vt_header2 *header2, 694 struct dcerpc_sec_vt *c) 695 { 696 if (header2 == NULL) { 697 if (c->command & DCERPC_SEC_VT_MUST_PROCESS) { 698 DEBUG(10, ("SEC_VT check Header2 must_process_command failed\n")); 699 return false; 700 } 701 702 return true; 703 } 704 705 if (!dcerpc_sec_vt_header2_equal(header2, &c->u.header2)) { 706 DEBUG(10, ("SEC_VT check Header2 failed\n")); 707 return false; 708 } 709 710 return true; 711 } 580 712 581 713 bool dcerpc_sec_verification_trailer_check( … … 592 724 593 725 for (i=0; i < vt->count.count; i++) { 726 bool ok; 594 727 struct dcerpc_sec_vt *c = &vt->commands[i]; 595 728 596 729 switch (c->command & DCERPC_SEC_VT_COMMAND_ENUM) { 597 730 case DCERPC_SEC_VT_COMMAND_BITMASK1: 598 if (bitmask1 == NULL) { 599 CHECK("Bitmask1 must_process_command", 600 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 601 break; 602 } 603 604 if (c->u.bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING) { 605 CHECK("Bitmask1 client_header_signing", 606 *bitmask1 & DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING); 731 ok = dcerpc_sec_vt_bitmask_check(bitmask1, c); 732 if (!ok) { 733 return false; 607 734 } 608 735 break; 609 736 610 737 case DCERPC_SEC_VT_COMMAND_PCONTEXT: 611 if (pcontext == NULL) { 612 CHECK("Pcontext must_process_command", 613 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 614 break; 738 ok = dcerpc_sec_vt_pctx_check(pcontext, c); 739 if (!ok) { 740 return false; 615 741 } 616 617 CHECK_SYNTAX("Pcontect abstract_syntax",618 pcontext->abstract_syntax,619 c->u.pcontext.abstract_syntax);620 CHECK_SYNTAX("Pcontext transfer_syntax",621 pcontext->transfer_syntax,622 c->u.pcontext.transfer_syntax);623 742 break; 624 743 625 744 case DCERPC_SEC_VT_COMMAND_HEADER2: { 626 if (header2 == NULL) { 627 CHECK("Header2 must_process_command", 628 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 629 break; 745 ok = dcerpc_sec_vt_hdr2_check(header2, c); 746 if (!ok) { 747 return false; 630 748 } 631 632 CHECK("Header2", dcerpc_sec_vt_header2_equal(header2, &c->u.header2));633 749 break; 634 750 } 635 751 636 752 default: 637 CHECK("Unknown must_process_command", 638 !(c->command & DCERPC_SEC_VT_MUST_PROCESS)); 753 if (c->command & DCERPC_SEC_VT_MUST_PROCESS) { 754 DEBUG(10, ("SEC_VT check Unknown must_process_command failed\n")); 755 return false; 756 } 757 639 758 break; 640 759 } … … 643 762 return true; 644 763 } 764 765 static const struct ndr_syntax_id dcerpc_bind_time_features_prefix = { 766 .uuid = { 767 .time_low = 0x6cb71c2c, 768 .time_mid = 0x9812, 769 .time_hi_and_version = 0x4540, 770 .clock_seq = {0x00, 0x00}, 771 .node = {0x00,0x00,0x00,0x00,0x00,0x00} 772 }, 773 .if_version = 1, 774 }; 775 776 bool dcerpc_extract_bind_time_features(struct ndr_syntax_id s, uint64_t *_features) 777 { 778 uint8_t values[8]; 779 uint64_t features = 0; 780 781 values[0] = s.uuid.clock_seq[0]; 782 values[1] = s.uuid.clock_seq[1]; 783 values[2] = s.uuid.node[0]; 784 values[3] = s.uuid.node[1]; 785 values[4] = s.uuid.node[2]; 786 values[5] = s.uuid.node[3]; 787 values[6] = s.uuid.node[4]; 788 values[7] = s.uuid.node[5]; 789 790 ZERO_STRUCT(s.uuid.clock_seq); 791 ZERO_STRUCT(s.uuid.node); 792 793 if (!ndr_syntax_id_equal(&s, &dcerpc_bind_time_features_prefix)) { 794 if (_features != NULL) { 795 *_features = 0; 796 } 797 return false; 798 } 799 800 features = BVAL(values, 0); 801 802 if (_features != NULL) { 803 *_features = features; 804 } 805 806 return true; 807 } 808 809 struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features) 810 { 811 struct ndr_syntax_id s = dcerpc_bind_time_features_prefix; 812 uint8_t values[8]; 813 814 SBVAL(values, 0, features); 815 816 s.uuid.clock_seq[0] = values[0]; 817 s.uuid.clock_seq[1] = values[1]; 818 s.uuid.node[0] = values[2]; 819 s.uuid.node[1] = values[3]; 820 s.uuid.node[2] = values[4]; 821 s.uuid.node[3] = values[5]; 822 s.uuid.node[4] = values[6]; 823 s.uuid.node[5] = values[7]; 824 825 return s; 826 } -
vendor/current/librpc/rpc/rpc_common.h
r919 r988 22 22 #ifndef __DEFAULT_LIBRPC_RPCCOMMON_H__ 23 23 #define __DEFAULT_LIBRPC_RPCCOMMON_H__ 24 25 #include "gen_ndr/dcerpc.h" 26 #include "lib/util/attr.h" 24 27 25 28 struct dcerpc_binding_handle; … … 41 44 42 45 /** this describes a binding to a particular transport/pipe */ 43 struct dcerpc_binding { 44 enum dcerpc_transport_t transport; 45 struct ndr_syntax_id object; 46 const char *host; 47 const char *target_hostname; 48 const char *target_principal; 49 const char *endpoint; 50 const char **options; 51 const char *localaddress; 52 uint32_t flags; 53 uint32_t assoc_group_id; 54 }; 46 struct dcerpc_binding; 55 47 56 48 /* dcerpc pipe flags */ … … 99 91 #define DCERPC_CONCURRENT_MULTIPLEX (1<<19) 100 92 101 /* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request*/93 /* this indicates DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag was negotiated */ 102 94 #define DCERPC_HEADER_SIGNING (1<<20) 103 95 … … 105 97 #define DCERPC_NDR64 (1<<21) 106 98 107 /* specify binding interface */ 108 #define DCERPC_LOCALADDRESS (1<<22) 99 /* handle upgrades or downgrades automatically */ 100 #define DCERPC_SCHANNEL_AUTO (1<<23) 101 102 /* use aes schannel with hmac-sh256 session key */ 103 #define DCERPC_SCHANNEL_AES (1<<24) 104 105 /* this triggers the DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN flag in the bind request */ 106 #define DCERPC_PROPOSE_HEADER_SIGNING (1<<25) 109 107 110 108 /* The following definitions come from ../librpc/rpc/dcerpc_error.c */ … … 112 110 const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code); 113 111 NTSTATUS dcerpc_fault_to_nt_status(uint32_t fault_code); 112 uint32_t dcerpc_fault_from_nt_status(NTSTATUS nt_status); 114 113 115 114 /* The following definitions come from ../librpc/rpc/binding.c */ 116 115 117 116 const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor); 118 c onst char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);117 char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor); 119 118 enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot); 120 119 struct dcerpc_binding *dcerpc_binding_dup(TALLOC_CTX *mem_ctx, … … 128 127 NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out); 129 128 char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b); 129 struct GUID dcerpc_binding_get_object(const struct dcerpc_binding *b); 130 NTSTATUS dcerpc_binding_set_object(struct dcerpc_binding *b, 131 struct GUID object); 132 enum dcerpc_transport_t dcerpc_binding_get_transport(const struct dcerpc_binding *b); 133 NTSTATUS dcerpc_binding_set_transport(struct dcerpc_binding *b, 134 enum dcerpc_transport_t transport); 135 void dcerpc_binding_get_auth_info(const struct dcerpc_binding *b, 136 enum dcerpc_AuthType *_auth_type, 137 enum dcerpc_AuthLevel *_auth_level); 138 uint32_t dcerpc_binding_get_assoc_group_id(const struct dcerpc_binding *b); 139 NTSTATUS dcerpc_binding_set_assoc_group_id(struct dcerpc_binding *b, 140 uint32_t assoc_group_id); 141 struct ndr_syntax_id dcerpc_binding_get_abstract_syntax(const struct dcerpc_binding *b); 142 NTSTATUS dcerpc_binding_set_abstract_syntax(struct dcerpc_binding *b, 143 const struct ndr_syntax_id *syntax); 144 const char *dcerpc_binding_get_string_option(const struct dcerpc_binding *b, 145 const char *name); 146 char *dcerpc_binding_copy_string_option(TALLOC_CTX *mem_ctx, 147 const struct dcerpc_binding *b, 148 const char *name); 149 NTSTATUS dcerpc_binding_set_string_option(struct dcerpc_binding *b, 150 const char *name, 151 const char *value); 152 uint32_t dcerpc_binding_get_flags(const struct dcerpc_binding *b); 153 NTSTATUS dcerpc_binding_set_flags(struct dcerpc_binding *b, 154 uint32_t additional, 155 uint32_t clear); 130 156 NTSTATUS dcerpc_floor_get_lhs_data(const struct epm_floor *epm_floor, struct ndr_syntax_id *syntax); 131 157 const char *derpc_transport_string_by_transport(enum dcerpc_transport_t t); 158 enum dcerpc_transport_t dcerpc_transport_by_name(const char *name); 132 159 enum dcerpc_transport_t dcerpc_transport_by_tower(const struct epm_tower *tower); 133 160 … … 136 163 void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v); 137 164 uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob); 138 uint32_t dcerpc_get_call_id(const DATA_BLOB *blob);139 165 void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v); 140 166 uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob); 167 const char *dcerpc_default_transport_endpoint(TALLOC_CTX *mem_ctx, 168 enum dcerpc_transport_t transport, 169 const struct ndr_interface_table *table); 141 170 142 171 /** … … 187 216 uint32_t timeout); 188 217 218 void (*auth_info)(struct dcerpc_binding_handle *h, 219 enum dcerpc_AuthType *auth_type, 220 enum dcerpc_AuthLevel *auth_level); 221 189 222 struct tevent_req *(*raw_call_send)(TALLOC_CTX *mem_ctx, 190 223 struct tevent_context *ev, … … 257 290 uint32_t timeout); 258 291 292 void dcerpc_binding_handle_auth_info(struct dcerpc_binding_handle *h, 293 enum dcerpc_AuthType *auth_type, 294 enum dcerpc_AuthLevel *auth_level); 295 259 296 struct tevent_req *dcerpc_binding_handle_raw_call_send(TALLOC_CTX *mem_ctx, 260 297 struct tevent_context *ev, … … 343 380 const struct dcerpc_sec_vt_header2 *header2); 344 381 382 /** 383 * @brief check and optionally extract the Bind Time Features from 384 * the given ndr_syntax_id. 385 * 386 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>. 387 * 388 * @param[in] s the syntax that should be checked. 389 * 390 * @param[out] features This is optional, it will be filled with the extracted 391 * features the on success, otherwise it's filled with 0. 392 * 393 * @return true if the syntax matches the 6CB71C2C-9812-4540 prefix with version 1, false otherwise. 394 * 395 * @see dcerpc_construct_bind_time_features 396 */ 397 bool dcerpc_extract_bind_time_features(struct ndr_syntax_id syntax, uint64_t *features); 398 399 /** 400 * @brief Construct a ndr_syntax_id used for Bind Time Features Negotiation. 401 * 402 * <a href="http://msdn.microsoft.com/en-us/library/cc243715.aspx">MS-RPCE 3.3.1.5.3 Bind Time Feature Negotiation</a>. 403 * 404 * @param[in] features The supported features. 405 * 406 * @return The ndr_syntax_id with the given features. 407 * 408 * @see dcerpc_extract_bind_time_features 409 */ 410 struct ndr_syntax_id dcerpc_construct_bind_time_features(uint64_t features); 411 412 #define DCERPC_AUTH_PAD_LENGTH(stub_length) (\ 413 (((stub_length) % DCERPC_AUTH_PAD_ALIGNMENT) > 0)?\ 414 (DCERPC_AUTH_PAD_ALIGNMENT - (stub_length) % DCERPC_AUTH_PAD_ALIGNMENT):\ 415 0) 416 345 417 #endif /* __DEFAULT_LIBRPC_RPCCOMMON_H__ */
Note:
See TracChangeset
for help on using the changeset viewer.