Changeset 740 for vendor/current/source3/rpc_client
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source3/rpc_client
- Files:
-
- 21 added
- 2 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/rpc_client/cli_lsarpc.c
r414 r740 24 24 25 25 #include "includes.h" 26 #include "../librpc/gen_ndr/cli_lsa.h" 26 #include "rpc_client/rpc_client.h" 27 #include "../librpc/gen_ndr/ndr_lsa_c.h" 28 #include "rpc_client/cli_lsarpc.h" 29 #include "rpc_client/init_lsa.h" 30 #include "../libcli/security/security.h" 27 31 28 32 /** @defgroup lsa LSA - Local Security Architecture … … 39 43 **/ 40 44 41 /** Open a LSA policy handle 42 * 43 * @param cli Handle on an initialised SMB connection */ 44 45 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, 45 NTSTATUS dcerpc_lsa_open_policy(struct dcerpc_binding_handle *h, 46 46 TALLOC_CTX *mem_ctx, 47 bool sec_qos, uint32 des_access, 48 struct policy_handle *pol) 47 bool sec_qos, 48 uint32_t des_access, 49 struct policy_handle *pol, 50 NTSTATUS *result) 49 51 { 50 52 struct lsa_ObjectAttribute attr; … … 65 67 } 66 68 67 return rpccli_lsa_OpenPolicy(cli, mem_ctx, 69 return dcerpc_lsa_OpenPolicy(h, 70 mem_ctx, 68 71 &system_name, 69 72 &attr, 70 73 des_access, 71 pol); 74 pol, 75 result); 72 76 } 73 77 74 78 /** Open a LSA policy handle 75 * 76 * @param cli Handle on an initialised SMB connection 77 */ 78 79 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, 80 TALLOC_CTX *mem_ctx, bool sec_qos, 81 uint32 des_access, struct policy_handle *pol) 79 * 80 * @param cli Handle on an initialised SMB connection */ 81 82 NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli, 83 TALLOC_CTX *mem_ctx, 84 bool sec_qos, uint32 des_access, 85 struct policy_handle *pol) 86 { 87 NTSTATUS status; 88 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 89 90 status = dcerpc_lsa_open_policy(cli->binding_handle, 91 mem_ctx, 92 sec_qos, 93 des_access, 94 pol, 95 &result); 96 if (!NT_STATUS_IS_OK(status)) { 97 return status; 98 } 99 100 return result; 101 } 102 103 NTSTATUS dcerpc_lsa_open_policy2(struct dcerpc_binding_handle *h, 104 TALLOC_CTX *mem_ctx, 105 const char *srv_name_slash, 106 bool sec_qos, 107 uint32_t des_access, 108 struct policy_handle *pol, 109 NTSTATUS *result) 82 110 { 83 111 struct lsa_ObjectAttribute attr; … … 97 125 } 98 126 99 return rpccli_lsa_OpenPolicy2(cli, mem_ctx, 100 cli->srv_name_slash, 127 return dcerpc_lsa_OpenPolicy2(h, 128 mem_ctx, 129 srv_name_slash, 101 130 &attr, 102 131 des_access, 103 pol); 132 pol, 133 result); 134 } 135 136 /** Open a LSA policy handle 137 * 138 * @param cli Handle on an initialised SMB connection 139 */ 140 141 NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli, 142 TALLOC_CTX *mem_ctx, bool sec_qos, 143 uint32 des_access, struct policy_handle *pol) 144 { 145 NTSTATUS status; 146 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 147 148 status = dcerpc_lsa_open_policy2(cli->binding_handle, 149 mem_ctx, 150 cli->srv_name_slash, 151 sec_qos, 152 des_access, 153 pol, 154 &result); 155 if (!NT_STATUS_IS_OK(status)) { 156 return status; 157 } 158 159 return result; 104 160 } 105 161 … … 107 163 * 108 164 * internal version withOUT memory allocation of the target arrays. 109 * this assumes suff ciently sized arrays to store domains, names and types. */110 111 static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli,165 * this assumes sufficiently sized arrays to store domains, names and types. */ 166 167 static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h, 112 168 TALLOC_CTX *mem_ctx, 113 169 struct policy_handle *pol, 114 170 int num_sids, 115 const DOM_SID*sids,171 const struct dom_sid *sids, 116 172 char **domains, 117 173 char **names, 118 174 enum lsa_SidType *types, 119 bool use_lookupsids3 )120 { 121 NTSTATUS result = NT_STATUS_OK; 122 TALLOC_CTX *tmp_ctx = NULL;123 int i;175 bool use_lookupsids3, 176 NTSTATUS *presult) 177 { 178 NTSTATUS status = NT_STATUS_OK; 179 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 124 180 struct lsa_SidArray sid_array; 125 181 struct lsa_RefDomainList *ref_domains = NULL; 126 182 struct lsa_TransNameArray lsa_names; 183 enum lsa_LookupNamesLevel level = LSA_LOOKUP_NAMES_ALL; 127 184 uint32_t count = 0; 128 uint16_t level = 1;185 int i; 129 186 130 187 ZERO_STRUCT(lsa_names); 131 132 tmp_ctx = talloc_new(mem_ctx);133 if (!tmp_ctx) {134 DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n"));135 result = NT_STATUS_UNSUCCESSFUL;136 goto done;137 }138 188 139 189 sid_array.num_sids = num_sids; 140 190 sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids); 141 if ( !sid_array.sids) {191 if (sid_array.sids == NULL) { 142 192 return NT_STATUS_NO_MEMORY; 143 193 } 144 194 145 195 for (i = 0; i<num_sids; i++) { 146 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]);196 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]); 147 197 if (!sid_array.sids[i].sid) { 148 198 return NT_STATUS_NO_MEMORY; … … 156 206 ZERO_STRUCT(lsa_names2); 157 207 158 result = rpccli_lsa_LookupSids3(cli, mem_ctx, 208 status = dcerpc_lsa_LookupSids3(h, 209 mem_ctx, 159 210 &sid_array, 160 211 &ref_domains, … … 162 213 level, 163 214 &count, 164 0, 165 0); 166 167 if (!NT_STATUS_IS_ERR(result)) { 168 lsa_names.count = lsa_names2.count; 169 lsa_names.names = talloc_array(mem_ctx, struct lsa_TranslatedName, lsa_names.count); 170 if (!lsa_names.names) { 215 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES, 216 LSA_CLIENT_REVISION_2, 217 &result); 218 if (!NT_STATUS_IS_OK(status)) { 219 return status; 220 } 221 222 if(!NT_STATUS_IS_ERR(result)) { 223 lsa_names.count = lsa_names2.count; 224 lsa_names.names = talloc_array(mem_ctx, 225 struct lsa_TranslatedName, 226 lsa_names.count); 227 if (lsa_names.names == NULL) { 171 228 return NT_STATUS_NO_MEMORY; 172 229 } … … 179 236 180 237 } else { 181 result = rpccli_lsa_LookupSids(cli, mem_ctx, 238 status = dcerpc_lsa_LookupSids(h, 239 mem_ctx, 182 240 pol, 183 241 &sid_array, … … 185 243 &lsa_names, 186 244 level, 187 &count); 188 } 189 190 DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n", 191 nt_errstr(result), count)); 245 &count, 246 &result); 247 } 248 249 DEBUG(10, ("LSA_LOOKUPSIDS returned status: '%s', result: '%s', " 250 "mapped count = %d'\n", 251 nt_errstr(status), nt_errstr(result), count)); 252 253 if (!NT_STATUS_IS_OK(status)) { 254 return status; 255 } 192 256 193 257 if (!NT_STATUS_IS_OK(result) && … … 195 259 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) 196 260 { 197 /* An actual error occured */198 goto done;261 *presult = result; 262 return status; 199 263 } 200 264 201 265 /* Return output parameters */ 202 203 266 if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) || 204 267 (count == 0)) … … 209 272 (types)[i] = SID_NAME_UNKNOWN; 210 273 } 211 result = NT_STATUS_NONE_MAPPED;212 goto done;274 *presult = NT_STATUS_NONE_MAPPED; 275 return status; 213 276 } 214 277 … … 225 288 226 289 if (name) { 227 (names)[i] = talloc_strdup( mem_ctx, name);290 (names)[i] = talloc_strdup(names, name); 228 291 if ((names)[i] == NULL) { 229 292 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n")); 230 result = NT_STATUS_UNSUCCESSFUL;231 goto done;293 *presult = NT_STATUS_UNSUCCESSFUL; 294 return status; 232 295 } 233 296 } else { 234 297 (names)[i] = NULL; 235 298 } 236 domains[i] = talloc_strdup( 237 mem_ctx,dom_name ? dom_name : "");299 domains[i] = talloc_strdup(domains, 300 dom_name ? dom_name : ""); 238 301 (types)[i] = lsa_names.names[i].sid_type; 239 302 if (((domains)[i] == NULL)) { 240 303 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n")); 241 result = NT_STATUS_UNSUCCESSFUL;242 goto done;304 *presult = NT_STATUS_UNSUCCESSFUL; 305 return status; 243 306 } 244 307 … … 250 313 } 251 314 252 done: 253 TALLOC_FREE(tmp_ctx); 254 return result; 315 *presult = NT_STATUS_OK; 316 return status; 255 317 } 256 318 … … 267 329 #define LOOKUP_SIDS_HUNK_SIZE 1000 268 330 269 static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli,331 static NTSTATUS dcerpc_lsa_lookup_sids_generic(struct dcerpc_binding_handle *h, 270 332 TALLOC_CTX *mem_ctx, 271 333 struct policy_handle *pol, 272 334 int num_sids, 273 const DOM_SID*sids,335 const struct dom_sid *sids, 274 336 char ***pdomains, 275 337 char ***pnames, 276 338 enum lsa_SidType **ptypes, 277 bool use_lookupsids3) 278 { 339 bool use_lookupsids3, 340 NTSTATUS *presult) 341 { 342 NTSTATUS status = NT_STATUS_OK; 279 343 NTSTATUS result = NT_STATUS_OK; 280 344 int sids_left = 0; 281 345 int sids_processed = 0; 282 const DOM_SID*hunk_sids = sids;346 const struct dom_sid *hunk_sids = sids; 283 347 char **hunk_domains; 284 348 char **hunk_names; … … 287 351 char **names = NULL; 288 352 enum lsa_SidType *types = NULL; 353 bool have_mapped = false; 354 bool have_unmapped = false; 289 355 290 356 if (num_sids) { 291 357 if (!(domains = TALLOC_ARRAY(mem_ctx, char *, num_sids))) { 292 358 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n")); 293 result= NT_STATUS_NO_MEMORY;359 status = NT_STATUS_NO_MEMORY; 294 360 goto fail; 295 361 } … … 297 363 if (!(names = TALLOC_ARRAY(mem_ctx, char *, num_sids))) { 298 364 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n")); 299 result= NT_STATUS_NO_MEMORY;365 status = NT_STATUS_NO_MEMORY; 300 366 goto fail; 301 367 } … … 303 369 if (!(types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_sids))) { 304 370 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n")); 305 result= NT_STATUS_NO_MEMORY;371 status = NT_STATUS_NO_MEMORY; 306 372 goto fail; 307 373 } … … 315 381 while (sids_left > 0) { 316 382 int hunk_num_sids; 317 NTSTATUS hunk_result = NT_STATUS_ OK;383 NTSTATUS hunk_result = NT_STATUS_UNSUCCESSFUL; 318 384 319 385 hunk_num_sids = ((sids_left > LOOKUP_SIDS_HUNK_SIZE) … … 327 393 num_sids)); 328 394 329 hunk_result = rpccli_lsa_lookup_sids_noalloc(cli, 330 mem_ctx, 331 pol, 332 hunk_num_sids, 333 hunk_sids, 334 hunk_domains, 335 hunk_names, 336 hunk_types, 337 use_lookupsids3); 395 status = dcerpc_lsa_lookup_sids_noalloc(h, 396 mem_ctx, 397 pol, 398 hunk_num_sids, 399 hunk_sids, 400 hunk_domains, 401 hunk_names, 402 hunk_types, 403 use_lookupsids3, 404 &hunk_result); 405 if (!NT_STATUS_IS_OK(status)) { 406 goto fail; 407 } 338 408 339 409 if (!NT_STATUS_IS_OK(hunk_result) && … … 342 412 { 343 413 /* An actual error occured */ 344 result = hunk_result;414 *presult = hunk_result; 345 415 goto fail; 346 416 } 347 417 348 /* adapt overall result */ 349 if (( NT_STATUS_IS_OK(result) && 350 !NT_STATUS_IS_OK(hunk_result)) 351 || 352 ( NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) && 353 !NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED))) 354 { 355 result = STATUS_SOME_UNMAPPED; 418 if (NT_STATUS_IS_OK(hunk_result)) { 419 have_mapped = true; 420 } 421 if (NT_STATUS_EQUAL(hunk_result, NT_STATUS_NONE_MAPPED)) { 422 have_unmapped = true; 423 } 424 if (NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED)) { 425 int i; 426 for (i=0; i<hunk_num_sids; i++) { 427 if (hunk_types[i] == SID_NAME_UNKNOWN) { 428 have_unmapped = true; 429 } else { 430 have_mapped = true; 431 } 432 } 356 433 } 357 434 … … 367 444 *pnames = names; 368 445 *ptypes = types; 369 return result; 446 447 if (!have_mapped) { 448 result = NT_STATUS_NONE_MAPPED; 449 } 450 if (have_unmapped) { 451 result = STATUS_SOME_UNMAPPED; 452 } 453 *presult = result; 454 455 return status; 370 456 371 457 fail: … … 373 459 TALLOC_FREE(names); 374 460 TALLOC_FREE(types); 375 return result; 461 462 return status; 463 } 464 465 NTSTATUS dcerpc_lsa_lookup_sids(struct dcerpc_binding_handle *h, 466 TALLOC_CTX *mem_ctx, 467 struct policy_handle *pol, 468 int num_sids, 469 const struct dom_sid *sids, 470 char ***pdomains, 471 char ***pnames, 472 enum lsa_SidType **ptypes, 473 NTSTATUS *result) 474 { 475 return dcerpc_lsa_lookup_sids_generic(h, 476 mem_ctx, 477 pol, 478 num_sids, 479 sids, 480 pdomains, 481 pnames, 482 ptypes, 483 false, 484 result); 376 485 } 377 486 … … 380 489 struct policy_handle *pol, 381 490 int num_sids, 382 const DOM_SID*sids,491 const struct dom_sid *sids, 383 492 char ***pdomains, 384 493 char ***pnames, 385 494 enum lsa_SidType **ptypes) 386 495 { 387 return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, 388 pdomains, pnames, ptypes, false); 496 NTSTATUS status; 497 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 498 499 status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, 500 mem_ctx, 501 pol, 502 num_sids, 503 sids, 504 pdomains, 505 pnames, 506 ptypes, 507 false, 508 &result); 509 if (!NT_STATUS_IS_OK(status)) { 510 return status; 511 } 512 513 return result; 514 } 515 516 NTSTATUS dcerpc_lsa_lookup_sids3(struct dcerpc_binding_handle *h, 517 TALLOC_CTX *mem_ctx, 518 struct policy_handle *pol, 519 int num_sids, 520 const struct dom_sid *sids, 521 char ***pdomains, 522 char ***pnames, 523 enum lsa_SidType **ptypes, 524 NTSTATUS *result) 525 { 526 return dcerpc_lsa_lookup_sids_generic(h, 527 mem_ctx, 528 pol, 529 num_sids, 530 sids, 531 pdomains, 532 pnames, 533 ptypes, 534 true, 535 result); 389 536 } 390 537 … … 393 540 struct policy_handle *pol, 394 541 int num_sids, 395 const DOM_SID*sids,542 const struct dom_sid *sids, 396 543 char ***pdomains, 397 544 char ***pnames, 398 545 enum lsa_SidType **ptypes) 399 546 { 400 return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, 401 pdomains, pnames, ptypes, true); 547 NTSTATUS status; 548 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 549 550 status = dcerpc_lsa_lookup_sids_generic(cli->binding_handle, 551 mem_ctx, 552 pol, 553 num_sids, 554 sids, 555 pdomains, 556 pnames, 557 ptypes, 558 true, 559 &result); 560 if (!NT_STATUS_IS_OK(status)) { 561 return status; 562 } 563 564 return result; 402 565 } 403 566 404 567 /** Lookup a list of names */ 405 568 406 static NTSTATUS rpccli_lsa_lookup_names_generic(struct rpc_pipe_client *cli,569 static NTSTATUS dcerpc_lsa_lookup_names_generic(struct dcerpc_binding_handle *h, 407 570 TALLOC_CTX *mem_ctx, 408 struct policy_handle *pol, int num_names, 571 struct policy_handle *pol, 572 uint32_t num_names, 409 573 const char **names, 410 574 const char ***dom_names, 411 intlevel,412 DOM_SID**sids,575 enum lsa_LookupNamesLevel level, 576 struct dom_sid **sids, 413 577 enum lsa_SidType **types, 414 bool use_lookupnames4 )415 { 416 NTSTATUS result; 417 int i;578 bool use_lookupnames4, 579 NTSTATUS *presult) 580 { 581 NTSTATUS status; 418 582 struct lsa_String *lsa_names = NULL; 419 583 struct lsa_RefDomainList *domains = NULL; … … 421 585 struct lsa_TransSidArray3 sid_array3; 422 586 uint32_t count = 0; 587 uint32_t i; 423 588 424 589 ZERO_STRUCT(sid_array); … … 426 591 427 592 lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names); 428 if ( !lsa_names) {593 if (lsa_names == NULL) { 429 594 return NT_STATUS_NO_MEMORY; 430 595 } 431 596 432 for (i =0; i<num_names; i++) {597 for (i = 0; i < num_names; i++) { 433 598 init_lsa_String(&lsa_names[i], names[i]); 434 599 } 435 600 436 601 if (use_lookupnames4) { 437 result = rpccli_lsa_LookupNames4(cli, mem_ctx, 602 status = dcerpc_lsa_LookupNames4(h, 603 mem_ctx, 438 604 num_names, 439 605 lsa_names, … … 442 608 level, 443 609 &count, 444 0, 445 0); 610 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES, 611 LSA_CLIENT_REVISION_2, 612 presult); 446 613 } else { 447 result = rpccli_lsa_LookupNames(cli, mem_ctx, 448 pol, 614 status = dcerpc_lsa_LookupNames(h, 615 mem_ctx, 616 pol, 449 617 num_names, 450 618 lsa_names, … … 452 620 &sid_array, 453 621 level, 454 &count); 455 } 456 457 if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != 458 NT_STATUS_V(STATUS_SOME_UNMAPPED)) { 459 622 &count, 623 presult); 624 } 625 if (!NT_STATUS_IS_OK(status)) { 626 goto done; 627 } 628 629 if (!NT_STATUS_IS_OK(*presult) && 630 !NT_STATUS_EQUAL(*presult, STATUS_SOME_UNMAPPED)) { 460 631 /* An actual error occured */ 461 462 632 goto done; 463 633 } 464 634 465 635 /* Return output parameters */ 466 467 636 if (count == 0) { 468 result = NT_STATUS_NONE_MAPPED;637 *presult = NT_STATUS_NONE_MAPPED; 469 638 goto done; 470 639 } 471 640 472 641 if (num_names) { 473 if (!((*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_names)))) {642 if (!((*sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_names)))) { 474 643 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); 475 result = NT_STATUS_NO_MEMORY;644 *presult = NT_STATUS_NO_MEMORY; 476 645 goto done; 477 646 } … … 479 648 if (!((*types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_names)))) { 480 649 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); 481 result = NT_STATUS_NO_MEMORY;650 *presult = NT_STATUS_NO_MEMORY; 482 651 goto done; 483 652 } … … 487 656 if (*dom_names == NULL) { 488 657 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); 489 result = NT_STATUS_NO_MEMORY;658 *presult = NT_STATUS_NO_MEMORY; 490 659 goto done; 491 660 } … … 501 670 for (i = 0; i < num_names; i++) { 502 671 uint32_t dom_idx; 503 DOM_SID*sid = &(*sids)[i];672 struct dom_sid *sid = &(*sids)[i]; 504 673 505 674 if (use_lookupnames4) { … … 538 707 539 708 done: 540 541 return result; 709 return status; 710 } 711 712 NTSTATUS dcerpc_lsa_lookup_names(struct dcerpc_binding_handle *h, 713 TALLOC_CTX *mem_ctx, 714 struct policy_handle *pol, 715 uint32_t num_names, 716 const char **names, 717 const char ***dom_names, 718 enum lsa_LookupNamesLevel level, 719 struct dom_sid **sids, 720 enum lsa_SidType **types, 721 NTSTATUS *result) 722 { 723 return dcerpc_lsa_lookup_names_generic(h, 724 mem_ctx, 725 pol, 726 num_names, 727 names, 728 dom_names, 729 level, 730 sids, 731 types, 732 false, 733 result); 542 734 } 543 735 544 736 NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, 545 737 TALLOC_CTX *mem_ctx, 546 struct policy_handle *pol, int num_names, 738 struct policy_handle *pol, 739 int num_names, 547 740 const char **names, 548 741 const char ***dom_names, 549 742 int level, 550 DOM_SID**sids,743 struct dom_sid **sids, 551 744 enum lsa_SidType **types) 552 745 { 553 return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names, 554 names, dom_names, level, sids, 555 types, false); 746 NTSTATUS status; 747 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 748 749 status = dcerpc_lsa_lookup_names(cli->binding_handle, 750 mem_ctx, 751 pol, 752 num_names, 753 names, 754 dom_names, 755 level, 756 sids, 757 types, 758 &result); 759 if (!NT_STATUS_IS_OK(status)) { 760 return status; 761 } 762 763 return result; 764 } 765 766 NTSTATUS dcerpc_lsa_lookup_names4(struct dcerpc_binding_handle *h, 767 TALLOC_CTX *mem_ctx, 768 struct policy_handle *pol, 769 uint32_t num_names, 770 const char **names, 771 const char ***dom_names, 772 enum lsa_LookupNamesLevel level, 773 struct dom_sid **sids, 774 enum lsa_SidType **types, 775 NTSTATUS *result) 776 { 777 return dcerpc_lsa_lookup_names_generic(h, 778 mem_ctx, 779 pol, 780 num_names, 781 names, 782 dom_names, 783 level, 784 sids, 785 types, 786 true, 787 result); 556 788 } 557 789 558 790 NTSTATUS rpccli_lsa_lookup_names4(struct rpc_pipe_client *cli, 559 791 TALLOC_CTX *mem_ctx, 560 struct policy_handle *pol, int num_names, 792 struct policy_handle *pol, 793 int num_names, 561 794 const char **names, 562 795 const char ***dom_names, 563 796 int level, 564 DOM_SID**sids,797 struct dom_sid **sids, 565 798 enum lsa_SidType **types) 566 799 { 567 return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names, 568 names, dom_names, level, sids, 569 types, true); 570 } 800 NTSTATUS status; 801 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 802 803 status = dcerpc_lsa_lookup_names4(cli->binding_handle, 804 mem_ctx, 805 pol, 806 num_names, 807 names, 808 dom_names, 809 level, 810 sids, 811 types, 812 &result); 813 if (!NT_STATUS_IS_OK(status)) { 814 return status; 815 } 816 817 return result; 818 } -
vendor/current/source3/rpc_client/cli_netlogon.c
r594 r740 22 22 23 23 #include "includes.h" 24 #include "rpc_client/rpc_client.h" 24 25 #include "../libcli/auth/libcli_auth.h" 25 #include "../librpc/gen_ndr/cli_netlogon.h" 26 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 27 #include "rpc_client/cli_netlogon.h" 28 #include "rpc_client/init_netlogon.h" 29 #include "rpc_client/util_netlogon.h" 30 #include "../libcli/security/security.h" 26 31 27 32 /**************************************************************************** … … 40 45 uint32_t *neg_flags_inout) 41 46 { 47 NTSTATUS status; 42 48 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 43 49 struct netr_Credential clnt_chal_send; … … 47 53 fstring mach_acct; 48 54 uint32_t neg_flags = *neg_flags_inout; 55 struct dcerpc_binding_handle *b = cli->binding_handle; 49 56 50 57 if (!ndr_syntax_id_equal(&cli->abstract_syntax, … … 65 72 66 73 /* Get the server challenge. */ 67 result = rpccli_netr_ServerReqChallenge(cli, talloc_tos(),74 status = dcerpc_netr_ServerReqChallenge(b, talloc_tos(), 68 75 cli->srv_name_slash, 69 76 clnt_name, 70 77 &clnt_chal_send, 71 &srv_chal_recv); 78 &srv_chal_recv, 79 &result); 80 if (!NT_STATUS_IS_OK(status)) { 81 return status; 82 } 72 83 if (!NT_STATUS_IS_OK(result)) { 73 84 return result; … … 75 86 76 87 /* Calculate the session key and client credentials */ 77 88 78 89 cli->dc = netlogon_creds_client_init(cli, 79 90 mach_acct, … … 93 104 */ 94 105 95 result = rpccli_netr_ServerAuthenticate2(cli, talloc_tos(),106 status = dcerpc_netr_ServerAuthenticate2(b, talloc_tos(), 96 107 cli->srv_name_slash, 97 108 cli->dc->account_name, … … 100 111 &clnt_chal_send, /* input. */ 101 112 &srv_chal_recv, /* output. */ 102 &neg_flags); 103 113 &neg_flags, 114 &result); 115 if (!NT_STATUS_IS_OK(status)) { 116 return status; 117 } 104 118 /* we might be talking to NT4, so let's downgrade in that case and retry 105 119 * with the returned neg_flags - gd */ … … 149 163 const char *password, 150 164 const char *workstation, 165 uint16_t validation_level, 151 166 int logon_type) 152 167 { 153 168 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 169 NTSTATUS status; 154 170 struct netr_Authenticator clnt_creds; 155 171 struct netr_Authenticator ret_creds; … … 157 173 union netr_Validation validation; 158 174 uint8_t authoritative; 159 int validation_level = 3;160 175 fstring clnt_name_slash; 161 uint8 zeros[16];176 struct dcerpc_binding_handle *b = cli->binding_handle; 162 177 163 178 ZERO_STRUCT(ret_creds); 164 ZERO_STRUCT(zeros);165 179 166 180 logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); … … 264 278 } 265 279 266 result = rpccli_netr_LogonSamLogon(cli, mem_ctx,280 status = dcerpc_netr_LogonSamLogon(b, mem_ctx, 267 281 cli->srv_name_slash, 268 282 global_myname(), … … 273 287 validation_level, 274 288 &validation, 275 &authoritative); 289 &authoritative, 290 &result); 291 if (!NT_STATUS_IS_OK(status)) { 292 return status; 293 } 276 294 277 295 /* Always check returned credentials */ … … 282 300 283 301 return result; 284 }285 286 #define COPY_LSA_STRING(mem_ctx, in, out, name) do { \287 if (in->name.string) { \288 out->name.string = talloc_strdup(mem_ctx, in->name.string); \289 NT_STATUS_HAVE_NO_MEMORY(out->name.string); \290 } \291 } while (0)292 293 static NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,294 const struct netr_SamBaseInfo *in,295 struct netr_SamBaseInfo *out)296 {297 /* first copy all, then realloc pointers */298 *out = *in;299 300 COPY_LSA_STRING(mem_ctx, in, out, account_name);301 COPY_LSA_STRING(mem_ctx, in, out, full_name);302 COPY_LSA_STRING(mem_ctx, in, out, logon_script);303 COPY_LSA_STRING(mem_ctx, in, out, profile_path);304 COPY_LSA_STRING(mem_ctx, in, out, home_directory);305 COPY_LSA_STRING(mem_ctx, in, out, home_drive);306 307 if (in->groups.count) {308 out->groups.rids = (struct samr_RidWithAttribute *)309 talloc_memdup(mem_ctx, in->groups.rids,310 (sizeof(struct samr_RidWithAttribute) *311 in->groups.count));312 NT_STATUS_HAVE_NO_MEMORY(out->groups.rids);313 }314 315 COPY_LSA_STRING(mem_ctx, in, out, logon_server);316 COPY_LSA_STRING(mem_ctx, in, out, domain);317 318 if (in->domain_sid) {319 out->domain_sid = sid_dup_talloc(mem_ctx, in->domain_sid);320 NT_STATUS_HAVE_NO_MEMORY(out->domain_sid);321 }322 323 return NT_STATUS_OK;324 302 } 325 303 … … 391 369 { 392 370 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 371 NTSTATUS status; 393 372 const char *workstation_name_slash; 394 373 const char *server_name_slash; 395 uint8 zeros[16];396 374 struct netr_Authenticator clnt_creds; 397 375 struct netr_Authenticator ret_creds; … … 402 380 struct netr_ChallengeResponse lm; 403 381 struct netr_ChallengeResponse nt; 382 struct dcerpc_binding_handle *b = cli->binding_handle; 404 383 405 384 *info3 = NULL; 406 385 407 ZERO_STRUCT(zeros);408 386 ZERO_STRUCT(ret_creds); 409 387 … … 462 440 /* Marshall data and send request */ 463 441 464 result = rpccli_netr_LogonSamLogon(cli, mem_ctx,442 status = dcerpc_netr_LogonSamLogon(b, mem_ctx, 465 443 server_name_slash, 466 444 global_myname(), … … 471 449 validation_level, 472 450 &validation, 473 &authoritative); 474 if (!NT_STATUS_IS_OK(result)) { 475 return result; 451 &authoritative, 452 &result); 453 if (!NT_STATUS_IS_OK(status)) { 454 return status; 476 455 } 477 456 … … 480 459 DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n")); 481 460 return NT_STATUS_ACCESS_DENIED; 461 } 462 463 if (!NT_STATUS_IS_OK(result)) { 464 return result; 482 465 } 483 466 … … 506 489 { 507 490 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 491 NTSTATUS status; 508 492 const char *workstation_name_slash; 509 493 const char *server_name_slash; 510 uint8 zeros[16];511 494 union netr_LogonLevel *logon = NULL; 512 495 struct netr_NetworkInfo *network_info; … … 516 499 struct netr_ChallengeResponse nt; 517 500 uint32_t flags = 0; 501 struct dcerpc_binding_handle *b = cli->binding_handle; 518 502 519 503 *info3 = NULL; 520 521 ZERO_STRUCT(zeros);522 504 523 505 ZERO_STRUCT(lm); … … 573 555 /* Marshall data and send request */ 574 556 575 result = rpccli_netr_LogonSamLogonEx(cli, mem_ctx,557 status = dcerpc_netr_LogonSamLogonEx(b, mem_ctx, 576 558 server_name_slash, 577 559 global_myname(), … … 581 563 &validation, 582 564 &authoritative, 583 &flags); 565 &flags, 566 &result); 567 if (!NT_STATUS_IS_OK(status)) { 568 return status; 569 } 570 584 571 if (!NT_STATUS_IS_OK(result)) { 585 572 return result; … … 613 600 enum netr_SchannelType sec_channel_type) 614 601 { 615 NTSTATUS result ;602 NTSTATUS result, status; 616 603 struct netr_Authenticator clnt_creds, srv_cred; 604 struct dcerpc_binding_handle *b = cli->binding_handle; 617 605 618 606 if (!cli->dc) { … … 643 631 &new_password); 644 632 645 result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx,633 status = dcerpc_netr_ServerPasswordSet2(b, mem_ctx, 646 634 cli->srv_name_slash, 647 635 cli->dc->account_name, … … 650 638 &clnt_creds, 651 639 &srv_cred, 652 &new_password); 653 if (!NT_STATUS_IS_OK(result)) { 654 DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n", 655 nt_errstr(result))); 656 return result; 640 &new_password, 641 &result); 642 if (!NT_STATUS_IS_OK(status)) { 643 DEBUG(0,("dcerpc_netr_ServerPasswordSet2 failed: %s\n", 644 nt_errstr(status))); 645 return status; 657 646 } 658 647 } else { … … 662 651 netlogon_creds_des_encrypt(cli->dc, &new_password); 663 652 664 result = rpccli_netr_ServerPasswordSet(cli, mem_ctx,653 status = dcerpc_netr_ServerPasswordSet(b, mem_ctx, 665 654 cli->srv_name_slash, 666 655 cli->dc->account_name, … … 669 658 &clnt_creds, 670 659 &srv_cred, 671 &new_password); 672 if (!NT_STATUS_IS_OK(result)) { 673 DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n", 674 nt_errstr(result))); 675 return result; 660 &new_password, 661 &result); 662 if (!NT_STATUS_IS_OK(status)) { 663 DEBUG(0,("dcerpc_netr_ServerPasswordSet failed: %s\n", 664 nt_errstr(status))); 665 return status; 676 666 } 677 667 } … … 683 673 } 684 674 675 if (!NT_STATUS_IS_OK(result)) { 676 DEBUG(0,("dcerpc_netr_ServerPasswordSet{2} failed: %s\n", 677 nt_errstr(result))); 678 return result; 679 } 680 685 681 return result; 686 682 } -
vendor/current/source3/rpc_client/cli_pipe.c
r597 r740 1 /* 1 /* 2 2 * Unix SMB/CIFS implementation. 3 * RPC Pipe client / serverroutines3 * RPC Pipe client routines 4 4 * Largely rewritten by Jeremy Allison 2005. 5 * 5 * Heavily modified by Simo Sorce 2010. 6 * 6 7 * This program is free software; you can redistribute it and/or modify 7 8 * it under the terms of the GNU General Public License as published by 8 9 * the Free Software Foundation; either version 3 of the License, or 9 10 * (at your option) any later version. 10 * 11 * 11 12 * This program is distributed in the hope that it will be useful, 12 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 15 * GNU General Public License for more details. 15 * 16 * 16 17 * You should have received a copy of the GNU General Public License 17 18 * along with this program; if not, see <http://www.gnu.org/licenses/>. … … 19 20 20 21 #include "includes.h" 21 #include "librpc/gen_ndr/cli_epmapper.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "librpc/gen_ndr/ndr_epmapper_c.h" 22 24 #include "../librpc/gen_ndr/ndr_schannel.h" 25 #include "../librpc/gen_ndr/ndr_dssetup.h" 23 26 #include "../libcli/auth/schannel.h" 24 27 #include "../libcli/auth/spnego.h" 25 #include "smb_krb5.h" 28 #include "../libcli/auth/ntlmssp.h" 29 #include "ntlmssp_wrap.h" 30 #include "librpc/gen_ndr/ndr_dcerpc.h" 31 #include "librpc/rpc/dcerpc.h" 32 #include "librpc/crypto/gse.h" 33 #include "librpc/crypto/spnego.h" 34 #include "rpc_dce.h" 35 #include "cli_pipe.h" 36 #include "client.h" 26 37 27 38 #undef DBGC_CLASS 28 39 #define DBGC_CLASS DBGC_RPC_CLI 29 30 static const char *get_pipe_name_from_iface(31 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)32 {33 int i;34 const struct ndr_interface_string_array *ep = interface->endpoints;35 char *p;36 37 for (i=0; i<ep->count; i++) {38 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {39 break;40 }41 }42 if (i == ep->count) {43 return NULL;44 }45 46 /*47 * extract the pipe name without \\pipe from for example48 * ncacn_np:[\\pipe\\epmapper]49 */50 p = strchr(ep->names[i]+15, ']');51 if (p == NULL) {52 return "PIPE";53 }54 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);55 }56 57 static const struct ndr_interface_table **interfaces;58 59 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)60 {61 int num_interfaces = talloc_array_length(interfaces);62 const struct ndr_interface_table **tmp;63 int i;64 65 for (i=0; i<num_interfaces; i++) {66 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,67 &interface->syntax_id)) {68 return true;69 }70 }71 72 tmp = talloc_realloc(NULL, interfaces,73 const struct ndr_interface_table *,74 num_interfaces + 1);75 if (tmp == NULL) {76 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));77 return false;78 }79 interfaces = tmp;80 interfaces[num_interfaces] = interface;81 return true;82 }83 84 static bool initialize_interfaces(void)85 {86 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {87 return false;88 }89 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {90 return false;91 }92 if (!smb_register_ndr_interface(&ndr_table_samr)) {93 return false;94 }95 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {96 return false;97 }98 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {99 return false;100 }101 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {102 return false;103 }104 if (!smb_register_ndr_interface(&ndr_table_winreg)) {105 return false;106 }107 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {108 return false;109 }110 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {111 return false;112 }113 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {114 return false;115 }116 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {117 return false;118 }119 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {120 return false;121 }122 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {123 return false;124 }125 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {126 return false;127 }128 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {129 return false;130 }131 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {132 return false;133 }134 return true;135 }136 137 const struct ndr_interface_table *get_iface_from_syntax(138 const struct ndr_syntax_id *syntax)139 {140 int num_interfaces;141 int i;142 143 if (interfaces == NULL) {144 if (!initialize_interfaces()) {145 return NULL;146 }147 }148 num_interfaces = talloc_array_length(interfaces);149 150 for (i=0; i<num_interfaces; i++) {151 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {152 return interfaces[i];153 }154 }155 156 return NULL;157 }158 159 /****************************************************************************160 Return the pipe name from the interface.161 ****************************************************************************/162 163 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,164 const struct ndr_syntax_id *syntax)165 {166 const struct ndr_interface_table *interface;167 char *guid_str;168 const char *result;169 170 interface = get_iface_from_syntax(syntax);171 if (interface != NULL) {172 result = get_pipe_name_from_iface(mem_ctx, interface);173 if (result != NULL) {174 return result;175 }176 }177 178 /*179 * Here we should ask \\epmapper, but for now our code is only180 * interested in the known pipes mentioned in pipe_names[]181 */182 183 guid_str = GUID_string(talloc_tos(), &syntax->uuid);184 if (guid_str == NULL) {185 return NULL;186 }187 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,188 (int)syntax->if_version);189 TALLOC_FREE(guid_str);190 191 if (result == NULL) {192 return "PIPE";193 }194 return result;195 }196 197 /********************************************************************198 Map internal value to wire value.199 ********************************************************************/200 201 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)202 {203 switch (auth_type) {204 205 case PIPE_AUTH_TYPE_NONE:206 return DCERPC_AUTH_TYPE_NONE;207 208 case PIPE_AUTH_TYPE_NTLMSSP:209 return DCERPC_AUTH_TYPE_NTLMSSP;210 211 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:212 case PIPE_AUTH_TYPE_SPNEGO_KRB5:213 return DCERPC_AUTH_TYPE_SPNEGO;214 215 case PIPE_AUTH_TYPE_SCHANNEL:216 return DCERPC_AUTH_TYPE_SCHANNEL;217 218 case PIPE_AUTH_TYPE_KRB5:219 return DCERPC_AUTH_TYPE_KRB5;220 221 default:222 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "223 "auth type %u\n",224 (unsigned int)auth_type ));225 break;226 }227 return -1;228 }229 40 230 41 /******************************************************************** … … 250 61 return ++call_id; 251 62 } 252 253 /*254 * Realloc pdu to have a least "size" bytes255 */256 257 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)258 {259 size_t extra_size;260 261 if (prs_data_size(pdu) >= size) {262 return true;263 }264 265 extra_size = size - prs_data_size(pdu);266 267 if (!prs_force_grow(pdu, extra_size)) {268 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "269 "%d bytes.\n", (int)extra_size));270 return false;271 }272 273 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",274 (int)extra_size, prs_data_size(pdu)));275 return true;276 }277 278 63 279 64 /******************************************************************* … … 442 227 443 228 444 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,445 struct rpc_hdr_info *prhdr,446 prs_struct *pdu)447 {448 /*449 * This next call sets the endian bit correctly in current_pdu. We450 * will propagate this to rbuf later.451 */452 453 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {454 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));455 return NT_STATUS_BUFFER_TOO_SMALL;456 }457 458 if (prhdr->frag_len > cli->max_recv_frag) {459 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"460 " we only allow %d\n", (int)prhdr->frag_len,461 (int)cli->max_recv_frag));462 return NT_STATUS_BUFFER_TOO_SMALL;463 }464 465 return NT_STATUS_OK;466 }467 468 229 /**************************************************************************** 469 230 Try and get a PDU's worth of data from current_pdu. If not, then read more … … 474 235 struct event_context *ev; 475 236 struct rpc_pipe_client *cli; 476 struct rpc_hdr_info *prhdr;477 prs_struct*pdu;237 uint16_t frag_len; 238 DATA_BLOB *pdu; 478 239 }; 479 240 … … 484 245 struct event_context *ev, 485 246 struct rpc_pipe_client *cli, 486 struct rpc_hdr_info *prhdr, 487 prs_struct *pdu) 247 DATA_BLOB *pdu) 488 248 { 489 249 struct tevent_req *req, *subreq; 490 250 struct get_complete_frag_state *state; 491 uint32_t pdu_len;251 size_t received; 492 252 NTSTATUS status; 493 253 … … 499 259 state->ev = ev; 500 260 state->cli = cli; 501 state-> prhdr = prhdr;261 state->frag_len = RPC_HEADER_LEN; 502 262 state->pdu = pdu; 503 263 504 pdu_len = prs_data_size(pdu);505 if ( pdu_len< RPC_HEADER_LEN) {506 if (! rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {264 received = pdu->length; 265 if (received < RPC_HEADER_LEN) { 266 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) { 507 267 status = NT_STATUS_NO_MEMORY; 508 268 goto post_status; 509 269 } 510 subreq = rpc_read_send( 511 state, state->ev, 512 state->cli->transport, 513 (uint8_t *)(prs_data_p(state->pdu) + pdu_len), 514 RPC_HEADER_LEN - pdu_len); 270 subreq = rpc_read_send(state, state->ev, 271 state->cli->transport, 272 pdu->data + received, 273 RPC_HEADER_LEN - received); 515 274 if (subreq == NULL) { 516 275 status = NT_STATUS_NO_MEMORY; … … 522 281 } 523 282 524 status = parse_rpc_header(cli, prhdr, pdu); 525 if (!NT_STATUS_IS_OK(status)) { 526 goto post_status; 527 } 283 state->frag_len = dcerpc_get_frag_length(pdu); 528 284 529 285 /* 530 286 * Ensure we have frag_len bytes of data. 531 287 */ 532 if ( pdu_len < prhdr->frag_len) {533 if (! rpc_grow_buffer(pdu, prhdr->frag_len)) {288 if (received < state->frag_len) { 289 if (!data_blob_realloc(NULL, pdu, state->frag_len)) { 534 290 status = NT_STATUS_NO_MEMORY; 535 291 goto post_status; 536 292 } 537 293 subreq = rpc_read_send(state, state->ev, 538 539 (uint8_t *)(prs_data_p(pdu) + pdu_len),540 prhdr->frag_len - pdu_len);294 state->cli->transport, 295 pdu->data + received, 296 state->frag_len - received); 541 297 if (subreq == NULL) { 542 298 status = NT_STATUS_NO_MEMORY; … … 573 329 } 574 330 575 status = parse_rpc_header(state->cli, state->prhdr, state->pdu); 576 if (!NT_STATUS_IS_OK(status)) { 577 tevent_req_nterror(req, status); 578 return; 579 } 580 581 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) { 331 state->frag_len = dcerpc_get_frag_length(state->pdu); 332 333 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) { 582 334 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 583 335 return; … … 589 341 */ 590 342 591 subreq = rpc_read_send( 592 state, state->ev, state->cli->transport, 593 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN), 594 state->prhdr->frag_len - RPC_HEADER_LEN); 343 subreq = rpc_read_send(state, state->ev, state->cli->transport, 344 state->pdu->data + RPC_HEADER_LEN, 345 state->frag_len - RPC_HEADER_LEN); 595 346 if (tevent_req_nomem(subreq, req)) { 596 347 return; … … 617 368 { 618 369 return tevent_req_simple_recv_ntstatus(req); 619 }620 621 /****************************************************************************622 NTLMSSP specific sign/seal.623 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.624 In fact I should probably abstract these into identical pieces of code... JRA.625 ****************************************************************************/626 627 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,628 prs_struct *current_pdu,629 uint8 *p_ss_padding_len)630 {631 RPC_HDR_AUTH auth_info;632 uint32 save_offset = prs_offset(current_pdu);633 uint32 auth_len = prhdr->auth_len;634 NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state;635 unsigned char *data = NULL;636 size_t data_len;637 unsigned char *full_packet_data = NULL;638 size_t full_packet_data_len;639 DATA_BLOB auth_blob;640 NTSTATUS status;641 642 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE643 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {644 return NT_STATUS_OK;645 }646 647 if (!ntlmssp_state) {648 return NT_STATUS_INVALID_PARAMETER;649 }650 651 /* Ensure there's enough data for an authenticated response. */652 if ((auth_len > RPC_MAX_SIGN_SIZE) ||653 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {654 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",655 (unsigned int)auth_len ));656 return NT_STATUS_BUFFER_TOO_SMALL;657 }658 659 /*660 * We need the full packet data + length (minus auth stuff) as well as the packet data + length661 * after the RPC header.662 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal663 * functions as NTLMv2 checks the rpc headers also.664 */665 666 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);667 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);668 669 full_packet_data = (unsigned char *)prs_data_p(current_pdu);670 full_packet_data_len = prhdr->frag_len - auth_len;671 672 /* Pull the auth header and the following data into a blob. */673 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {674 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",675 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));676 return NT_STATUS_BUFFER_TOO_SMALL;677 }678 679 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {680 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));681 return NT_STATUS_BUFFER_TOO_SMALL;682 }683 684 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);685 auth_blob.length = auth_len;686 687 switch (cli->auth->auth_level) {688 case DCERPC_AUTH_LEVEL_PRIVACY:689 /* Data is encrypted. */690 status = ntlmssp_unseal_packet(ntlmssp_state,691 data, data_len,692 full_packet_data,693 full_packet_data_len,694 &auth_blob);695 if (!NT_STATUS_IS_OK(status)) {696 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "697 "packet from %s. Error was %s.\n",698 rpccli_pipe_txt(talloc_tos(), cli),699 nt_errstr(status) ));700 return status;701 }702 break;703 case DCERPC_AUTH_LEVEL_INTEGRITY:704 /* Data is signed. */705 status = ntlmssp_check_packet(ntlmssp_state,706 data, data_len,707 full_packet_data,708 full_packet_data_len,709 &auth_blob);710 if (!NT_STATUS_IS_OK(status)) {711 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "712 "packet from %s. Error was %s.\n",713 rpccli_pipe_txt(talloc_tos(), cli),714 nt_errstr(status) ));715 return status;716 }717 break;718 default:719 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "720 "auth level %d\n", cli->auth->auth_level));721 return NT_STATUS_INVALID_INFO_CLASS;722 }723 724 /*725 * Return the current pointer to the data offset.726 */727 728 if(!prs_set_offset(current_pdu, save_offset)) {729 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",730 (unsigned int)save_offset ));731 return NT_STATUS_BUFFER_TOO_SMALL;732 }733 734 /*735 * Remember the padding length. We must remove it from the real data736 * stream once the sign/seal is done.737 */738 739 *p_ss_padding_len = auth_info.auth_pad_len;740 741 return NT_STATUS_OK;742 }743 744 /****************************************************************************745 schannel specific sign/seal.746 ****************************************************************************/747 748 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,749 prs_struct *current_pdu,750 uint8 *p_ss_padding_len)751 {752 RPC_HDR_AUTH auth_info;753 uint32 auth_len = prhdr->auth_len;754 uint32 save_offset = prs_offset(current_pdu);755 struct schannel_state *schannel_auth =756 cli->auth->a_u.schannel_auth;757 uint8_t *data;758 uint32 data_len;759 DATA_BLOB blob;760 NTSTATUS status;761 762 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE763 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {764 return NT_STATUS_OK;765 }766 767 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {768 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));769 return NT_STATUS_INVALID_PARAMETER;770 }771 772 if (!schannel_auth) {773 return NT_STATUS_INVALID_PARAMETER;774 }775 776 /* Ensure there's enough data for an authenticated response. */777 if ((auth_len > RPC_MAX_SIGN_SIZE) ||778 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {779 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",780 (unsigned int)auth_len ));781 return NT_STATUS_INVALID_PARAMETER;782 }783 784 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;785 786 if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {787 DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",788 (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));789 return NT_STATUS_BUFFER_TOO_SMALL;790 }791 792 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {793 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));794 return NT_STATUS_BUFFER_TOO_SMALL;795 }796 797 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {798 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",799 auth_info.auth_type));800 return NT_STATUS_BUFFER_TOO_SMALL;801 }802 803 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);804 805 if (DEBUGLEVEL >= 10) {806 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);807 }808 809 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;810 811 switch (cli->auth->auth_level) {812 case DCERPC_AUTH_LEVEL_PRIVACY:813 status = netsec_incoming_packet(schannel_auth,814 talloc_tos(),815 true,816 data,817 data_len,818 &blob);819 break;820 case DCERPC_AUTH_LEVEL_INTEGRITY:821 status = netsec_incoming_packet(schannel_auth,822 talloc_tos(),823 false,824 data,825 data_len,826 &blob);827 break;828 default:829 status = NT_STATUS_INTERNAL_ERROR;830 break;831 }832 833 if (!NT_STATUS_IS_OK(status)) {834 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "835 "Connection to %s (%s).\n",836 rpccli_pipe_txt(talloc_tos(), cli),837 nt_errstr(status)));838 return NT_STATUS_INVALID_PARAMETER;839 }840 841 /*842 * Return the current pointer to the data offset.843 */844 845 if(!prs_set_offset(current_pdu, save_offset)) {846 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",847 (unsigned int)save_offset ));848 return NT_STATUS_BUFFER_TOO_SMALL;849 }850 851 /*852 * Remember the padding length. We must remove it from the real data853 * stream once the sign/seal is done.854 */855 856 *p_ss_padding_len = auth_info.auth_pad_len;857 858 return NT_STATUS_OK;859 }860 861 /****************************************************************************862 Do the authentication checks on an incoming pdu. Check sign and unseal etc.863 ****************************************************************************/864 865 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,866 prs_struct *current_pdu,867 uint8 *p_ss_padding_len)868 {869 NTSTATUS ret = NT_STATUS_OK;870 871 /* Paranioa checks for auth_len. */872 if (prhdr->auth_len) {873 if (prhdr->auth_len > prhdr->frag_len) {874 return NT_STATUS_INVALID_PARAMETER;875 }876 877 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||878 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {879 /* Integer wrap attempt. */880 return NT_STATUS_INVALID_PARAMETER;881 }882 }883 884 /*885 * Now we have a complete RPC request PDU fragment, try and verify any auth data.886 */887 888 switch(cli->auth->auth_type) {889 case PIPE_AUTH_TYPE_NONE:890 if (prhdr->auth_len) {891 DEBUG(3, ("cli_pipe_validate_rpc_response: "892 "Connection to %s - got non-zero "893 "auth len %u.\n",894 rpccli_pipe_txt(talloc_tos(), cli),895 (unsigned int)prhdr->auth_len ));896 return NT_STATUS_INVALID_PARAMETER;897 }898 break;899 900 case PIPE_AUTH_TYPE_NTLMSSP:901 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:902 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);903 if (!NT_STATUS_IS_OK(ret)) {904 return ret;905 }906 break;907 908 case PIPE_AUTH_TYPE_SCHANNEL:909 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);910 if (!NT_STATUS_IS_OK(ret)) {911 return ret;912 }913 break;914 915 case PIPE_AUTH_TYPE_KRB5:916 case PIPE_AUTH_TYPE_SPNEGO_KRB5:917 default:918 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "919 "to %s - unknown internal auth type %u.\n",920 rpccli_pipe_txt(talloc_tos(), cli),921 cli->auth->auth_type ));922 return NT_STATUS_INVALID_INFO_CLASS;923 }924 925 return NT_STATUS_OK;926 370 } 927 371 … … 930 374 ****************************************************************************/ 931 375 932 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, 933 prs_struct *current_pdu, 934 uint8 expected_pkt_type, 935 char **ppdata, 936 uint32 *pdata_len, 937 prs_struct *return_data) 938 { 939 376 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx, 377 struct rpc_pipe_client *cli, 378 struct ncacn_packet *pkt, 379 DATA_BLOB *pdu, 380 uint8_t expected_pkt_type, 381 DATA_BLOB *rdata, 382 DATA_BLOB *reply_pdu) 383 { 384 struct dcerpc_response *r; 940 385 NTSTATUS ret = NT_STATUS_OK; 941 uint32 current_pdu_len = prs_data_size(current_pdu); 942 943 if (current_pdu_len != prhdr->frag_len) { 944 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n", 945 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len )); 946 return NT_STATUS_INVALID_PARAMETER; 947 } 386 size_t pad_len = 0; 948 387 949 388 /* … … 951 390 * header. Just in case the caller wants it. 952 391 */ 953 *ppdata = prs_data_p(current_pdu); 954 *pdata_len = current_pdu_len; 392 *rdata = *pdu; 955 393 956 394 /* Ensure we have the correct type. */ 957 switch (prhdr->pkt_type) { 958 case DCERPC_PKT_ALTER_RESP: 959 case DCERPC_PKT_BIND_ACK: 960 961 /* Alter context and bind ack share the same packet definitions. */ 962 break; 963 964 965 case DCERPC_PKT_RESPONSE: 966 { 967 RPC_HDR_RESP rhdr_resp; 968 uint8 ss_padding_len = 0; 969 970 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) { 971 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n")); 972 return NT_STATUS_BUFFER_TOO_SMALL; 973 } 974 975 /* Here's where we deal with incoming sign/seal. */ 976 ret = cli_pipe_validate_rpc_response(cli, prhdr, 977 current_pdu, &ss_padding_len); 978 if (!NT_STATUS_IS_OK(ret)) { 979 return ret; 980 } 981 982 /* Point the return values at the NDR data. Remember to remove any ss padding. */ 983 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN; 984 985 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) { 986 return NT_STATUS_BUFFER_TOO_SMALL; 987 } 988 989 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len; 990 991 /* Remember to remove the auth footer. */ 992 if (prhdr->auth_len) { 993 /* We've already done integer wrap tests on auth_len in 994 cli_pipe_validate_rpc_response(). */ 995 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) { 996 return NT_STATUS_BUFFER_TOO_SMALL; 997 } 998 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len); 999 } 1000 1001 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n", 1002 current_pdu_len, *pdata_len, ss_padding_len )); 1003 1004 /* 1005 * If this is the first reply, and the allocation hint is reasonably, try and 1006 * set up the return_data parse_struct to the correct size. 1007 */ 1008 1009 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) { 1010 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) { 1011 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u " 1012 "too large to allocate\n", 1013 (unsigned int)rhdr_resp.alloc_hint )); 1014 return NT_STATUS_NO_MEMORY; 1015 } 1016 } 1017 1018 break; 395 switch (pkt->ptype) { 396 case DCERPC_PKT_ALTER_RESP: 397 case DCERPC_PKT_BIND_ACK: 398 399 /* Client code never receives this kind of packets */ 400 break; 401 402 403 case DCERPC_PKT_RESPONSE: 404 405 r = &pkt->u.response; 406 407 /* Here's where we deal with incoming sign/seal. */ 408 ret = dcerpc_check_auth(cli->auth, pkt, 409 &r->stub_and_verifier, 410 DCERPC_RESPONSE_LENGTH, 411 pdu, &pad_len); 412 if (!NT_STATUS_IS_OK(ret)) { 413 return ret; 1019 414 } 1020 415 1021 case DCERPC_PKT_BIND_NAK: 1022 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK " 1023 "received from %s!\n", 1024 rpccli_pipe_txt(talloc_tos(), cli))); 1025 /* Use this for now... */ 1026 return NT_STATUS_NETWORK_ACCESS_DENIED; 1027 1028 case DCERPC_PKT_FAULT: 1029 { 1030 RPC_HDR_RESP rhdr_resp; 1031 RPC_HDR_FAULT fault_resp; 1032 1033 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) { 1034 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n")); 1035 return NT_STATUS_BUFFER_TOO_SMALL; 1036 } 1037 1038 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) { 1039 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n")); 1040 return NT_STATUS_BUFFER_TOO_SMALL; 1041 } 1042 1043 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault " 1044 "code %s received from %s!\n", 1045 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)), 1046 rpccli_pipe_txt(talloc_tos(), cli))); 1047 if (NT_STATUS_IS_OK(fault_resp.status)) { 1048 return NT_STATUS_UNSUCCESSFUL; 1049 } else { 1050 return fault_resp.status; 416 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) { 417 return NT_STATUS_BUFFER_TOO_SMALL; 418 } 419 420 /* Point the return values at the NDR data. */ 421 rdata->data = r->stub_and_verifier.data; 422 423 if (pkt->auth_length) { 424 /* We've already done integer wrap tests in 425 * dcerpc_check_auth(). */ 426 rdata->length = r->stub_and_verifier.length 427 - pad_len 428 - DCERPC_AUTH_TRAILER_LENGTH 429 - pkt->auth_length; 430 } else { 431 rdata->length = r->stub_and_verifier.length; 432 } 433 434 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n", 435 (long unsigned int)pdu->length, 436 (long unsigned int)rdata->length, 437 (unsigned int)pad_len)); 438 439 /* 440 * If this is the first reply, and the allocation hint is 441 * reasonable, try and set up the reply_pdu DATA_BLOB to the 442 * correct size. 443 */ 444 445 if ((reply_pdu->length == 0) && 446 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) { 447 if (!data_blob_realloc(mem_ctx, reply_pdu, 448 r->alloc_hint)) { 449 DEBUG(0, ("reply alloc hint %d too " 450 "large to allocate\n", 451 (int)r->alloc_hint)); 452 return NT_STATUS_NO_MEMORY; 1051 453 } 1052 454 } 1053 455 1054 default: 1055 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received " 1056 "from %s!\n", 1057 (unsigned int)prhdr->pkt_type, 1058 rpccli_pipe_txt(talloc_tos(), cli))); 1059 return NT_STATUS_INVALID_INFO_CLASS; 1060 } 1061 1062 if (prhdr->pkt_type != expected_pkt_type) { 1063 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s " 1064 "got an unexpected RPC packet type - %u, not %u\n", 1065 rpccli_pipe_txt(talloc_tos(), cli), 1066 prhdr->pkt_type, 1067 expected_pkt_type)); 456 break; 457 458 case DCERPC_PKT_BIND_NAK: 459 DEBUG(1, (__location__ ": Bind NACK received from %s!\n", 460 rpccli_pipe_txt(talloc_tos(), cli))); 461 /* Use this for now... */ 462 return NT_STATUS_NETWORK_ACCESS_DENIED; 463 464 case DCERPC_PKT_FAULT: 465 466 DEBUG(1, (__location__ ": RPC fault code %s received " 467 "from %s!\n", 468 dcerpc_errstr(talloc_tos(), 469 pkt->u.fault.status), 470 rpccli_pipe_txt(talloc_tos(), cli))); 471 472 return dcerpc_fault_to_nt_status(pkt->u.fault.status); 473 474 default: 475 DEBUG(0, (__location__ "Unknown packet type %u received " 476 "from %s!\n", 477 (unsigned int)pkt->ptype, 478 rpccli_pipe_txt(talloc_tos(), cli))); 479 return NT_STATUS_INVALID_INFO_CLASS; 480 } 481 482 if (pkt->ptype != expected_pkt_type) { 483 DEBUG(3, (__location__ ": Connection to %s got an unexpected " 484 "RPC packet type - %u, not %u\n", 485 rpccli_pipe_txt(talloc_tos(), cli), 486 pkt->ptype, expected_pkt_type)); 1068 487 return NT_STATUS_INVALID_INFO_CLASS; 1069 488 } … … 1073 492 it before. */ 1074 493 1075 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) { 1076 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), " 1077 "setting fragment first/last ON.\n")); 1078 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST; 1079 } 1080 1081 return NT_STATUS_OK; 1082 } 1083 1084 /**************************************************************************** 1085 Ensure we eat the just processed pdu from the current_pdu prs_struct. 1086 Normally the frag_len and buffer size will match, but on the first trans 1087 reply there is a theoretical chance that buffer size > frag_len, so we must 1088 deal with that. 1089 ****************************************************************************/ 1090 1091 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu) 1092 { 1093 uint32 current_pdu_len = prs_data_size(current_pdu); 1094 1095 if (current_pdu_len < prhdr->frag_len) { 1096 return NT_STATUS_BUFFER_TOO_SMALL; 1097 } 1098 1099 /* Common case. */ 1100 if (current_pdu_len == (uint32)prhdr->frag_len) { 1101 prs_mem_free(current_pdu); 1102 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL); 1103 /* Make current_pdu dynamic with no memory. */ 1104 prs_give_memory(current_pdu, 0, 0, True); 1105 return NT_STATUS_OK; 1106 } 1107 1108 /* 1109 * Oh no ! More data in buffer than we processed in current pdu. 1110 * Cheat. Move the data down and shrink the buffer. 1111 */ 1112 1113 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len, 1114 current_pdu_len - prhdr->frag_len); 1115 1116 /* Remember to set the read offset back to zero. */ 1117 prs_set_offset(current_pdu, 0); 1118 1119 /* Shrink the buffer. */ 1120 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) { 1121 return NT_STATUS_BUFFER_TOO_SMALL; 494 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) && 495 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { 496 DEBUG(5, (__location__ ": bug in server (AS/U?), setting " 497 "fragment first/last ON.\n")); 498 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; 1122 499 } 1123 500 … … 1188 565 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req); 1189 566 return req; 1190 1191 status = NT_STATUS_INVALID_PARAMETER;1192 567 1193 568 post_status: … … 1287 662 1288 663 /**************************************************************************** 1289 Send data on an rpc pipe via trans. The prs_structdata must be the last664 Send data on an rpc pipe via trans. The data must be the last 1290 665 pdu fragment of an NDR data stream. 1291 666 … … 1317 692 uint8_t expected_pkt_type; 1318 693 1319 prs_struct incoming_frag; 1320 struct rpc_hdr_info rhdr; 1321 1322 prs_struct incoming_pdu; /* Incoming reply */ 1323 uint32_t incoming_pdu_offset; 694 DATA_BLOB incoming_frag; 695 struct ncacn_packet *pkt; 696 697 /* Incoming reply */ 698 DATA_BLOB reply_pdu; 699 size_t reply_pdu_offset; 700 uint8_t endianess; 1324 701 }; 1325 1326 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)1327 {1328 prs_mem_free(&state->incoming_frag);1329 prs_mem_free(&state->incoming_pdu);1330 return 0;1331 }1332 702 1333 703 static void rpc_api_pipe_trans_done(struct tevent_req *subreq); 1334 704 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); 705 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq); 1335 706 1336 707 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, 1337 708 struct event_context *ev, 1338 709 struct rpc_pipe_client *cli, 1339 prs_struct*data, /* Outgoing PDU */710 DATA_BLOB *data, /* Outgoing PDU */ 1340 711 uint8_t expected_pkt_type) 1341 712 { … … 1352 723 state->cli = cli; 1353 724 state->expected_pkt_type = expected_pkt_type; 1354 state->incoming_pdu_offset = 0; 1355 1356 prs_init_empty(&state->incoming_frag, state, UNMARSHALL); 1357 1358 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL); 1359 /* Make incoming_pdu dynamic with no memory. */ 1360 prs_give_memory(&state->incoming_pdu, NULL, 0, true); 1361 1362 talloc_set_destructor(state, rpc_api_pipe_state_destructor); 725 state->incoming_frag = data_blob_null; 726 state->reply_pdu = data_blob_null; 727 state->reply_pdu_offset = 0; 728 state->endianess = DCERPC_DREP_LE; 1363 729 1364 730 /* 1365 731 * Ensure we're not sending too much. 1366 732 */ 1367 if ( prs_offset(data)> cli->max_xmit_frag) {733 if (data->length > cli->max_xmit_frag) { 1368 734 status = NT_STATUS_INVALID_PARAMETER; 1369 735 goto post_status; … … 1372 738 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli))); 1373 739 1374 max_recv_frag = cli->max_recv_frag; 1375 1376 #if 0 1377 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32); 1378 #endif 740 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) { 741 subreq = rpc_write_send(state, ev, cli->transport, 742 data->data, data->length); 743 if (subreq == NULL) { 744 goto fail; 745 } 746 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req); 747 return req; 748 } 749 750 /* get the header first, then fetch the rest once we have 751 * the frag_length available */ 752 max_recv_frag = RPC_HEADER_LEN; 1379 753 1380 754 subreq = cli_api_pipe_send(state, ev, cli->transport, 1381 (uint8_t *)prs_data_p(data), 1382 prs_offset(data), max_recv_frag); 755 data->data, data->length, max_recv_frag); 1383 756 if (subreq == NULL) { 1384 757 goto fail; … … 1395 768 } 1396 769 770 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq) 771 { 772 struct tevent_req *req = 773 tevent_req_callback_data(subreq, 774 struct tevent_req); 775 NTSTATUS status; 776 777 status = rpc_write_recv(subreq); 778 TALLOC_FREE(subreq); 779 if (!NT_STATUS_IS_OK(status)) { 780 tevent_req_nterror(req, status); 781 return; 782 } 783 784 tevent_req_done(req); 785 } 786 1397 787 static void rpc_api_pipe_trans_done(struct tevent_req *subreq) 1398 788 { … … 1404 794 uint8_t *rdata = NULL; 1405 795 uint32_t rdata_len = 0; 1406 char *rdata_copy;1407 796 1408 797 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len); … … 1422 811 1423 812 /* 1424 * Give the memory received from cli_trans as dynamic to the current 1425 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc 1426 * :-( 813 * Move data on state->incoming_frag. 1427 814 */ 1428 rdata_copy = (char *)memdup(rdata, rdata_len);1429 TALLOC_FREE(rdata);1430 if ( tevent_req_nomem(rdata_copy, req)) {1431 return;1432 }1433 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);815 state->incoming_frag.data = talloc_move(state, &rdata); 816 state->incoming_frag.length = rdata_len; 817 if (!state->incoming_frag.data) { 818 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 819 return; 820 } 1434 821 1435 822 /* Ensure we have enough data for a pdu. */ 1436 823 subreq = get_complete_frag_send(state, state->ev, state->cli, 1437 &state-> rhdr, &state->incoming_frag);824 &state->incoming_frag); 1438 825 if (tevent_req_nomem(subreq, req)) { 1439 826 return; … … 1449 836 req, struct rpc_api_pipe_state); 1450 837 NTSTATUS status; 1451 char *rdata = NULL; 1452 uint32_t rdata_len = 0; 838 DATA_BLOB rdata = data_blob_null; 1453 839 1454 840 status = get_complete_frag_recv(subreq); … … 1461 847 } 1462 848 1463 status = cli_pipe_validate_current_pdu( 1464 state->cli, &state->rhdr, &state->incoming_frag, 1465 state->expected_pkt_type, &rdata, &rdata_len, 1466 &state->incoming_pdu); 849 state->pkt = talloc(state, struct ncacn_packet); 850 if (!state->pkt) { 851 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 852 return; 853 } 854 855 status = dcerpc_pull_ncacn_packet(state->pkt, 856 &state->incoming_frag, 857 state->pkt, 858 !state->endianess); 859 if (!NT_STATUS_IS_OK(status)) { 860 tevent_req_nterror(req, status); 861 return; 862 } 863 864 if (state->incoming_frag.length != state->pkt->frag_length) { 865 DEBUG(5, ("Incorrect pdu length %u, expected %u\n", 866 (unsigned int)state->incoming_frag.length, 867 (unsigned int)state->pkt->frag_length)); 868 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 869 return; 870 } 871 872 status = cli_pipe_validate_current_pdu(state, 873 state->cli, state->pkt, 874 &state->incoming_frag, 875 state->expected_pkt_type, 876 &rdata, 877 &state->reply_pdu); 1467 878 1468 879 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n", 1469 (unsigned) prs_data_size(&state->incoming_frag),1470 (unsigned)state-> incoming_pdu_offset,880 (unsigned)state->incoming_frag.length, 881 (unsigned)state->reply_pdu_offset, 1471 882 nt_errstr(status))); 1472 883 … … 1476 887 } 1477 888 1478 if ((state-> rhdr.flags & DCERPC_PFC_FLAG_FIRST)1479 && (state-> rhdr.pack_type[0] == 0)) {889 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) 890 && (state->pkt->drep[0] != DCERPC_DREP_LE)) { 1480 891 /* 1481 892 * Set the data type correctly for big-endian data on the … … 1485 896 "big-endian.\n", 1486 897 rpccli_pipe_txt(talloc_tos(), state->cli))); 1487 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);898 state->endianess = 0x00; /* BIG ENDIAN */ 1488 899 } 1489 900 /* 1490 901 * Check endianness on subsequent packets. 1491 902 */ 1492 if (state->incoming_frag.bigendian_data 1493 != state->incoming_pdu.bigendian_data) { 903 if (state->endianess != state->pkt->drep[0]) { 1494 904 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to " 1495 905 "%s\n", 1496 state-> incoming_pdu.bigendian_data?"big":"little",1497 state-> incoming_frag.bigendian_data?"big":"little"));906 state->endianess?"little":"big", 907 state->pkt->drep[0]?"little":"big")); 1498 908 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1499 909 return; … … 1501 911 1502 912 /* Now copy the data portion out of the pdu into rbuf. */ 1503 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) { 1504 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1505 return; 1506 } 1507 1508 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset, 1509 rdata, (size_t)rdata_len); 1510 state->incoming_pdu_offset += rdata_len; 1511 1512 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr, 1513 &state->incoming_frag); 1514 if (!NT_STATUS_IS_OK(status)) { 1515 tevent_req_nterror(req, status); 1516 return; 1517 } 1518 1519 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) { 913 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) { 914 if (!data_blob_realloc(NULL, &state->reply_pdu, 915 state->reply_pdu_offset + rdata.length)) { 916 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 917 return; 918 } 919 } 920 921 memcpy(state->reply_pdu.data + state->reply_pdu_offset, 922 rdata.data, rdata.length); 923 state->reply_pdu_offset += rdata.length; 924 925 /* reset state->incoming_frag, there is no need to free it, 926 * it will be reallocated to the right size the next time 927 * it is used */ 928 state->incoming_frag.length = 0; 929 930 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) { 931 /* make sure the pdu length is right now that we 932 * have all the data available (alloc hint may 933 * have allocated more than was actually used) */ 934 state->reply_pdu.length = state->reply_pdu_offset; 1520 935 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", 1521 936 rpccli_pipe_txt(talloc_tos(), state->cli), 1522 (unsigned) prs_data_size(&state->incoming_pdu)));937 (unsigned)state->reply_pdu.length)); 1523 938 tevent_req_done(req); 1524 939 return; … … 1526 941 1527 942 subreq = get_complete_frag_send(state, state->ev, state->cli, 1528 &state-> rhdr, &state->incoming_frag);943 &state->incoming_frag); 1529 944 if (tevent_req_nomem(subreq, req)) { 1530 945 return; … … 1534 949 1535 950 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1536 prs_struct *reply_pdu) 951 struct ncacn_packet **pkt, 952 DATA_BLOB *reply_pdu) 1537 953 { 1538 954 struct rpc_api_pipe_state *state = tevent_req_data( … … 1544 960 } 1545 961 1546 *reply_pdu = state->incoming_pdu; 1547 reply_pdu->mem_ctx = mem_ctx; 1548 1549 /* 1550 * Prevent state->incoming_pdu from being freed in 1551 * rpc_api_pipe_state_destructor() 1552 */ 1553 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL); 962 /* return data to caller and assign it ownership of memory */ 963 if (reply_pdu) { 964 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data); 965 reply_pdu->length = state->reply_pdu.length; 966 state->reply_pdu.length = 0; 967 } else { 968 data_blob_free(&state->reply_pdu); 969 } 970 971 if (pkt) { 972 *pkt = talloc_steal(mem_ctx, state->pkt); 973 } 974 975 return NT_STATUS_OK; 976 } 977 978 /******************************************************************* 979 Creates spnego auth bind. 980 ********************************************************************/ 981 982 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx, 983 struct pipe_auth_data *auth, 984 DATA_BLOB *auth_token) 985 { 986 struct spnego_context *spnego_ctx; 987 DATA_BLOB in_token = data_blob_null; 988 NTSTATUS status; 989 990 spnego_ctx = talloc_get_type_abort(auth->auth_ctx, 991 struct spnego_context); 992 993 /* Negotiate the initial auth token */ 994 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx, 995 &in_token, auth_token); 996 if (!NT_STATUS_IS_OK(status)) { 997 return status; 998 } 999 1000 DEBUG(5, ("Created GSS Authentication Token:\n")); 1001 dump_data(5, auth_token->data, auth_token->length); 1554 1002 1555 1003 return NT_STATUS_OK; … … 1560 1008 ********************************************************************/ 1561 1009 1562 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, 1563 enum dcerpc_AuthLevel auth_level, 1564 RPC_HDR_AUTH *pauth_out, 1565 prs_struct *auth_data) 1566 { 1567 #ifdef HAVE_KRB5 1568 int ret; 1569 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth; 1570 DATA_BLOB tkt = data_blob_null; 1571 DATA_BLOB tkt_wrapped = data_blob_null; 1572 1573 /* We may change the pad length before marshalling. */ 1574 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1); 1575 1576 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n", 1577 a->service_principal )); 1578 1579 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ 1580 1581 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt, 1582 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL); 1583 1584 if (ret) { 1585 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " 1586 "failed with %s\n", 1587 a->service_principal, 1588 error_message(ret) )); 1589 1590 data_blob_free(&tkt); 1591 prs_mem_free(auth_data); 1592 return NT_STATUS_INVALID_PARAMETER; 1593 } 1594 1595 /* wrap that up in a nice GSS-API wrapping */ 1596 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); 1597 1598 data_blob_free(&tkt); 1599 1600 /* Auth len in the rpc header doesn't include auth_header. */ 1601 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) { 1602 data_blob_free(&tkt_wrapped); 1603 prs_mem_free(auth_data); 1604 return NT_STATUS_NO_MEMORY; 1605 } 1606 1607 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n")); 1608 dump_data(5, tkt_wrapped.data, tkt_wrapped.length); 1609 1610 data_blob_free(&tkt_wrapped); 1611 return NT_STATUS_OK; 1612 #else 1613 return NT_STATUS_INVALID_PARAMETER; 1614 #endif 1615 } 1616 1617 /******************************************************************* 1618 Creates SPNEGO NTLMSSP auth bind. 1619 ********************************************************************/ 1620 1621 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, 1622 enum dcerpc_AuthLevel auth_level, 1623 RPC_HDR_AUTH *pauth_out, 1624 prs_struct *auth_data) 1625 { 1626 NTSTATUS nt_status; 1627 DATA_BLOB null_blob = data_blob_null; 1628 DATA_BLOB request = data_blob_null; 1629 DATA_BLOB spnego_msg = data_blob_null; 1630 1631 /* We may change the pad length before marshalling. */ 1632 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1); 1633 1634 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); 1635 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, 1636 null_blob, 1637 &request); 1638 1639 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1640 data_blob_free(&request); 1641 prs_mem_free(auth_data); 1642 return nt_status; 1643 } 1644 1645 /* Wrap this in SPNEGO. */ 1646 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request); 1647 1648 data_blob_free(&request); 1649 1650 /* Auth len in the rpc header doesn't include auth_header. */ 1651 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) { 1652 data_blob_free(&spnego_msg); 1653 prs_mem_free(auth_data); 1654 return NT_STATUS_NO_MEMORY; 1655 } 1656 1657 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); 1658 dump_data(5, spnego_msg.data, spnego_msg.length); 1659 1660 data_blob_free(&spnego_msg); 1010 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx, 1011 struct pipe_auth_data *auth, 1012 DATA_BLOB *auth_token) 1013 { 1014 struct gse_context *gse_ctx; 1015 DATA_BLOB in_token = data_blob_null; 1016 NTSTATUS status; 1017 1018 gse_ctx = talloc_get_type_abort(auth->auth_ctx, 1019 struct gse_context); 1020 1021 /* Negotiate the initial auth token */ 1022 status = gse_get_client_auth_token(mem_ctx, gse_ctx, 1023 &in_token, 1024 auth_token); 1025 if (!NT_STATUS_IS_OK(status)) { 1026 return status; 1027 } 1028 1029 DEBUG(5, ("Created GSS Authentication Token:\n")); 1030 dump_data(5, auth_token->data, auth_token->length); 1031 1661 1032 return NT_STATUS_OK; 1662 1033 } … … 1666 1037 ********************************************************************/ 1667 1038 1668 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, 1669 enum dcerpc_AuthLevel auth_level, 1670 RPC_HDR_AUTH *pauth_out, 1671 prs_struct *auth_data) 1672 { 1673 NTSTATUS nt_status; 1039 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli, 1040 DATA_BLOB *auth_token) 1041 { 1042 struct auth_ntlmssp_state *ntlmssp_ctx; 1674 1043 DATA_BLOB null_blob = data_blob_null; 1675 DATA_BLOB request = data_blob_null;1676 1677 /* We may change the pad length before marshalling. */1678 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);1044 NTSTATUS status; 1045 1046 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx, 1047 struct auth_ntlmssp_state); 1679 1048 1680 1049 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); 1681 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, 1682 null_blob, 1683 &request); 1684 1685 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1686 data_blob_free(&request); 1687 prs_mem_free(auth_data); 1688 return nt_status; 1689 } 1690 1691 /* Auth len in the rpc header doesn't include auth_header. */ 1692 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) { 1693 data_blob_free(&request); 1694 prs_mem_free(auth_data); 1695 return NT_STATUS_NO_MEMORY; 1050 status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token); 1051 1052 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1053 data_blob_free(auth_token); 1054 return status; 1696 1055 } 1697 1056 1698 1057 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); 1699 dump_data(5, request.data, request.length); 1700 1701 data_blob_free(&request); 1058 dump_data(5, auth_token->data, auth_token->length); 1059 1702 1060 return NT_STATUS_OK; 1703 1061 } … … 1707 1065 ********************************************************************/ 1708 1066 1709 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, 1710 enum dcerpc_AuthLevel auth_level, 1711 RPC_HDR_AUTH *pauth_out, 1712 prs_struct *auth_data) 1713 { 1067 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli, 1068 DATA_BLOB *auth_token) 1069 { 1070 NTSTATUS status; 1714 1071 struct NL_AUTH_MESSAGE r; 1715 enum ndr_err_code ndr_err;1716 DATA_BLOB blob;1717 1718 /* We may change the pad length before marshalling. */1719 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);1720 1072 1721 1073 /* Use lp_workgroup() if domain not specified */ … … 1738 1090 r.oem_netbios_computer.a = global_myname(); 1739 1091 1740 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &r, 1741 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); 1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1743 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n")); 1744 prs_mem_free(auth_data); 1745 return ndr_map_error2ntstatus(ndr_err); 1746 } 1747 1748 if (DEBUGLEVEL >= 10) { 1749 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r); 1750 } 1751 1752 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length)) 1753 { 1754 prs_mem_free(auth_data); 1755 return NT_STATUS_NO_MEMORY; 1092 status = dcerpc_push_schannel_bind(cli, &r, auth_token); 1093 if (!NT_STATUS_IS_OK(status)) { 1094 return status; 1756 1095 } 1757 1096 … … 1763 1102 ********************************************************************/ 1764 1103 1765 static NTSTATUS create_bind_or_alt_ctx_internal( enum dcerpc_pkt_type pkt_type,1766 prs_struct *rpc_out,1104 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx, 1105 enum dcerpc_pkt_type ptype, 1767 1106 uint32 rpc_call_id, 1768 1107 const struct ndr_syntax_id *abstract, 1769 1108 const struct ndr_syntax_id *transfer, 1770 RPC_HDR_AUTH *phdr_auth, 1771 prs_struct *pauth_info) 1772 { 1773 RPC_HDR hdr; 1774 RPC_HDR_RB hdr_rb; 1775 RPC_CONTEXT rpc_ctx; 1776 uint16 auth_len = prs_offset(pauth_info); 1777 uint8 ss_padding_len = 0; 1778 uint16 frag_len = 0; 1779 1780 /* create the RPC context. */ 1781 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer); 1782 1783 /* create the bind request RPC_HDR_RB */ 1784 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx); 1785 1786 /* Start building the frag length. */ 1787 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb); 1788 1789 /* Do we need to pad ? */ 1109 const DATA_BLOB *auth_info, 1110 DATA_BLOB *blob) 1111 { 1112 uint16 auth_len = auth_info->length; 1113 NTSTATUS status; 1114 union dcerpc_payload u; 1115 struct dcerpc_ctx_list ctx_list; 1116 1790 1117 if (auth_len) { 1791 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb); 1792 if (data_len % 8) { 1793 ss_padding_len = 8 - (data_len % 8); 1794 phdr_auth->auth_pad_len = ss_padding_len; 1795 } 1796 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len; 1797 } 1798 1799 /* Create the request RPC_HDR */ 1800 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len); 1801 1802 /* Marshall the RPC header */ 1803 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { 1804 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n")); 1805 return NT_STATUS_NO_MEMORY; 1806 } 1807 1808 /* Marshall the bind request data */ 1809 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) { 1810 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n")); 1811 return NT_STATUS_NO_MEMORY; 1812 } 1813 1814 /* 1815 * Grow the outgoing buffer to store any auth info. 1816 */ 1817 1818 if(auth_len != 0) { 1819 if (ss_padding_len) { 1820 char pad[8]; 1821 memset(pad, '\0', 8); 1822 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) { 1823 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n")); 1824 return NT_STATUS_NO_MEMORY; 1825 } 1826 } 1827 1828 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) { 1829 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n")); 1830 return NT_STATUS_NO_MEMORY; 1831 } 1832 1833 1834 if(!prs_append_prs_data( rpc_out, pauth_info)) { 1835 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n")); 1836 return NT_STATUS_NO_MEMORY; 1837 } 1118 auth_len -= DCERPC_AUTH_TRAILER_LENGTH; 1119 } 1120 1121 ctx_list.context_id = 0; 1122 ctx_list.num_transfer_syntaxes = 1; 1123 ctx_list.abstract_syntax = *abstract; 1124 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer); 1125 1126 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; 1127 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN; 1128 u.bind.assoc_group_id = 0x0; 1129 u.bind.num_contexts = 1; 1130 u.bind.ctx_list = &ctx_list; 1131 u.bind.auth_info = *auth_info; 1132 1133 status = dcerpc_push_ncacn_packet(mem_ctx, 1134 ptype, 1135 DCERPC_PFC_FLAG_FIRST | 1136 DCERPC_PFC_FLAG_LAST, 1137 auth_len, 1138 rpc_call_id, 1139 &u, 1140 blob); 1141 if (!NT_STATUS_IS_OK(status)) { 1142 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n")); 1143 return status; 1838 1144 } 1839 1145 … … 1845 1151 ********************************************************************/ 1846 1152 1847 static NTSTATUS create_rpc_bind_req( struct rpc_pipe_client *cli,1848 prs_struct *rpc_out,1849 uint32 rpc_call_id,1850 const struct ndr_syntax_id *abstract,1851 const struct ndr_syntax_id *transfer,1852 enum pipe_auth_type auth_type,1853 enum dcerpc_AuthLevel auth_level)1854 { 1855 RPC_HDR_AUTH hdr_auth;1856 prs_struct auth_info;1153 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx, 1154 struct rpc_pipe_client *cli, 1155 struct pipe_auth_data *auth, 1156 uint32 rpc_call_id, 1157 const struct ndr_syntax_id *abstract, 1158 const struct ndr_syntax_id *transfer, 1159 DATA_BLOB *rpc_out) 1160 { 1161 DATA_BLOB auth_token = data_blob_null; 1162 DATA_BLOB auth_info = data_blob_null; 1857 1163 NTSTATUS ret = NT_STATUS_OK; 1858 1164 1859 ZERO_STRUCT(hdr_auth); 1860 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL)) 1861 return NT_STATUS_NO_MEMORY; 1862 1863 switch (auth_type) { 1864 case PIPE_AUTH_TYPE_SCHANNEL: 1865 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); 1866 if (!NT_STATUS_IS_OK(ret)) { 1867 prs_mem_free(&auth_info); 1868 return ret; 1869 } 1870 break; 1871 1872 case PIPE_AUTH_TYPE_NTLMSSP: 1873 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); 1874 if (!NT_STATUS_IS_OK(ret)) { 1875 prs_mem_free(&auth_info); 1876 return ret; 1877 } 1878 break; 1879 1880 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: 1881 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); 1882 if (!NT_STATUS_IS_OK(ret)) { 1883 prs_mem_free(&auth_info); 1884 return ret; 1885 } 1886 break; 1887 1888 case PIPE_AUTH_TYPE_KRB5: 1889 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info); 1890 if (!NT_STATUS_IS_OK(ret)) { 1891 prs_mem_free(&auth_info); 1892 return ret; 1893 } 1894 break; 1895 1896 case PIPE_AUTH_TYPE_NONE: 1897 break; 1898 1899 default: 1900 /* "Can't" happen. */ 1901 return NT_STATUS_INVALID_INFO_CLASS; 1902 } 1903 1904 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND, 1905 rpc_out, 1906 rpc_call_id, 1907 abstract, 1908 transfer, 1909 &hdr_auth, 1165 switch (auth->auth_type) { 1166 case DCERPC_AUTH_TYPE_SCHANNEL: 1167 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token); 1168 if (!NT_STATUS_IS_OK(ret)) { 1169 return ret; 1170 } 1171 break; 1172 1173 case DCERPC_AUTH_TYPE_NTLMSSP: 1174 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token); 1175 if (!NT_STATUS_IS_OK(ret)) { 1176 return ret; 1177 } 1178 break; 1179 1180 case DCERPC_AUTH_TYPE_SPNEGO: 1181 ret = create_spnego_auth_bind_req(cli, auth, &auth_token); 1182 if (!NT_STATUS_IS_OK(ret)) { 1183 return ret; 1184 } 1185 break; 1186 1187 case DCERPC_AUTH_TYPE_KRB5: 1188 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token); 1189 if (!NT_STATUS_IS_OK(ret)) { 1190 return ret; 1191 } 1192 break; 1193 1194 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: 1195 auth_token = data_blob_talloc(mem_ctx, 1196 "NCALRPC_AUTH_TOKEN", 1197 18); 1198 break; 1199 1200 case DCERPC_AUTH_TYPE_NONE: 1201 break; 1202 1203 default: 1204 /* "Can't" happen. */ 1205 return NT_STATUS_INVALID_INFO_CLASS; 1206 } 1207 1208 if (auth_token.length != 0) { 1209 ret = dcerpc_push_dcerpc_auth(cli, 1210 auth->auth_type, 1211 auth->auth_level, 1212 0, /* auth_pad_length */ 1213 1, /* auth_context_id */ 1214 &auth_token, 1910 1215 &auth_info); 1911 1912 prs_mem_free(&auth_info); 1216 if (!NT_STATUS_IS_OK(ret)) { 1217 return ret; 1218 } 1219 data_blob_free(&auth_token); 1220 } 1221 1222 ret = create_bind_or_alt_ctx_internal(mem_ctx, 1223 DCERPC_PKT_BIND, 1224 rpc_call_id, 1225 abstract, 1226 transfer, 1227 &auth_info, 1228 rpc_out); 1913 1229 return ret; 1914 }1915 1916 /*******************************************************************1917 Create and add the NTLMSSP sign/seal auth header and data.1918 ********************************************************************/1919 1920 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,1921 RPC_HDR *phdr,1922 uint32 ss_padding_len,1923 prs_struct *outgoing_pdu)1924 {1925 RPC_HDR_AUTH auth_info;1926 NTSTATUS status;1927 DATA_BLOB auth_blob = data_blob_null;1928 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;1929 1930 if (!cli->auth->a_u.ntlmssp_state) {1931 return NT_STATUS_INVALID_PARAMETER;1932 }1933 1934 /* Init and marshall the auth header. */1935 init_rpc_hdr_auth(&auth_info,1936 map_pipe_auth_type_to_rpc_auth_type(1937 cli->auth->auth_type),1938 cli->auth->auth_level,1939 ss_padding_len,1940 1 /* context id. */);1941 1942 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {1943 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));1944 data_blob_free(&auth_blob);1945 return NT_STATUS_NO_MEMORY;1946 }1947 1948 switch (cli->auth->auth_level) {1949 case DCERPC_AUTH_LEVEL_PRIVACY:1950 /* Data portion is encrypted. */1951 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,1952 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,1953 data_and_pad_len,1954 (unsigned char *)prs_data_p(outgoing_pdu),1955 (size_t)prs_offset(outgoing_pdu),1956 &auth_blob);1957 if (!NT_STATUS_IS_OK(status)) {1958 data_blob_free(&auth_blob);1959 return status;1960 }1961 break;1962 1963 case DCERPC_AUTH_LEVEL_INTEGRITY:1964 /* Data is signed. */1965 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,1966 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,1967 data_and_pad_len,1968 (unsigned char *)prs_data_p(outgoing_pdu),1969 (size_t)prs_offset(outgoing_pdu),1970 &auth_blob);1971 if (!NT_STATUS_IS_OK(status)) {1972 data_blob_free(&auth_blob);1973 return status;1974 }1975 break;1976 1977 default:1978 /* Can't happen. */1979 smb_panic("bad auth level");1980 /* Notreached. */1981 return NT_STATUS_INVALID_PARAMETER;1982 }1983 1984 /* Finally marshall the blob. */1985 1986 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {1987 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",1988 (unsigned int)NTLMSSP_SIG_SIZE));1989 data_blob_free(&auth_blob);1990 return NT_STATUS_NO_MEMORY;1991 }1992 1993 data_blob_free(&auth_blob);1994 return NT_STATUS_OK;1995 }1996 1997 /*******************************************************************1998 Create and add the schannel sign/seal auth header and data.1999 ********************************************************************/2000 2001 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,2002 RPC_HDR *phdr,2003 uint32 ss_padding_len,2004 prs_struct *outgoing_pdu)2005 {2006 RPC_HDR_AUTH auth_info;2007 struct schannel_state *sas = cli->auth->a_u.schannel_auth;2008 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;2009 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;2010 DATA_BLOB blob;2011 NTSTATUS status;2012 2013 if (!sas) {2014 return NT_STATUS_INVALID_PARAMETER;2015 }2016 2017 /* Init and marshall the auth header. */2018 init_rpc_hdr_auth(&auth_info,2019 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),2020 cli->auth->auth_level,2021 ss_padding_len,2022 1 /* context id. */);2023 2024 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {2025 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));2026 return NT_STATUS_NO_MEMORY;2027 }2028 2029 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",2030 sas->seq_num));2031 2032 switch (cli->auth->auth_level) {2033 case DCERPC_AUTH_LEVEL_PRIVACY:2034 status = netsec_outgoing_packet(sas,2035 talloc_tos(),2036 true,2037 (uint8_t *)data_p,2038 data_and_pad_len,2039 &blob);2040 break;2041 case DCERPC_AUTH_LEVEL_INTEGRITY:2042 status = netsec_outgoing_packet(sas,2043 talloc_tos(),2044 false,2045 (uint8_t *)data_p,2046 data_and_pad_len,2047 &blob);2048 break;2049 default:2050 status = NT_STATUS_INTERNAL_ERROR;2051 break;2052 }2053 2054 if (!NT_STATUS_IS_OK(status)) {2055 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",2056 nt_errstr(status)));2057 return status;2058 }2059 2060 if (DEBUGLEVEL >= 10) {2061 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);2062 }2063 2064 /* Finally marshall the blob. */2065 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {2066 return NT_STATUS_NO_MEMORY;2067 }2068 2069 return NT_STATUS_OK;2070 }2071 2072 /*******************************************************************2073 Calculate how much data we're going to send in this packet, also2074 work out any sign/seal padding length.2075 ********************************************************************/2076 2077 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,2078 uint32 data_left,2079 uint16 *p_frag_len,2080 uint16 *p_auth_len,2081 uint32 *p_ss_padding)2082 {2083 uint32 data_space, data_len;2084 2085 #if 02086 if ((data_left > 0) && (sys_random() % 2)) {2087 data_left = MAX(data_left/2, 1);2088 }2089 #endif2090 2091 switch (cli->auth->auth_level) {2092 case DCERPC_AUTH_LEVEL_NONE:2093 case DCERPC_AUTH_LEVEL_CONNECT:2094 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;2095 data_len = MIN(data_space, data_left);2096 *p_ss_padding = 0;2097 *p_auth_len = 0;2098 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;2099 return data_len;2100 2101 case DCERPC_AUTH_LEVEL_INTEGRITY:2102 case DCERPC_AUTH_LEVEL_PRIVACY:2103 /* Treat the same for all authenticated rpc requests. */2104 switch(cli->auth->auth_type) {2105 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:2106 case PIPE_AUTH_TYPE_NTLMSSP:2107 *p_auth_len = NTLMSSP_SIG_SIZE;2108 break;2109 case PIPE_AUTH_TYPE_SCHANNEL:2110 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;2111 break;2112 default:2113 smb_panic("bad auth type");2114 break;2115 }2116 2117 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -2118 RPC_HDR_AUTH_LEN - *p_auth_len;2119 2120 data_len = MIN(data_space, data_left);2121 *p_ss_padding = 0;2122 if (data_len % 8) {2123 *p_ss_padding = 8 - (data_len % 8);2124 }2125 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */2126 data_len + *p_ss_padding + /* data plus padding. */2127 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */2128 return data_len;2129 2130 default:2131 smb_panic("bad auth level");2132 /* Notreached. */2133 return 0;2134 }2135 1230 } 2136 1231 … … 2147 1242 uint8_t op_num; 2148 1243 uint32_t call_id; 2149 prs_struct*req_data;1244 DATA_BLOB *req_data; 2150 1245 uint32_t req_data_sent; 2151 prs_struct outgoing_frag;2152 prs_structreply_pdu;1246 DATA_BLOB rpc_out; 1247 DATA_BLOB reply_pdu; 2153 1248 }; 2154 2155 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)2156 {2157 prs_mem_free(&s->outgoing_frag);2158 prs_mem_free(&s->reply_pdu);2159 return 0;2160 }2161 1249 2162 1250 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq); … … 2169 1257 struct rpc_pipe_client *cli, 2170 1258 uint8_t op_num, 2171 prs_struct*req_data)1259 DATA_BLOB *req_data) 2172 1260 { 2173 1261 struct tevent_req *req, *subreq; … … 2187 1275 state->req_data_sent = 0; 2188 1276 state->call_id = get_rpc_call_id(); 2189 2190 if (cli->max_xmit_frag 2191 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) { 1277 state->reply_pdu = data_blob_null; 1278 state->rpc_out = data_blob_null; 1279 1280 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH 1281 + RPC_MAX_SIGN_SIZE) { 2192 1282 /* Server is screwed up ! */ 2193 1283 status = NT_STATUS_INVALID_PARAMETER; … … 2195 1285 } 2196 1286 2197 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);2198 2199 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,2200 state, MARSHALL)) {2201 goto fail;2202 }2203 2204 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);2205 2206 1287 status = prepare_next_frag(state, &is_last_frag); 2207 1288 if (!NT_STATUS_IS_OK(status)) { … … 2211 1292 if (is_last_frag) { 2212 1293 subreq = rpc_api_pipe_send(state, ev, state->cli, 2213 &state-> outgoing_frag,1294 &state->rpc_out, 2214 1295 DCERPC_PKT_RESPONSE); 2215 1296 if (subreq == NULL) { … … 2218 1299 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); 2219 1300 } else { 2220 subreq = rpc_write_send( 2221 state, ev, cli->transport, 2222 (uint8_t *)prs_data_p(&state->outgoing_frag), 2223 prs_offset(&state->outgoing_frag)); 1301 subreq = rpc_write_send(state, ev, cli->transport, 1302 state->rpc_out.data, 1303 state->rpc_out.length); 2224 1304 if (subreq == NULL) { 2225 1305 goto fail; … … 2241 1321 bool *is_last_frag) 2242 1322 { 2243 RPC_HDR hdr; 2244 RPC_HDR_REQ hdr_req; 2245 uint32_t data_sent_thistime; 2246 uint16_t auth_len; 2247 uint16_t frag_len; 1323 size_t data_sent_thistime; 1324 size_t auth_len; 1325 size_t frag_len; 2248 1326 uint8_t flags = 0; 2249 uint32_t ss_padding; 2250 uint32_t data_left; 2251 char pad[8] = { 0, }; 2252 NTSTATUS status; 2253 2254 data_left = prs_offset(state->req_data) - state->req_data_sent; 2255 2256 data_sent_thistime = calculate_data_len_tosend( 2257 state->cli, data_left, &frag_len, &auth_len, &ss_padding); 1327 size_t pad_len; 1328 size_t data_left; 1329 NTSTATUS status; 1330 union dcerpc_payload u; 1331 1332 data_left = state->req_data->length - state->req_data_sent; 1333 1334 status = dcerpc_guess_sizes(state->cli->auth, 1335 DCERPC_REQUEST_LENGTH, data_left, 1336 state->cli->max_xmit_frag, 1337 CLIENT_NDR_PADDING_SIZE, 1338 &data_sent_thistime, 1339 &frag_len, &auth_len, &pad_len); 1340 if (!NT_STATUS_IS_OK(status)) { 1341 return status; 1342 } 2258 1343 2259 1344 if (state->req_data_sent == 0) { … … 2265 1350 } 2266 1351 2267 if (!prs_set_offset(&state->outgoing_frag, 0)) { 1352 data_blob_free(&state->rpc_out); 1353 1354 ZERO_STRUCT(u.request); 1355 1356 u.request.alloc_hint = state->req_data->length; 1357 u.request.context_id = 0; 1358 u.request.opnum = state->op_num; 1359 1360 status = dcerpc_push_ncacn_packet(state, 1361 DCERPC_PKT_REQUEST, 1362 flags, 1363 auth_len, 1364 state->call_id, 1365 &u, 1366 &state->rpc_out); 1367 if (!NT_STATUS_IS_OK(status)) { 1368 return status; 1369 } 1370 1371 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't 1372 * compute it right for requests because the auth trailer is missing 1373 * at this stage */ 1374 dcerpc_set_frag_length(&state->rpc_out, frag_len); 1375 1376 /* Copy in the data. */ 1377 if (!data_blob_append(NULL, &state->rpc_out, 1378 state->req_data->data + state->req_data_sent, 1379 data_sent_thistime)) { 2268 1380 return NT_STATUS_NO_MEMORY; 2269 1381 } 2270 1382 2271 /* Create and marshall the header and request header. */ 2272 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len, 2273 auth_len); 2274 2275 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) { 2276 return NT_STATUS_NO_MEMORY; 2277 } 2278 2279 /* Create the rpc request RPC_HDR_REQ */ 2280 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data), 2281 state->op_num); 2282 2283 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req, 2284 &state->outgoing_frag, 0)) { 2285 return NT_STATUS_NO_MEMORY; 2286 } 2287 2288 /* Copy in the data, plus any ss padding. */ 2289 if (!prs_append_some_prs_data(&state->outgoing_frag, 2290 state->req_data, state->req_data_sent, 2291 data_sent_thistime)) { 2292 return NT_STATUS_NO_MEMORY; 2293 } 2294 2295 /* Copy the sign/seal padding data. */ 2296 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) { 2297 return NT_STATUS_NO_MEMORY; 2298 } 2299 2300 /* Generate any auth sign/seal and add the auth footer. */ 2301 switch (state->cli->auth->auth_type) { 2302 case PIPE_AUTH_TYPE_NONE: 2303 status = NT_STATUS_OK; 1383 switch (state->cli->auth->auth_level) { 1384 case DCERPC_AUTH_LEVEL_NONE: 1385 case DCERPC_AUTH_LEVEL_CONNECT: 1386 case DCERPC_AUTH_LEVEL_PACKET: 2304 1387 break; 2305 case PIPE_AUTH_TYPE_NTLMSSP: 2306 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: 2307 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding, 2308 &state->outgoing_frag); 2309 break; 2310 case PIPE_AUTH_TYPE_SCHANNEL: 2311 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding, 2312 &state->outgoing_frag); 1388 case DCERPC_AUTH_LEVEL_INTEGRITY: 1389 case DCERPC_AUTH_LEVEL_PRIVACY: 1390 status = dcerpc_add_auth_footer(state->cli->auth, pad_len, 1391 &state->rpc_out); 1392 if (!NT_STATUS_IS_OK(status)) { 1393 return status; 1394 } 2313 1395 break; 2314 1396 default: 2315 status = NT_STATUS_INVALID_PARAMETER; 2316 break; 1397 return NT_STATUS_INVALID_PARAMETER; 2317 1398 } 2318 1399 … … 2347 1428 if (is_last_frag) { 2348 1429 subreq = rpc_api_pipe_send(state, state->ev, state->cli, 2349 &state-> outgoing_frag,1430 &state->rpc_out, 2350 1431 DCERPC_PKT_RESPONSE); 2351 1432 if (tevent_req_nomem(subreq, req)) { … … 2354 1435 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); 2355 1436 } else { 2356 subreq = rpc_write_send( 2357 state, state->ev, 2358 state->cli->transport, 2359 (uint8_t *)prs_data_p(&state->outgoing_frag), 2360 prs_offset(&state->outgoing_frag)); 1437 subreq = rpc_write_send(state, state->ev, 1438 state->cli->transport, 1439 state->rpc_out.data, 1440 state->rpc_out.length); 2361 1441 if (tevent_req_nomem(subreq, req)) { 2362 1442 return; … … 2375 1455 NTSTATUS status; 2376 1456 2377 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);1457 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu); 2378 1458 TALLOC_FREE(subreq); 2379 1459 if (!NT_STATUS_IS_OK(status)) { … … 2385 1465 2386 1466 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 2387 prs_struct*reply_pdu)1467 DATA_BLOB *reply_pdu) 2388 1468 { 2389 1469 struct rpc_api_pipe_req_state *state = tevent_req_data( … … 2396 1476 * none. The rpccli_* caller routines expect this. 2397 1477 */ 2398 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);1478 *reply_pdu = data_blob_null; 2399 1479 return status; 2400 1480 } 2401 1481 2402 *reply_pdu = state->reply_pdu; 2403 reply_pdu->mem_ctx = mem_ctx; 2404 2405 /* 2406 * Prevent state->req_pdu from being freed in 2407 * rpc_api_pipe_req_state_destructor() 2408 */ 2409 prs_init_empty(&state->reply_pdu, state, UNMARSHALL); 1482 /* return data to caller and assign it ownership of memory */ 1483 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data); 1484 reply_pdu->length = state->reply_pdu.length; 1485 state->reply_pdu.length = 0; 2410 1486 2411 1487 return NT_STATUS_OK; 2412 1488 } 2413 2414 #if 02415 /****************************************************************************2416 Set the handle state.2417 ****************************************************************************/2418 2419 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,2420 const char *pipe_name, uint16 device_state)2421 {2422 bool state_set = False;2423 char param[2];2424 uint16 setup[2]; /* only need 2 uint16 setup parameters */2425 char *rparam = NULL;2426 char *rdata = NULL;2427 uint32 rparam_len, rdata_len;2428 2429 if (pipe_name == NULL)2430 return False;2431 2432 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",2433 cli->fnum, pipe_name, device_state));2434 2435 /* create parameters: device state */2436 SSVAL(param, 0, device_state);2437 2438 /* create setup parameters. */2439 setup[0] = 0x0001;2440 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */2441 2442 /* send the data on \PIPE\ */2443 if (cli_api_pipe(cli->cli, "\\PIPE\\",2444 setup, 2, 0, /* setup, length, max */2445 param, 2, 0, /* param, length, max */2446 NULL, 0, 1024, /* data, length, max */2447 &rparam, &rparam_len, /* return param, length */2448 &rdata, &rdata_len)) /* return data, length */2449 {2450 DEBUG(5, ("Set Handle state: return OK\n"));2451 state_set = True;2452 }2453 2454 SAFE_FREE(rparam);2455 SAFE_FREE(rdata);2456 2457 return state_set;2458 }2459 #endif2460 1489 2461 1490 /**************************************************************************** … … 2463 1492 ****************************************************************************/ 2464 1493 2465 static bool check_bind_response( RPC_HDR_BA *hdr_ba,1494 static bool check_bind_response(const struct dcerpc_bind_ack *r, 2466 1495 const struct ndr_syntax_id *transfer) 2467 1496 { 2468 if ( hdr_ba->addr.len == 0) { 1497 struct dcerpc_ack_ctx ctx; 1498 1499 if (r->secondary_address_size == 0) { 2469 1500 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); 2470 1501 } 2471 1502 1503 if (r->num_results < 1 || !r->ctx_list) { 1504 return false; 1505 } 1506 1507 ctx = r->ctx_list[0]; 1508 2472 1509 /* check the transfer syntax */ 2473 if (( hdr_ba->transfer.if_version != transfer->if_version) ||2474 (memcmp(& hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {1510 if ((ctx.syntax.if_version != transfer->if_version) || 1511 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) { 2475 1512 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n")); 2476 1513 return False; 2477 1514 } 2478 1515 2479 if ( hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {1516 if (r->num_results != 0x1 || ctx.result != 0) { 2480 1517 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", 2481 hdr_ba->res.num_results, hdr_ba->res.reason));1518 r->num_results, ctx.reason)); 2482 1519 } 2483 1520 … … 2493 1530 ********************************************************************/ 2494 1531 2495 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli, 1532 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx, 1533 struct rpc_pipe_client *cli, 2496 1534 uint32 rpc_call_id, 2497 enum pipe_auth_type auth_type,1535 enum dcerpc_AuthType auth_type, 2498 1536 enum dcerpc_AuthLevel auth_level, 2499 1537 DATA_BLOB *pauth_blob, 2500 prs_struct *rpc_out) 2501 { 2502 RPC_HDR hdr; 2503 RPC_HDR_AUTH hdr_auth; 2504 uint32 pad = 0; 2505 2506 /* Create the request RPC_HDR */ 2507 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, 2508 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length, 2509 pauth_blob->length ); 2510 2511 /* Marshall it. */ 2512 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) { 2513 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n")); 2514 return NT_STATUS_NO_MEMORY; 2515 } 2516 2517 /* 2518 I'm puzzled about this - seems to violate the DCE RPC auth rules, 2519 about padding - shouldn't this pad to length 8 ? JRA. 2520 */ 2521 2522 /* 4 bytes padding. */ 2523 if (!prs_uint32("pad", rpc_out, 0, &pad)) { 2524 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n")); 2525 return NT_STATUS_NO_MEMORY; 2526 } 2527 2528 /* Create the request RPC_HDR_AUTHA */ 2529 init_rpc_hdr_auth(&hdr_auth, 2530 map_pipe_auth_type_to_rpc_auth_type(auth_type), 2531 auth_level, 0, 1); 2532 2533 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) { 2534 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n")); 2535 return NT_STATUS_NO_MEMORY; 2536 } 2537 2538 /* 2539 * Append the auth data to the outgoing buffer. 2540 */ 2541 2542 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) { 2543 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n")); 2544 return NT_STATUS_NO_MEMORY; 1538 DATA_BLOB *rpc_out) 1539 { 1540 NTSTATUS status; 1541 union dcerpc_payload u; 1542 1543 u.auth3._pad = 0; 1544 1545 status = dcerpc_push_dcerpc_auth(mem_ctx, 1546 auth_type, 1547 auth_level, 1548 0, /* auth_pad_length */ 1549 1, /* auth_context_id */ 1550 pauth_blob, 1551 &u.auth3.auth_info); 1552 if (!NT_STATUS_IS_OK(status)) { 1553 return status; 1554 } 1555 1556 status = dcerpc_push_ncacn_packet(mem_ctx, 1557 DCERPC_PKT_AUTH3, 1558 DCERPC_PFC_FLAG_FIRST | 1559 DCERPC_PFC_FLAG_LAST, 1560 pauth_blob->length, 1561 rpc_call_id, 1562 &u, 1563 rpc_out); 1564 data_blob_free(&u.auth3.auth_info); 1565 if (!NT_STATUS_IS_OK(status)) { 1566 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n")); 1567 return status; 2545 1568 } 2546 1569 … … 2553 1576 ********************************************************************/ 2554 1577 2555 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, 1578 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx, 1579 enum dcerpc_AuthType auth_type, 1580 enum dcerpc_AuthLevel auth_level, 1581 uint32 rpc_call_id, 2556 1582 const struct ndr_syntax_id *abstract, 2557 1583 const struct ndr_syntax_id *transfer, 2558 enum dcerpc_AuthLevel auth_level,2559 1584 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ 2560 prs_struct *rpc_out) 2561 { 2562 RPC_HDR_AUTH hdr_auth; 2563 prs_struct auth_info; 2564 NTSTATUS ret = NT_STATUS_OK; 2565 2566 ZERO_STRUCT(hdr_auth); 2567 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL)) 2568 return NT_STATUS_NO_MEMORY; 2569 2570 /* We may change the pad length before marshalling. */ 2571 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1); 2572 2573 if (pauth_blob->length) { 2574 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) { 2575 prs_mem_free(&auth_info); 2576 return NT_STATUS_NO_MEMORY; 2577 } 2578 } 2579 2580 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER, 2581 rpc_out, 2582 rpc_call_id, 2583 abstract, 2584 transfer, 2585 &hdr_auth, 2586 &auth_info); 2587 prs_mem_free(&auth_info); 2588 return ret; 1585 DATA_BLOB *rpc_out) 1586 { 1587 DATA_BLOB auth_info; 1588 NTSTATUS status; 1589 1590 status = dcerpc_push_dcerpc_auth(mem_ctx, 1591 auth_type, 1592 auth_level, 1593 0, /* auth_pad_length */ 1594 1, /* auth_context_id */ 1595 pauth_blob, 1596 &auth_info); 1597 if (!NT_STATUS_IS_OK(status)) { 1598 return status; 1599 } 1600 1601 status = create_bind_or_alt_ctx_internal(mem_ctx, 1602 DCERPC_PKT_ALTER, 1603 rpc_call_id, 1604 abstract, 1605 transfer, 1606 &auth_info, 1607 rpc_out); 1608 data_blob_free(&auth_info); 1609 return status; 2589 1610 } 2590 1611 … … 2596 1617 struct event_context *ev; 2597 1618 struct rpc_pipe_client *cli; 2598 prs_struct rpc_out; 1619 DATA_BLOB rpc_out; 1620 bool auth3; 2599 1621 uint32_t rpc_call_id; 2600 1622 }; 2601 1623 2602 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)2603 {2604 prs_mem_free(&state->rpc_out);2605 return 0;2606 }2607 2608 1624 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); 2609 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, 2610 struct rpc_pipe_bind_state *state, 2611 struct rpc_hdr_info *phdr, 2612 prs_struct *reply_pdu); 2613 static void rpc_bind_auth3_write_done(struct tevent_req *subreq); 2614 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, 2615 struct rpc_pipe_bind_state *state, 2616 struct rpc_hdr_info *phdr, 2617 prs_struct *reply_pdu); 2618 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); 1625 static NTSTATUS rpc_bind_next_send(struct tevent_req *req, 1626 struct rpc_pipe_bind_state *state, 1627 DATA_BLOB *credentials); 1628 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, 1629 struct rpc_pipe_bind_state *state, 1630 DATA_BLOB *credentials); 2619 1631 2620 1632 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, 2621 1633 struct event_context *ev, 2622 1634 struct rpc_pipe_client *cli, 2623 struct cli_pipe_auth_data *auth)1635 struct pipe_auth_data *auth) 2624 1636 { 2625 1637 struct tevent_req *req, *subreq; … … 2641 1653 state->rpc_call_id = get_rpc_call_id(); 2642 1654 2643 prs_init_empty(&state->rpc_out, state, MARSHALL);2644 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);2645 2646 1655 cli->auth = talloc_move(cli, &auth); 2647 1656 2648 1657 /* Marshall the outgoing data. */ 2649 status = create_rpc_bind_req(cli, &state->rpc_out, 1658 status = create_rpc_bind_req(state, cli, 1659 cli->auth, 2650 1660 state->rpc_call_id, 2651 1661 &cli->abstract_syntax, 2652 1662 &cli->transfer_syntax, 2653 cli->auth->auth_type, 2654 cli->auth->auth_level); 1663 &state->rpc_out); 2655 1664 2656 1665 if (!NT_STATUS_IS_OK(status)) { … … 2680 1689 struct rpc_pipe_bind_state *state = tevent_req_data( 2681 1690 req, struct rpc_pipe_bind_state); 2682 prs_struct reply_pdu; 2683 struct rpc_hdr_info hdr; 2684 struct rpc_hdr_ba_info hdr_ba; 2685 NTSTATUS status; 2686 2687 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); 1691 struct pipe_auth_data *pauth = state->cli->auth; 1692 struct auth_ntlmssp_state *ntlmssp_ctx; 1693 struct spnego_context *spnego_ctx; 1694 struct gse_context *gse_ctx; 1695 struct ncacn_packet *pkt = NULL; 1696 struct dcerpc_auth auth; 1697 DATA_BLOB auth_token = data_blob_null; 1698 NTSTATUS status; 1699 1700 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL); 2688 1701 TALLOC_FREE(subreq); 2689 1702 if (!NT_STATUS_IS_OK(status)) { … … 2695 1708 } 2696 1709 2697 /* Unmarshall the RPC header */ 2698 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) { 2699 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); 2700 prs_mem_free(&reply_pdu); 1710 if (state->auth3) { 1711 tevent_req_done(req); 1712 return; 1713 } 1714 1715 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) { 1716 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); 2701 1717 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2702 1718 return; 2703 1719 } 2704 1720 2705 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) { 2706 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall " 2707 "RPC_HDR_BA.\n")); 2708 prs_mem_free(&reply_pdu); 2709 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2710 return; 2711 } 2712 2713 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) { 2714 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); 2715 prs_mem_free(&reply_pdu); 2716 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2717 return; 2718 } 2719 2720 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize; 2721 state->cli->max_recv_frag = hdr_ba.bba.max_rsize; 1721 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; 1722 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag; 1723 1724 switch(pauth->auth_type) { 1725 1726 case DCERPC_AUTH_TYPE_NONE: 1727 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: 1728 case DCERPC_AUTH_TYPE_SCHANNEL: 1729 /* Bind complete. */ 1730 tevent_req_done(req); 1731 return; 1732 1733 case DCERPC_AUTH_TYPE_NTLMSSP: 1734 case DCERPC_AUTH_TYPE_SPNEGO: 1735 case DCERPC_AUTH_TYPE_KRB5: 1736 /* Paranoid lenght checks */ 1737 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH 1738 + pkt->auth_length) { 1739 tevent_req_nterror(req, 1740 NT_STATUS_INFO_LENGTH_MISMATCH); 1741 return; 1742 } 1743 /* get auth credentials */ 1744 status = dcerpc_pull_dcerpc_auth(talloc_tos(), 1745 &pkt->u.bind_ack.auth_info, 1746 &auth, false); 1747 if (!NT_STATUS_IS_OK(status)) { 1748 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n", 1749 nt_errstr(status))); 1750 tevent_req_nterror(req, status); 1751 return; 1752 } 1753 break; 1754 1755 default: 1756 goto err_out; 1757 } 2722 1758 2723 1759 /* … … 2725 1761 */ 2726 1762 2727 switch(state->cli->auth->auth_type) { 2728 2729 case PIPE_AUTH_TYPE_NONE: 2730 case PIPE_AUTH_TYPE_SCHANNEL: 1763 switch(pauth->auth_type) { 1764 1765 case DCERPC_AUTH_TYPE_NONE: 1766 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: 1767 case DCERPC_AUTH_TYPE_SCHANNEL: 2731 1768 /* Bind complete. */ 2732 prs_mem_free(&reply_pdu);2733 1769 tevent_req_done(req); 2734 break; 2735 2736 case PIPE_AUTH_TYPE_NTLMSSP: 2737 /* Need to send AUTH3 packet - no reply. */ 2738 status = rpc_finish_auth3_bind_send(req, state, &hdr, 2739 &reply_pdu); 2740 prs_mem_free(&reply_pdu); 2741 if (!NT_STATUS_IS_OK(status)) { 2742 tevent_req_nterror(req, status); 1770 return; 1771 1772 case DCERPC_AUTH_TYPE_NTLMSSP: 1773 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx, 1774 struct auth_ntlmssp_state); 1775 status = auth_ntlmssp_update(ntlmssp_ctx, 1776 auth.credentials, &auth_token); 1777 if (NT_STATUS_EQUAL(status, 1778 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1779 status = rpc_bind_next_send(req, state, 1780 &auth_token); 1781 } else if (NT_STATUS_IS_OK(status)) { 1782 status = rpc_bind_finish_send(req, state, 1783 &auth_token); 2743 1784 } 2744 1785 break; 2745 1786 2746 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: 2747 /* Need to send alter context request and reply. */ 2748 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr, 2749 &reply_pdu); 2750 prs_mem_free(&reply_pdu); 1787 case DCERPC_AUTH_TYPE_SPNEGO: 1788 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx, 1789 struct spnego_context); 1790 status = spnego_get_client_auth_token(state, 1791 spnego_ctx, 1792 &auth.credentials, 1793 &auth_token); 2751 1794 if (!NT_STATUS_IS_OK(status)) { 2752 tevent_req_nterror(req, status); 1795 break; 1796 } 1797 if (auth_token.length == 0) { 1798 /* Bind complete. */ 1799 tevent_req_done(req); 1800 return; 1801 } 1802 if (spnego_require_more_processing(spnego_ctx)) { 1803 status = rpc_bind_next_send(req, state, 1804 &auth_token); 1805 } else { 1806 status = rpc_bind_finish_send(req, state, 1807 &auth_token); 2753 1808 } 2754 1809 break; 2755 1810 2756 case PIPE_AUTH_TYPE_KRB5: 2757 /* */ 1811 case DCERPC_AUTH_TYPE_KRB5: 1812 gse_ctx = talloc_get_type_abort(pauth->auth_ctx, 1813 struct gse_context); 1814 status = gse_get_client_auth_token(state, 1815 gse_ctx, 1816 &auth.credentials, 1817 &auth_token); 1818 if (!NT_STATUS_IS_OK(status)) { 1819 break; 1820 } 1821 1822 if (gse_require_more_processing(gse_ctx)) { 1823 status = rpc_bind_next_send(req, state, &auth_token); 1824 } else { 1825 status = rpc_bind_finish_send(req, state, &auth_token); 1826 } 1827 break; 2758 1828 2759 1829 default: 2760 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", 2761 (unsigned int)state->cli->auth->auth_type)); 2762 prs_mem_free(&reply_pdu); 2763 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 2764 } 2765 } 2766 2767 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, 2768 struct rpc_pipe_bind_state *state, 2769 struct rpc_hdr_info *phdr, 2770 prs_struct *reply_pdu) 2771 { 2772 DATA_BLOB server_response = data_blob_null; 2773 DATA_BLOB client_reply = data_blob_null; 2774 struct rpc_hdr_auth_info hdr_auth; 1830 goto err_out; 1831 } 1832 1833 if (!NT_STATUS_IS_OK(status)) { 1834 tevent_req_nterror(req, status); 1835 } 1836 return; 1837 1838 err_out: 1839 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", 1840 (unsigned int)state->cli->auth->auth_type)); 1841 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 1842 } 1843 1844 static NTSTATUS rpc_bind_next_send(struct tevent_req *req, 1845 struct rpc_pipe_bind_state *state, 1846 DATA_BLOB *auth_token) 1847 { 1848 struct pipe_auth_data *auth = state->cli->auth; 2775 1849 struct tevent_req *subreq; 2776 1850 NTSTATUS status; 2777 1851 2778 if ((phdr->auth_len == 0)2779 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {2780 return NT_STATUS_INVALID_PARAMETER;2781 }2782 2783 if (!prs_set_offset(2784 reply_pdu,2785 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {2786 return NT_STATUS_INVALID_PARAMETER;2787 }2788 2789 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {2790 return NT_STATUS_INVALID_PARAMETER;2791 }2792 2793 /* TODO - check auth_type/auth_level match. */2794 2795 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);2796 prs_copy_data_out((char *)server_response.data, reply_pdu,2797 phdr->auth_len);2798 2799 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,2800 server_response, &client_reply);2801 2802 if (!NT_STATUS_IS_OK(status)) {2803 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "2804 "blob failed: %s.\n", nt_errstr(status)));2805 return status;2806 }2807 2808 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);2809 2810 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,2811 state->cli->auth->auth_type,2812 state->cli->auth->auth_level,2813 &client_reply, &state->rpc_out);2814 data_blob_free(&client_reply);2815 2816 if (!NT_STATUS_IS_OK(status)) {2817 return status;2818 }2819 2820 subreq = rpc_write_send(state, state->ev, state->cli->transport,2821 (uint8_t *)prs_data_p(&state->rpc_out),2822 prs_offset(&state->rpc_out));2823 if (subreq == NULL) {2824 return NT_STATUS_NO_MEMORY;2825 }2826 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);2827 return NT_STATUS_OK;2828 }2829 2830 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)2831 {2832 struct tevent_req *req = tevent_req_callback_data(2833 subreq, struct tevent_req);2834 NTSTATUS status;2835 2836 status = rpc_write_recv(subreq);2837 TALLOC_FREE(subreq);2838 if (!NT_STATUS_IS_OK(status)) {2839 tevent_req_nterror(req, status);2840 return;2841 }2842 tevent_req_done(req);2843 }2844 2845 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,2846 struct rpc_pipe_bind_state *state,2847 struct rpc_hdr_info *phdr,2848 prs_struct *reply_pdu)2849 {2850 DATA_BLOB server_spnego_response = data_blob_null;2851 DATA_BLOB server_ntlm_response = data_blob_null;2852 DATA_BLOB client_reply = data_blob_null;2853 DATA_BLOB tmp_blob = data_blob_null;2854 RPC_HDR_AUTH hdr_auth;2855 struct tevent_req *subreq;2856 NTSTATUS status;2857 2858 if ((phdr->auth_len == 0)2859 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {2860 return NT_STATUS_INVALID_PARAMETER;2861 }2862 2863 /* Process the returned NTLMSSP blob first. */2864 if (!prs_set_offset(2865 reply_pdu,2866 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {2867 return NT_STATUS_INVALID_PARAMETER;2868 }2869 2870 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {2871 return NT_STATUS_INVALID_PARAMETER;2872 }2873 2874 server_spnego_response = data_blob(NULL, phdr->auth_len);2875 prs_copy_data_out((char *)server_spnego_response.data,2876 reply_pdu, phdr->auth_len);2877 2878 /*2879 * The server might give us back two challenges - tmp_blob is for the2880 * second.2881 */2882 if (!spnego_parse_challenge(server_spnego_response,2883 &server_ntlm_response, &tmp_blob)) {2884 data_blob_free(&server_spnego_response);2885 data_blob_free(&server_ntlm_response);2886 data_blob_free(&tmp_blob);2887 return NT_STATUS_INVALID_PARAMETER;2888 }2889 2890 /* We're finished with the server spnego response and the tmp_blob. */2891 data_blob_free(&server_spnego_response);2892 data_blob_free(&tmp_blob);2893 2894 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,2895 server_ntlm_response, &client_reply);2896 2897 /* Finished with the server_ntlm response */2898 data_blob_free(&server_ntlm_response);2899 2900 if (!NT_STATUS_IS_OK(status)) {2901 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "2902 "using server blob failed.\n"));2903 data_blob_free(&client_reply);2904 return status;2905 }2906 2907 /* SPNEGO wrap the client reply. */2908 tmp_blob = spnego_gen_auth(client_reply);2909 data_blob_free(&client_reply);2910 client_reply = tmp_blob;2911 tmp_blob = data_blob_null;2912 2913 1852 /* Now prepare the alter context pdu. */ 2914 prs_init_empty(&state->rpc_out, state, MARSHALL); 2915 2916 status = create_rpc_alter_context(state->rpc_call_id, 1853 data_blob_free(&state->rpc_out); 1854 1855 status = create_rpc_alter_context(state, 1856 auth->auth_type, 1857 auth->auth_level, 1858 state->rpc_call_id, 2917 1859 &state->cli->abstract_syntax, 2918 1860 &state->cli->transfer_syntax, 2919 state->cli->auth->auth_level, 2920 &client_reply, 1861 auth_token, 2921 1862 &state->rpc_out); 2922 data_blob_free(&client_reply);2923 2924 1863 if (!NT_STATUS_IS_OK(status)) { 2925 1864 return status; … … 2931 1870 return NT_STATUS_NO_MEMORY; 2932 1871 } 2933 tevent_req_set_callback(subreq, rpc_ bind_ntlmssp_api_done, req);1872 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); 2934 1873 return NT_STATUS_OK; 2935 1874 } 2936 1875 2937 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) 2938 { 2939 struct tevent_req *req = tevent_req_callback_data( 2940 subreq, struct tevent_req); 2941 struct rpc_pipe_bind_state *state = tevent_req_data( 2942 req, struct rpc_pipe_bind_state); 2943 DATA_BLOB server_spnego_response = data_blob_null; 2944 DATA_BLOB tmp_blob = data_blob_null; 2945 prs_struct reply_pdu; 2946 struct rpc_hdr_info hdr; 2947 struct rpc_hdr_auth_info hdr_auth; 2948 NTSTATUS status; 2949 2950 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); 2951 TALLOC_FREE(subreq); 2952 if (!NT_STATUS_IS_OK(status)) { 2953 tevent_req_nterror(req, status); 2954 return; 2955 } 2956 2957 /* Get the auth blob from the reply. */ 2958 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) { 2959 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to " 2960 "unmarshall RPC_HDR.\n")); 2961 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); 2962 return; 2963 } 2964 2965 if (!prs_set_offset( 2966 &reply_pdu, 2967 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) { 2968 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2969 return; 2970 } 2971 2972 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) { 2973 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2974 return; 2975 } 2976 2977 server_spnego_response = data_blob(NULL, hdr.auth_len); 2978 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu, 2979 hdr.auth_len); 2980 2981 /* Check we got a valid auth response. */ 2982 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, 2983 OID_NTLMSSP, &tmp_blob)) { 2984 data_blob_free(&server_spnego_response); 2985 data_blob_free(&tmp_blob); 2986 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2987 return; 2988 } 2989 2990 data_blob_free(&server_spnego_response); 2991 data_blob_free(&tmp_blob); 2992 2993 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " 2994 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli))); 2995 tevent_req_done(req); 1876 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, 1877 struct rpc_pipe_bind_state *state, 1878 DATA_BLOB *auth_token) 1879 { 1880 struct pipe_auth_data *auth = state->cli->auth; 1881 struct tevent_req *subreq; 1882 NTSTATUS status; 1883 1884 state->auth3 = true; 1885 1886 /* Now prepare the auth3 context pdu. */ 1887 data_blob_free(&state->rpc_out); 1888 1889 status = create_rpc_bind_auth3(state, state->cli, 1890 state->rpc_call_id, 1891 auth->auth_type, 1892 auth->auth_level, 1893 auth_token, 1894 &state->rpc_out); 1895 if (!NT_STATUS_IS_OK(status)) { 1896 return status; 1897 } 1898 1899 subreq = rpc_api_pipe_send(state, state->ev, state->cli, 1900 &state->rpc_out, DCERPC_PKT_AUTH3); 1901 if (subreq == NULL) { 1902 return NT_STATUS_NO_MEMORY; 1903 } 1904 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); 1905 return NT_STATUS_OK; 2996 1906 } 2997 1907 … … 3002 1912 3003 1913 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, 3004 struct cli_pipe_auth_data *auth)1914 struct pipe_auth_data *auth) 3005 1915 { 3006 1916 TALLOC_CTX *frame = talloc_stackframe(); … … 3068 1978 } 3069 1979 1980 struct rpccli_bh_state { 1981 struct rpc_pipe_client *rpc_cli; 1982 }; 1983 1984 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h) 1985 { 1986 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, 1987 struct rpccli_bh_state); 1988 1989 return rpccli_is_connected(hs->rpc_cli); 1990 } 1991 1992 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h, 1993 uint32_t timeout) 1994 { 1995 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, 1996 struct rpccli_bh_state); 1997 1998 return rpccli_set_timeout(hs->rpc_cli, timeout); 1999 } 2000 2001 struct rpccli_bh_raw_call_state { 2002 DATA_BLOB in_data; 2003 DATA_BLOB out_data; 2004 uint32_t out_flags; 2005 }; 2006 2007 static void rpccli_bh_raw_call_done(struct tevent_req *subreq); 2008 2009 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx, 2010 struct tevent_context *ev, 2011 struct dcerpc_binding_handle *h, 2012 const struct GUID *object, 2013 uint32_t opnum, 2014 uint32_t in_flags, 2015 const uint8_t *in_data, 2016 size_t in_length) 2017 { 2018 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, 2019 struct rpccli_bh_state); 2020 struct tevent_req *req; 2021 struct rpccli_bh_raw_call_state *state; 2022 bool ok; 2023 struct tevent_req *subreq; 2024 2025 req = tevent_req_create(mem_ctx, &state, 2026 struct rpccli_bh_raw_call_state); 2027 if (req == NULL) { 2028 return NULL; 2029 } 2030 state->in_data.data = discard_const_p(uint8_t, in_data); 2031 state->in_data.length = in_length; 2032 2033 ok = rpccli_bh_is_connected(h); 2034 if (!ok) { 2035 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); 2036 return tevent_req_post(req, ev); 2037 } 2038 2039 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli, 2040 opnum, &state->in_data); 2041 if (tevent_req_nomem(subreq, req)) { 2042 return tevent_req_post(req, ev); 2043 } 2044 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req); 2045 2046 return req; 2047 } 2048 2049 static void rpccli_bh_raw_call_done(struct tevent_req *subreq) 2050 { 2051 struct tevent_req *req = 2052 tevent_req_callback_data(subreq, 2053 struct tevent_req); 2054 struct rpccli_bh_raw_call_state *state = 2055 tevent_req_data(req, 2056 struct rpccli_bh_raw_call_state); 2057 NTSTATUS status; 2058 2059 state->out_flags = 0; 2060 2061 /* TODO: support bigendian responses */ 2062 2063 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data); 2064 TALLOC_FREE(subreq); 2065 if (!NT_STATUS_IS_OK(status)) { 2066 tevent_req_nterror(req, status); 2067 return; 2068 } 2069 2070 tevent_req_done(req); 2071 } 2072 2073 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req, 2074 TALLOC_CTX *mem_ctx, 2075 uint8_t **out_data, 2076 size_t *out_length, 2077 uint32_t *out_flags) 2078 { 2079 struct rpccli_bh_raw_call_state *state = 2080 tevent_req_data(req, 2081 struct rpccli_bh_raw_call_state); 2082 NTSTATUS status; 2083 2084 if (tevent_req_is_nterror(req, &status)) { 2085 tevent_req_received(req); 2086 return status; 2087 } 2088 2089 *out_data = talloc_move(mem_ctx, &state->out_data.data); 2090 *out_length = state->out_data.length; 2091 *out_flags = state->out_flags; 2092 tevent_req_received(req); 2093 return NT_STATUS_OK; 2094 } 2095 2096 struct rpccli_bh_disconnect_state { 2097 uint8_t _dummy; 2098 }; 2099 2100 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx, 2101 struct tevent_context *ev, 2102 struct dcerpc_binding_handle *h) 2103 { 2104 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h, 2105 struct rpccli_bh_state); 2106 struct tevent_req *req; 2107 struct rpccli_bh_disconnect_state *state; 2108 bool ok; 2109 2110 req = tevent_req_create(mem_ctx, &state, 2111 struct rpccli_bh_disconnect_state); 2112 if (req == NULL) { 2113 return NULL; 2114 } 2115 2116 ok = rpccli_bh_is_connected(h); 2117 if (!ok) { 2118 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); 2119 return tevent_req_post(req, ev); 2120 } 2121 2122 /* 2123 * TODO: do a real async disconnect ... 2124 * 2125 * For now the caller needs to free rpc_cli 2126 */ 2127 hs->rpc_cli = NULL; 2128 2129 tevent_req_done(req); 2130 return tevent_req_post(req, ev); 2131 } 2132 2133 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req) 2134 { 2135 NTSTATUS status; 2136 2137 if (tevent_req_is_nterror(req, &status)) { 2138 tevent_req_received(req); 2139 return status; 2140 } 2141 2142 tevent_req_received(req); 2143 return NT_STATUS_OK; 2144 } 2145 2146 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h) 2147 { 2148 return true; 2149 } 2150 2151 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h, 2152 int ndr_flags, 2153 const void *_struct_ptr, 2154 const struct ndr_interface_call *call) 2155 { 2156 void *struct_ptr = discard_const(_struct_ptr); 2157 2158 if (DEBUGLEVEL < 10) { 2159 return; 2160 } 2161 2162 if (ndr_flags & NDR_IN) { 2163 ndr_print_function_debug(call->ndr_print, 2164 call->name, 2165 ndr_flags, 2166 struct_ptr); 2167 } 2168 if (ndr_flags & NDR_OUT) { 2169 ndr_print_function_debug(call->ndr_print, 2170 call->name, 2171 ndr_flags, 2172 struct_ptr); 2173 } 2174 } 2175 2176 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = { 2177 .name = "rpccli", 2178 .is_connected = rpccli_bh_is_connected, 2179 .set_timeout = rpccli_bh_set_timeout, 2180 .raw_call_send = rpccli_bh_raw_call_send, 2181 .raw_call_recv = rpccli_bh_raw_call_recv, 2182 .disconnect_send = rpccli_bh_disconnect_send, 2183 .disconnect_recv = rpccli_bh_disconnect_recv, 2184 2185 .ref_alloc = rpccli_bh_ref_alloc, 2186 .do_ndr_print = rpccli_bh_do_ndr_print, 2187 }; 2188 2189 /* initialise a rpc_pipe_client binding handle */ 2190 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c) 2191 { 2192 struct dcerpc_binding_handle *h; 2193 struct rpccli_bh_state *hs; 2194 2195 h = dcerpc_binding_handle_create(c, 2196 &rpccli_bh_ops, 2197 NULL, 2198 NULL, /* TODO */ 2199 &hs, 2200 struct rpccli_bh_state, 2201 __location__); 2202 if (h == NULL) { 2203 return NULL; 2204 } 2205 hs->rpc_cli = c; 2206 2207 return h; 2208 } 2209 3070 2210 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) 3071 2211 { 2212 struct auth_ntlmssp_state *a = NULL; 3072 2213 struct cli_state *cli; 3073 2214 3074 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) 3075 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) { 3076 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16); 2215 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) { 2216 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx, 2217 struct auth_ntlmssp_state); 2218 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) { 2219 struct spnego_context *spnego_ctx; 2220 enum spnego_mech auth_type; 2221 void *auth_ctx; 2222 NTSTATUS status; 2223 2224 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx, 2225 struct spnego_context); 2226 status = spnego_get_negotiated_mech(spnego_ctx, 2227 &auth_type, &auth_ctx); 2228 if (!NT_STATUS_IS_OK(status)) { 2229 return false; 2230 } 2231 2232 if (auth_type == SPNEGO_NTLMSSP) { 2233 a = talloc_get_type_abort(auth_ctx, 2234 struct auth_ntlmssp_state); 2235 } 2236 } 2237 2238 if (a) { 2239 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16); 3077 2240 return true; 3078 2241 } … … 3086 2249 } 3087 2250 3088 NTSTATUS rpccli_ anon_bind_data(TALLOC_CTX *mem_ctx,3089 struct cli_pipe_auth_data **presult)3090 { 3091 struct cli_pipe_auth_data *result;3092 3093 result = talloc(mem_ctx, struct cli_pipe_auth_data);2251 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx, 2252 struct pipe_auth_data **presult) 2253 { 2254 struct pipe_auth_data *result; 2255 2256 result = talloc(mem_ctx, struct pipe_auth_data); 3094 2257 if (result == NULL) { 3095 2258 return NT_STATUS_NO_MEMORY; 3096 2259 } 3097 2260 3098 result->auth_type = PIPE_AUTH_TYPE_NONE;3099 result->auth_level = DCERPC_AUTH_LEVEL_ NONE;2261 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM; 2262 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT; 3100 2263 3101 2264 result->user_name = talloc_strdup(result, ""); … … 3110 2273 } 3111 2274 3112 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth) 3113 { 3114 ntlmssp_end(&auth->a_u.ntlmssp_state); 2275 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, 2276 struct pipe_auth_data **presult) 2277 { 2278 struct pipe_auth_data *result; 2279 2280 result = talloc(mem_ctx, struct pipe_auth_data); 2281 if (result == NULL) { 2282 return NT_STATUS_NO_MEMORY; 2283 } 2284 2285 result->auth_type = DCERPC_AUTH_TYPE_NONE; 2286 result->auth_level = DCERPC_AUTH_LEVEL_NONE; 2287 2288 result->user_name = talloc_strdup(result, ""); 2289 result->domain = talloc_strdup(result, ""); 2290 if ((result->user_name == NULL) || (result->domain == NULL)) { 2291 TALLOC_FREE(result); 2292 return NT_STATUS_NO_MEMORY; 2293 } 2294 2295 *presult = result; 2296 return NT_STATUS_OK; 2297 } 2298 2299 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth) 2300 { 2301 TALLOC_FREE(auth->auth_ctx); 3115 2302 return 0; 3116 2303 } 3117 2304 3118 2305 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, 3119 enum pipe_auth_type auth_type,2306 enum dcerpc_AuthType auth_type, 3120 2307 enum dcerpc_AuthLevel auth_level, 3121 2308 const char *domain, 3122 2309 const char *username, 3123 2310 const char *password, 3124 struct cli_pipe_auth_data **presult) 3125 { 3126 struct cli_pipe_auth_data *result; 3127 NTSTATUS status; 3128 3129 result = talloc(mem_ctx, struct cli_pipe_auth_data); 2311 struct pipe_auth_data **presult) 2312 { 2313 struct auth_ntlmssp_state *ntlmssp_ctx; 2314 struct pipe_auth_data *result; 2315 NTSTATUS status; 2316 2317 result = talloc(mem_ctx, struct pipe_auth_data); 3130 2318 if (result == NULL) { 3131 2319 return NT_STATUS_NO_MEMORY; … … 3142 2330 } 3143 2331 3144 status = ntlmssp_client_start(&result->a_u.ntlmssp_state); 2332 status = auth_ntlmssp_client_start(NULL, 2333 global_myname(), 2334 lp_workgroup(), 2335 lp_client_ntlmv2_auth(), 2336 &ntlmssp_ctx); 3145 2337 if (!NT_STATUS_IS_OK(status)) { 3146 2338 goto fail; … … 3149 2341 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor); 3150 2342 3151 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);2343 status = auth_ntlmssp_set_username(ntlmssp_ctx, username); 3152 2344 if (!NT_STATUS_IS_OK(status)) { 3153 2345 goto fail; 3154 2346 } 3155 2347 3156 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);2348 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain); 3157 2349 if (!NT_STATUS_IS_OK(status)) { 3158 2350 goto fail; 3159 2351 } 3160 2352 3161 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);2353 status = auth_ntlmssp_set_password(ntlmssp_ctx, password); 3162 2354 if (!NT_STATUS_IS_OK(status)) { 3163 2355 goto fail; … … 3167 2359 * Turn off sign+seal to allow selected auth level to turn it back on. 3168 2360 */ 3169 result->a_u.ntlmssp_state->neg_flags &=3170 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);2361 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN | 2362 NTLMSSP_NEGOTIATE_SEAL)); 3171 2363 3172 2364 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { 3173 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;2365 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN); 3174 2366 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { 3175 result->a_u.ntlmssp_state->neg_flags 3176 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; 3177 } 3178 2367 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL | 2368 NTLMSSP_NEGOTIATE_SIGN); 2369 } 2370 2371 result->auth_ctx = ntlmssp_ctx; 3179 2372 *presult = result; 3180 2373 return NT_STATUS_OK; … … 3188 2381 enum dcerpc_AuthLevel auth_level, 3189 2382 struct netlogon_creds_CredentialState *creds, 3190 struct cli_pipe_auth_data **presult) 3191 { 3192 struct cli_pipe_auth_data *result; 3193 3194 result = talloc(mem_ctx, struct cli_pipe_auth_data); 2383 struct pipe_auth_data **presult) 2384 { 2385 struct schannel_state *schannel_auth; 2386 struct pipe_auth_data *result; 2387 2388 result = talloc(mem_ctx, struct pipe_auth_data); 3195 2389 if (result == NULL) { 3196 2390 return NT_STATUS_NO_MEMORY; 3197 2391 } 3198 2392 3199 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;2393 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL; 3200 2394 result->auth_level = auth_level; 3201 2395 … … 3206 2400 } 3207 2401 3208 result->a_u.schannel_auth = talloc(result, struct schannel_state);3209 if ( result->a_u.schannel_auth == NULL) {2402 schannel_auth = talloc(result, struct schannel_state); 2403 if (schannel_auth == NULL) { 3210 2404 goto fail; 3211 2405 } 3212 2406 3213 result->a_u.schannel_auth->state = SCHANNEL_STATE_START; 3214 result->a_u.schannel_auth->seq_num = 0; 3215 result->a_u.schannel_auth->initiator = true; 3216 result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds); 3217 2407 schannel_auth->state = SCHANNEL_STATE_START; 2408 schannel_auth->seq_num = 0; 2409 schannel_auth->initiator = true; 2410 schannel_auth->creds = netlogon_creds_copy(result, creds); 2411 2412 result->auth_ctx = schannel_auth; 3218 2413 *presult = result; 3219 2414 return NT_STATUS_OK; … … 3222 2417 TALLOC_FREE(result); 3223 2418 return NT_STATUS_NO_MEMORY; 3224 }3225 3226 #ifdef HAVE_KRB53227 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)3228 {3229 data_blob_free(&auth->session_key);3230 return 0;3231 }3232 #endif3233 3234 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,3235 enum dcerpc_AuthLevel auth_level,3236 const char *service_princ,3237 const char *username,3238 const char *password,3239 struct cli_pipe_auth_data **presult)3240 {3241 #ifdef HAVE_KRB53242 struct cli_pipe_auth_data *result;3243 3244 if ((username != NULL) && (password != NULL)) {3245 int ret = kerberos_kinit_password(username, password, 0, NULL);3246 if (ret != 0) {3247 return NT_STATUS_ACCESS_DENIED;3248 }3249 }3250 3251 result = talloc(mem_ctx, struct cli_pipe_auth_data);3252 if (result == NULL) {3253 return NT_STATUS_NO_MEMORY;3254 }3255 3256 result->auth_type = PIPE_AUTH_TYPE_KRB5;3257 result->auth_level = auth_level;3258 3259 /*3260 * Username / domain need fixing!3261 */3262 result->user_name = talloc_strdup(result, "");3263 result->domain = talloc_strdup(result, "");3264 if ((result->user_name == NULL) || (result->domain == NULL)) {3265 goto fail;3266 }3267 3268 result->a_u.kerberos_auth = TALLOC_ZERO_P(3269 result, struct kerberos_auth_struct);3270 if (result->a_u.kerberos_auth == NULL) {3271 goto fail;3272 }3273 talloc_set_destructor(result->a_u.kerberos_auth,3274 cli_auth_kerberos_data_destructor);3275 3276 result->a_u.kerberos_auth->service_principal = talloc_strdup(3277 result, service_princ);3278 if (result->a_u.kerberos_auth->service_principal == NULL) {3279 goto fail;3280 }3281 3282 *presult = result;3283 return NT_STATUS_OK;3284 3285 fail:3286 TALLOC_FREE(result);3287 return NT_STATUS_NO_MEMORY;3288 #else3289 return NT_STATUS_NOT_SUPPORTED;3290 #endif3291 2419 } 3292 2420 … … 3311 2439 result->abstract_syntax = *abstract_syntax; 3312 2440 result->transfer_syntax = ndr_transfer_syntax; 3313 result->dispatch = cli_do_rpc_ndr;3314 result->dispatch_send = cli_do_rpc_ndr_send;3315 result->dispatch_recv = cli_do_rpc_ndr_recv;3316 2441 3317 2442 result->desthost = talloc_strdup(result, host); … … 3344 2469 3345 2470 result->transport->transport = NCACN_IP_TCP; 2471 2472 result->binding_handle = rpccli_bh_create(result); 2473 if (result->binding_handle == NULL) { 2474 TALLOC_FREE(result); 2475 return NT_STATUS_NO_MEMORY; 2476 } 3346 2477 3347 2478 *presult = result; … … 3364 2495 NTSTATUS status; 3365 2496 struct rpc_pipe_client *epm_pipe = NULL; 3366 struct cli_pipe_auth_data *auth = NULL; 2497 struct dcerpc_binding_handle *epm_handle = NULL; 2498 struct pipe_auth_data *auth = NULL; 3367 2499 struct dcerpc_binding *map_binding = NULL; 3368 2500 struct dcerpc_binding *res_binding = NULL; … … 3374 2506 struct epm_twr_p_t towers; 3375 2507 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 2508 uint32_t result = 0; 3376 2509 3377 2510 if (pport == NULL) { 3378 2511 status = NT_STATUS_INVALID_PARAMETER; 3379 2512 goto done; 2513 } 2514 2515 if (ndr_syntax_id_equal(abstract_syntax, 2516 &ndr_table_epmapper.syntax_id)) { 2517 *pport = 135; 2518 return NT_STATUS_OK; 3380 2519 } 3381 2520 … … 3388 2527 goto done; 3389 2528 } 2529 epm_handle = epm_pipe->binding_handle; 3390 2530 3391 2531 status = rpccli_anon_bind_data(tmp_ctx, &auth); … … 3441 2581 /* ask the endpoint mapper for the port */ 3442 2582 3443 status = rpccli_epm_Map(epm_pipe,2583 status = dcerpc_epm_Map(epm_handle, 3444 2584 tmp_ctx, 3445 2585 CONST_DISCARD(struct GUID *, … … 3449 2589 max_towers, 3450 2590 &num_towers, 3451 &towers); 3452 3453 if (!NT_STATUS_IS_OK(status)) { 2591 &towers, 2592 &result); 2593 2594 if (!NT_STATUS_IS_OK(status)) { 2595 goto done; 2596 } 2597 2598 if (result != EPMAPPER_STATUS_OK) { 2599 status = NT_STATUS_UNSUCCESSFUL; 3454 2600 goto done; 3455 2601 } … … 3522 2668 result->abstract_syntax = *abstract_syntax; 3523 2669 result->transfer_syntax = ndr_transfer_syntax; 3524 result->dispatch = cli_do_rpc_ndr;3525 result->dispatch_send = cli_do_rpc_ndr_send;3526 result->dispatch_recv = cli_do_rpc_ndr_recv;3527 2670 3528 2671 result->desthost = get_myname(result); … … 3545 2688 ZERO_STRUCT(addr); 3546 2689 addr.sun_family = AF_UNIX; 3547 str ncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));2690 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); 3548 2691 3549 2692 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) { … … 3561 2704 3562 2705 result->transport->transport = NCALRPC; 2706 2707 result->binding_handle = rpccli_bh_create(result); 2708 if (result->binding_handle == NULL) { 2709 TALLOC_FREE(result); 2710 return NT_STATUS_NO_MEMORY; 2711 } 3563 2712 3564 2713 *presult = result; … … 3615 2764 result->abstract_syntax = *abstract_syntax; 3616 2765 result->transfer_syntax = ndr_transfer_syntax; 3617 result->dispatch = cli_do_rpc_ndr;3618 result->dispatch_send = cli_do_rpc_ndr_send;3619 result->dispatch_recv = cli_do_rpc_ndr_recv;3620 2766 result->desthost = talloc_strdup(result, cli->desthost); 3621 2767 result->srv_name_slash = talloc_asprintf_strupper_m( … … 3650 2796 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor); 3651 2797 3652 *presult = result; 3653 return NT_STATUS_OK; 3654 } 3655 3656 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx, 3657 struct rpc_cli_smbd_conn *conn, 3658 const struct ndr_syntax_id *syntax, 3659 struct rpc_pipe_client **presult) 3660 { 3661 struct rpc_pipe_client *result; 3662 struct cli_pipe_auth_data *auth; 3663 NTSTATUS status; 3664 3665 result = talloc(mem_ctx, struct rpc_pipe_client); 3666 if (result == NULL) { 3667 return NT_STATUS_NO_MEMORY; 3668 } 3669 result->abstract_syntax = *syntax; 3670 result->transfer_syntax = ndr_transfer_syntax; 3671 result->dispatch = cli_do_rpc_ndr; 3672 result->dispatch_send = cli_do_rpc_ndr_send; 3673 result->dispatch_recv = cli_do_rpc_ndr_recv; 3674 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; 3675 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; 3676 3677 result->desthost = talloc_strdup(result, global_myname()); 3678 result->srv_name_slash = talloc_asprintf_strupper_m( 3679 result, "\\\\%s", global_myname()); 3680 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { 2798 result->binding_handle = rpccli_bh_create(result); 2799 if (result->binding_handle == NULL) { 3681 2800 TALLOC_FREE(result); 3682 2801 return NT_STATUS_NO_MEMORY; 3683 2802 } 3684 3685 status = rpc_transport_smbd_init(result, conn, syntax,3686 &result->transport);3687 if (!NT_STATUS_IS_OK(status)) {3688 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",3689 nt_errstr(status)));3690 TALLOC_FREE(result);3691 return status;3692 }3693 3694 status = rpccli_anon_bind_data(result, &auth);3695 if (!NT_STATUS_IS_OK(status)) {3696 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",3697 nt_errstr(status)));3698 TALLOC_FREE(result);3699 return status;3700 }3701 3702 status = rpc_pipe_bind(result, auth);3703 if (!NT_STATUS_IS_OK(status)) {3704 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));3705 TALLOC_FREE(result);3706 return status;3707 }3708 3709 result->transport->transport = NCACN_INTERNAL;3710 2803 3711 2804 *presult = result; … … 3743 2836 { 3744 2837 struct rpc_pipe_client *result; 3745 struct cli_pipe_auth_data *auth;2838 struct pipe_auth_data *auth; 3746 2839 NTSTATUS status; 3747 2840 … … 3820 2913 ****************************************************************************/ 3821 2914 3822 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,3823 const struct ndr_syntax_id *interface,3824 enum dcerpc_transport_t transport,3825 enum pipe_auth_type auth_type,3826 enum dcerpc_AuthLevel auth_level,3827 const char *domain,3828 const char *username,3829 const char *password,3830 struct rpc_pipe_client **presult)3831 {3832 struct rpc_pipe_client *result;3833 struct cli_pipe_auth_data *auth;3834 NTSTATUS status;3835 3836 status = cli_rpc_pipe_open(cli, transport, interface, &result);3837 if (!NT_STATUS_IS_OK(status)) {3838 return status;3839 }3840 3841 status = rpccli_ntlmssp_bind_data(3842 result, auth_type, auth_level, domain, username,3843 password, &auth);3844 if (!NT_STATUS_IS_OK(status)) {3845 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",3846 nt_errstr(status)));3847 goto err;3848 }3849 3850 status = rpc_pipe_bind(result, auth);3851 if (!NT_STATUS_IS_OK(status)) {3852 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",3853 nt_errstr(status) ));3854 goto err;3855 }3856 3857 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "3858 "machine %s and bound NTLMSSP as user %s\\%s.\n",3859 get_pipe_name_from_syntax(talloc_tos(), interface),3860 cli->desthost, domain, username ));3861 3862 *presult = result;3863 return NT_STATUS_OK;3864 3865 err:3866 3867 TALLOC_FREE(result);3868 return status;3869 }3870 3871 /****************************************************************************3872 External interface.3873 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)3874 ****************************************************************************/3875 3876 2915 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, 3877 2916 const struct ndr_syntax_id *interface, … … 3883 2922 struct rpc_pipe_client **presult) 3884 2923 { 3885 return cli_rpc_pipe_open_ntlmssp_internal(cli, 3886 interface, 3887 transport, 3888 PIPE_AUTH_TYPE_NTLMSSP, 3889 auth_level, 3890 domain, 3891 username, 3892 password, 3893 presult); 2924 struct rpc_pipe_client *result; 2925 struct pipe_auth_data *auth = NULL; 2926 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP; 2927 NTSTATUS status; 2928 2929 status = cli_rpc_pipe_open(cli, transport, interface, &result); 2930 if (!NT_STATUS_IS_OK(status)) { 2931 return status; 2932 } 2933 2934 status = rpccli_ntlmssp_bind_data(result, 2935 auth_type, auth_level, 2936 domain, username, password, 2937 &auth); 2938 if (!NT_STATUS_IS_OK(status)) { 2939 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n", 2940 nt_errstr(status))); 2941 goto err; 2942 } 2943 2944 status = rpc_pipe_bind(result, auth); 2945 if (!NT_STATUS_IS_OK(status)) { 2946 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n", 2947 nt_errstr(status) )); 2948 goto err; 2949 } 2950 2951 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to " 2952 "machine %s and bound NTLMSSP as user %s\\%s.\n", 2953 get_pipe_name_from_syntax(talloc_tos(), interface), 2954 cli->desthost, domain, username )); 2955 2956 *presult = result; 2957 return NT_STATUS_OK; 2958 2959 err: 2960 2961 TALLOC_FREE(result); 2962 return status; 3894 2963 } 3895 2964 3896 2965 /**************************************************************************** 3897 2966 External interface. 3898 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9) 2967 Open a named pipe to an SMB server and bind using schannel (bind type 68) 2968 using session_key. sign and seal. 2969 2970 The *pdc will be stolen onto this new pipe 3899 2971 ****************************************************************************/ 2972 2973 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, 2974 const struct ndr_syntax_id *interface, 2975 enum dcerpc_transport_t transport, 2976 enum dcerpc_AuthLevel auth_level, 2977 const char *domain, 2978 struct netlogon_creds_CredentialState **pdc, 2979 struct rpc_pipe_client **presult) 2980 { 2981 struct rpc_pipe_client *result; 2982 struct pipe_auth_data *auth; 2983 NTSTATUS status; 2984 2985 status = cli_rpc_pipe_open(cli, transport, interface, &result); 2986 if (!NT_STATUS_IS_OK(status)) { 2987 return status; 2988 } 2989 2990 status = rpccli_schannel_bind_data(result, domain, auth_level, 2991 *pdc, &auth); 2992 if (!NT_STATUS_IS_OK(status)) { 2993 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n", 2994 nt_errstr(status))); 2995 TALLOC_FREE(result); 2996 return status; 2997 } 2998 2999 status = rpc_pipe_bind(result, auth); 3000 if (!NT_STATUS_IS_OK(status)) { 3001 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: " 3002 "cli_rpc_pipe_bind failed with error %s\n", 3003 nt_errstr(status) )); 3004 TALLOC_FREE(result); 3005 return status; 3006 } 3007 3008 /* 3009 * The credentials on a new netlogon pipe are the ones we are passed 3010 * in - copy them over 3011 */ 3012 result->dc = netlogon_creds_copy(result, *pdc); 3013 if (result->dc == NULL) { 3014 TALLOC_FREE(result); 3015 return NT_STATUS_NO_MEMORY; 3016 } 3017 3018 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " 3019 "for domain %s and bound using schannel.\n", 3020 get_pipe_name_from_syntax(talloc_tos(), interface), 3021 cli->desthost, domain )); 3022 3023 *presult = result; 3024 return NT_STATUS_OK; 3025 } 3026 3027 /**************************************************************************** 3028 Open a named pipe to an SMB server and bind using krb5 (bind type 16). 3029 The idea is this can be called with service_princ, username and password all 3030 NULL so long as the caller has a TGT. 3031 ****************************************************************************/ 3032 3033 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli, 3034 const struct ndr_syntax_id *interface, 3035 enum dcerpc_transport_t transport, 3036 enum dcerpc_AuthLevel auth_level, 3037 const char *server, 3038 const char *username, 3039 const char *password, 3040 struct rpc_pipe_client **presult) 3041 { 3042 struct rpc_pipe_client *result; 3043 struct pipe_auth_data *auth; 3044 struct gse_context *gse_ctx; 3045 NTSTATUS status; 3046 3047 status = cli_rpc_pipe_open(cli, transport, interface, &result); 3048 if (!NT_STATUS_IS_OK(status)) { 3049 return status; 3050 } 3051 3052 auth = talloc(result, struct pipe_auth_data); 3053 if (auth == NULL) { 3054 status = NT_STATUS_NO_MEMORY; 3055 goto err_out; 3056 } 3057 auth->auth_type = DCERPC_AUTH_TYPE_KRB5; 3058 auth->auth_level = auth_level; 3059 3060 if (!username) { 3061 username = ""; 3062 } 3063 auth->user_name = talloc_strdup(auth, username); 3064 if (!auth->user_name) { 3065 status = NT_STATUS_NO_MEMORY; 3066 goto err_out; 3067 } 3068 3069 /* Fixme, should we fetch/set the Realm ? */ 3070 auth->domain = talloc_strdup(auth, ""); 3071 if (!auth->domain) { 3072 status = NT_STATUS_NO_MEMORY; 3073 goto err_out; 3074 } 3075 3076 status = gse_init_client(auth, 3077 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY), 3078 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY), 3079 NULL, server, "cifs", username, password, 3080 GSS_C_DCE_STYLE, &gse_ctx); 3081 if (!NT_STATUS_IS_OK(status)) { 3082 DEBUG(0, ("gse_init_client returned %s\n", 3083 nt_errstr(status))); 3084 goto err_out; 3085 } 3086 auth->auth_ctx = gse_ctx; 3087 3088 status = rpc_pipe_bind(result, auth); 3089 if (!NT_STATUS_IS_OK(status)) { 3090 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n", 3091 nt_errstr(status))); 3092 goto err_out; 3093 } 3094 3095 *presult = result; 3096 return NT_STATUS_OK; 3097 3098 err_out: 3099 TALLOC_FREE(result); 3100 return status; 3101 } 3102 3103 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli, 3104 const struct ndr_syntax_id *interface, 3105 enum dcerpc_transport_t transport, 3106 enum dcerpc_AuthLevel auth_level, 3107 const char *server, 3108 const char *username, 3109 const char *password, 3110 struct rpc_pipe_client **presult) 3111 { 3112 struct rpc_pipe_client *result; 3113 struct pipe_auth_data *auth; 3114 struct spnego_context *spnego_ctx; 3115 NTSTATUS status; 3116 3117 status = cli_rpc_pipe_open(cli, transport, interface, &result); 3118 if (!NT_STATUS_IS_OK(status)) { 3119 return status; 3120 } 3121 3122 auth = talloc(result, struct pipe_auth_data); 3123 if (auth == NULL) { 3124 status = NT_STATUS_NO_MEMORY; 3125 goto err_out; 3126 } 3127 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; 3128 auth->auth_level = auth_level; 3129 3130 if (!username) { 3131 username = ""; 3132 } 3133 auth->user_name = talloc_strdup(auth, username); 3134 if (!auth->user_name) { 3135 status = NT_STATUS_NO_MEMORY; 3136 goto err_out; 3137 } 3138 3139 /* Fixme, should we fetch/set the Realm ? */ 3140 auth->domain = talloc_strdup(auth, ""); 3141 if (!auth->domain) { 3142 status = NT_STATUS_NO_MEMORY; 3143 goto err_out; 3144 } 3145 3146 status = spnego_gssapi_init_client(auth, 3147 (auth->auth_level == 3148 DCERPC_AUTH_LEVEL_INTEGRITY), 3149 (auth->auth_level == 3150 DCERPC_AUTH_LEVEL_PRIVACY), 3151 true, 3152 NULL, server, "cifs", 3153 username, password, 3154 &spnego_ctx); 3155 if (!NT_STATUS_IS_OK(status)) { 3156 DEBUG(0, ("spnego_init_client returned %s\n", 3157 nt_errstr(status))); 3158 goto err_out; 3159 } 3160 auth->auth_ctx = spnego_ctx; 3161 3162 status = rpc_pipe_bind(result, auth); 3163 if (!NT_STATUS_IS_OK(status)) { 3164 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n", 3165 nt_errstr(status))); 3166 goto err_out; 3167 } 3168 3169 *presult = result; 3170 return NT_STATUS_OK; 3171 3172 err_out: 3173 TALLOC_FREE(result); 3174 return status; 3175 } 3900 3176 3901 3177 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, … … 3908 3184 struct rpc_pipe_client **presult) 3909 3185 { 3910 return cli_rpc_pipe_open_ntlmssp_internal(cli, 3911 interface, 3912 transport, 3913 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, 3914 auth_level, 3915 domain, 3916 username, 3917 password, 3918 presult); 3919 } 3920 3921 /**************************************************************************** 3922 Get a the schannel session key out of an already opened netlogon pipe. 3923 ****************************************************************************/ 3924 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe, 3925 struct cli_state *cli, 3926 const char *domain, 3927 uint32 *pneg_flags) 3928 { 3929 enum netr_SchannelType sec_chan_type = 0; 3930 unsigned char machine_pwd[16]; 3931 const char *machine_account; 3932 NTSTATUS status; 3933 3934 /* Get the machine account credentials from secrets.tdb. */ 3935 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, 3936 &sec_chan_type)) 3937 { 3938 DEBUG(0, ("get_schannel_session_key: could not fetch " 3939 "trust account password for domain '%s'\n", 3940 domain)); 3941 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 3942 } 3943 3944 status = rpccli_netlogon_setup_creds(netlogon_pipe, 3945 cli->desthost, /* server name */ 3946 domain, /* domain */ 3947 global_myname(), /* client name */ 3948 machine_account, /* machine account name */ 3949 machine_pwd, 3950 sec_chan_type, 3951 pneg_flags); 3952 3953 if (!NT_STATUS_IS_OK(status)) { 3954 DEBUG(3, ("get_schannel_session_key_common: " 3955 "rpccli_netlogon_setup_creds failed with result %s " 3956 "to server %s, domain %s, machine account %s.\n", 3957 nt_errstr(status), cli->desthost, domain, 3958 machine_account )); 3186 struct rpc_pipe_client *result; 3187 struct pipe_auth_data *auth; 3188 struct spnego_context *spnego_ctx; 3189 NTSTATUS status; 3190 3191 status = cli_rpc_pipe_open(cli, transport, interface, &result); 3192 if (!NT_STATUS_IS_OK(status)) { 3959 3193 return status; 3960 3194 } 3961 3195 3962 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { 3963 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", 3964 cli->desthost)); 3965 return NT_STATUS_INVALID_NETWORK_RESPONSE; 3966 } 3967 3968 return NT_STATUS_OK;; 3969 } 3970 3971 /**************************************************************************** 3972 Open a netlogon pipe and get the schannel session key. 3973 Now exposed to external callers. 3974 ****************************************************************************/ 3975 3976 3977 NTSTATUS get_schannel_session_key(struct cli_state *cli, 3978 const char *domain, 3979 uint32 *pneg_flags, 3980 struct rpc_pipe_client **presult) 3981 { 3982 struct rpc_pipe_client *netlogon_pipe = NULL; 3983 NTSTATUS status; 3984 3985 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id, 3986 &netlogon_pipe); 3987 if (!NT_STATUS_IS_OK(status)) { 3988 return status; 3989 } 3990 3991 status = get_schannel_session_key_common(netlogon_pipe, cli, domain, 3992 pneg_flags); 3993 if (!NT_STATUS_IS_OK(status)) { 3994 TALLOC_FREE(netlogon_pipe); 3995 return status; 3996 } 3997 3998 *presult = netlogon_pipe; 3999 return NT_STATUS_OK; 4000 } 4001 4002 /**************************************************************************** 4003 External interface. 4004 Open a named pipe to an SMB server and bind using schannel (bind type 68) 4005 using session_key. sign and seal. 4006 4007 The *pdc will be stolen onto this new pipe 4008 ****************************************************************************/ 4009 4010 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, 4011 const struct ndr_syntax_id *interface, 4012 enum dcerpc_transport_t transport, 4013 enum dcerpc_AuthLevel auth_level, 4014 const char *domain, 4015 struct netlogon_creds_CredentialState **pdc, 4016 struct rpc_pipe_client **presult) 4017 { 4018 struct rpc_pipe_client *result; 4019 struct cli_pipe_auth_data *auth; 4020 NTSTATUS status; 4021 4022 status = cli_rpc_pipe_open(cli, transport, interface, &result); 4023 if (!NT_STATUS_IS_OK(status)) { 4024 return status; 4025 } 4026 4027 status = rpccli_schannel_bind_data(result, domain, auth_level, 4028 *pdc, &auth); 4029 if (!NT_STATUS_IS_OK(status)) { 4030 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n", 3196 auth = talloc(result, struct pipe_auth_data); 3197 if (auth == NULL) { 3198 status = NT_STATUS_NO_MEMORY; 3199 goto err_out; 3200 } 3201 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO; 3202 auth->auth_level = auth_level; 3203 3204 if (!username) { 3205 username = ""; 3206 } 3207 auth->user_name = talloc_strdup(auth, username); 3208 if (!auth->user_name) { 3209 status = NT_STATUS_NO_MEMORY; 3210 goto err_out; 3211 } 3212 3213 if (!domain) { 3214 domain = ""; 3215 } 3216 auth->domain = talloc_strdup(auth, domain); 3217 if (!auth->domain) { 3218 status = NT_STATUS_NO_MEMORY; 3219 goto err_out; 3220 } 3221 3222 status = spnego_ntlmssp_init_client(auth, 3223 (auth->auth_level == 3224 DCERPC_AUTH_LEVEL_INTEGRITY), 3225 (auth->auth_level == 3226 DCERPC_AUTH_LEVEL_PRIVACY), 3227 true, 3228 domain, username, password, 3229 &spnego_ctx); 3230 if (!NT_STATUS_IS_OK(status)) { 3231 DEBUG(0, ("spnego_init_client returned %s\n", 4031 3232 nt_errstr(status))); 4032 TALLOC_FREE(result);4033 return status;4034 }3233 goto err_out; 3234 } 3235 auth->auth_ctx = spnego_ctx; 4035 3236 4036 3237 status = rpc_pipe_bind(result, auth); 4037 3238 if (!NT_STATUS_IS_OK(status)) { 4038 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: " 4039 "cli_rpc_pipe_bind failed with error %s\n", 4040 nt_errstr(status) )); 4041 TALLOC_FREE(result); 4042 return status; 4043 } 4044 4045 /* 4046 * The credentials on a new netlogon pipe are the ones we are passed 4047 * in - copy them over 4048 */ 4049 result->dc = netlogon_creds_copy(result, *pdc); 4050 if (result->dc == NULL) { 4051 TALLOC_FREE(result); 4052 return NT_STATUS_NO_MEMORY; 4053 } 4054 4055 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " 4056 "for domain %s and bound using schannel.\n", 4057 get_pipe_name_from_syntax(talloc_tos(), interface), 4058 cli->desthost, domain )); 3239 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n", 3240 nt_errstr(status))); 3241 goto err_out; 3242 } 4059 3243 4060 3244 *presult = result; 4061 3245 return NT_STATUS_OK; 4062 } 4063 4064 /**************************************************************************** 4065 Open a named pipe to an SMB server and bind using schannel (bind type 68). 4066 Fetch the session key ourselves using a temporary netlogon pipe. This 4067 version uses an ntlmssp auth bound netlogon pipe to get the key. 4068 ****************************************************************************/ 4069 4070 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli, 4071 const char *domain, 4072 const char *username, 4073 const char *password, 4074 uint32 *pneg_flags, 4075 struct rpc_pipe_client **presult) 4076 { 4077 struct rpc_pipe_client *netlogon_pipe = NULL; 4078 NTSTATUS status; 4079 4080 status = cli_rpc_pipe_open_spnego_ntlmssp( 4081 cli, &ndr_table_netlogon.syntax_id, NCACN_NP, 4082 DCERPC_AUTH_LEVEL_PRIVACY, 4083 domain, username, password, &netlogon_pipe); 4084 if (!NT_STATUS_IS_OK(status)) { 4085 return status; 4086 } 4087 4088 status = get_schannel_session_key_common(netlogon_pipe, cli, domain, 4089 pneg_flags); 4090 if (!NT_STATUS_IS_OK(status)) { 4091 TALLOC_FREE(netlogon_pipe); 4092 return status; 4093 } 4094 4095 *presult = netlogon_pipe; 4096 return NT_STATUS_OK; 4097 } 4098 4099 /**************************************************************************** 4100 Open a named pipe to an SMB server and bind using schannel (bind type 68). 4101 Fetch the session key ourselves using a temporary netlogon pipe. This version 4102 uses an ntlmssp bind to get the session key. 4103 ****************************************************************************/ 4104 4105 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli, 4106 const struct ndr_syntax_id *interface, 4107 enum dcerpc_transport_t transport, 4108 enum dcerpc_AuthLevel auth_level, 4109 const char *domain, 4110 const char *username, 4111 const char *password, 4112 struct rpc_pipe_client **presult) 4113 { 4114 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; 4115 struct rpc_pipe_client *netlogon_pipe = NULL; 4116 struct rpc_pipe_client *result = NULL; 4117 NTSTATUS status; 4118 4119 status = get_schannel_session_key_auth_ntlmssp( 4120 cli, domain, username, password, &neg_flags, &netlogon_pipe); 4121 if (!NT_STATUS_IS_OK(status)) { 4122 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " 4123 "key from server %s for domain %s.\n", 4124 cli->desthost, domain )); 4125 return status; 4126 } 4127 4128 status = cli_rpc_pipe_open_schannel_with_key( 4129 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc, 4130 &result); 4131 4132 /* Now we've bound using the session key we can close the netlog pipe. */ 4133 TALLOC_FREE(netlogon_pipe); 4134 4135 if (NT_STATUS_IS_OK(status)) { 4136 *presult = result; 4137 } 3246 3247 err_out: 3248 TALLOC_FREE(result); 4138 3249 return status; 4139 }4140 4141 /****************************************************************************4142 Open a named pipe to an SMB server and bind using schannel (bind type 68).4143 Fetch the session key ourselves using a temporary netlogon pipe.4144 ****************************************************************************/4145 4146 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,4147 const struct ndr_syntax_id *interface,4148 enum dcerpc_transport_t transport,4149 enum dcerpc_AuthLevel auth_level,4150 const char *domain,4151 struct rpc_pipe_client **presult)4152 {4153 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;4154 struct rpc_pipe_client *netlogon_pipe = NULL;4155 struct rpc_pipe_client *result = NULL;4156 NTSTATUS status;4157 4158 status = get_schannel_session_key(cli, domain, &neg_flags,4159 &netlogon_pipe);4160 if (!NT_STATUS_IS_OK(status)) {4161 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "4162 "key from server %s for domain %s.\n",4163 cli->desthost, domain ));4164 return status;4165 }4166 4167 status = cli_rpc_pipe_open_schannel_with_key(4168 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,4169 &result);4170 4171 /* Now we've bound using the session key we can close the netlog pipe. */4172 TALLOC_FREE(netlogon_pipe);4173 4174 if (NT_STATUS_IS_OK(status)) {4175 *presult = result;4176 }4177 4178 return status;4179 }4180 4181 /****************************************************************************4182 Open a named pipe to an SMB server and bind using krb5 (bind type 16).4183 The idea is this can be called with service_princ, username and password all4184 NULL so long as the caller has a TGT.4185 ****************************************************************************/4186 4187 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,4188 const struct ndr_syntax_id *interface,4189 enum dcerpc_AuthLevel auth_level,4190 const char *service_princ,4191 const char *username,4192 const char *password,4193 struct rpc_pipe_client **presult)4194 {4195 #ifdef HAVE_KRB54196 struct rpc_pipe_client *result;4197 struct cli_pipe_auth_data *auth;4198 NTSTATUS status;4199 4200 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);4201 if (!NT_STATUS_IS_OK(status)) {4202 return status;4203 }4204 4205 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,4206 username, password, &auth);4207 if (!NT_STATUS_IS_OK(status)) {4208 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",4209 nt_errstr(status)));4210 TALLOC_FREE(result);4211 return status;4212 }4213 4214 status = rpc_pipe_bind(result, auth);4215 if (!NT_STATUS_IS_OK(status)) {4216 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "4217 "with error %s\n", nt_errstr(status)));4218 TALLOC_FREE(result);4219 return status;4220 }4221 4222 *presult = result;4223 return NT_STATUS_OK;4224 #else4225 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));4226 return NT_STATUS_NOT_IMPLEMENTED;4227 #endif4228 3250 } 4229 3251 … … 4232 3254 DATA_BLOB *session_key) 4233 3255 { 3256 struct pipe_auth_data *a = cli->auth; 3257 struct schannel_state *schannel_auth; 3258 struct auth_ntlmssp_state *ntlmssp_ctx; 3259 struct spnego_context *spnego_ctx; 3260 struct gse_context *gse_ctx; 3261 DATA_BLOB sk = data_blob_null; 3262 bool make_dup = false; 3263 4234 3264 if (!session_key || !cli) { 4235 3265 return NT_STATUS_INVALID_PARAMETER; … … 4241 3271 4242 3272 switch (cli->auth->auth_type) { 4243 case PIPE_AUTH_TYPE_SCHANNEL: 4244 *session_key = data_blob_talloc(mem_ctx, 4245 cli->auth->a_u.schannel_auth->creds->session_key, 16); 4246 break; 4247 case PIPE_AUTH_TYPE_NTLMSSP: 4248 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: 4249 *session_key = data_blob_talloc(mem_ctx, 4250 cli->auth->a_u.ntlmssp_state->session_key.data, 4251 cli->auth->a_u.ntlmssp_state->session_key.length); 4252 break; 4253 case PIPE_AUTH_TYPE_KRB5: 4254 case PIPE_AUTH_TYPE_SPNEGO_KRB5: 4255 *session_key = data_blob_talloc(mem_ctx, 4256 cli->auth->a_u.kerberos_auth->session_key.data, 4257 cli->auth->a_u.kerberos_auth->session_key.length); 4258 break; 4259 case PIPE_AUTH_TYPE_NONE: 4260 *session_key = data_blob_talloc(mem_ctx, 4261 cli->auth->user_session_key.data, 4262 cli->auth->user_session_key.length); 4263 break; 4264 default: 4265 return NT_STATUS_NO_USER_SESSION_KEY; 3273 case DCERPC_AUTH_TYPE_SCHANNEL: 3274 schannel_auth = talloc_get_type_abort(a->auth_ctx, 3275 struct schannel_state); 3276 sk = data_blob_const(schannel_auth->creds->session_key, 16); 3277 make_dup = true; 3278 break; 3279 case DCERPC_AUTH_TYPE_SPNEGO: 3280 spnego_ctx = talloc_get_type_abort(a->auth_ctx, 3281 struct spnego_context); 3282 sk = spnego_get_session_key(mem_ctx, spnego_ctx); 3283 make_dup = false; 3284 break; 3285 case DCERPC_AUTH_TYPE_NTLMSSP: 3286 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx, 3287 struct auth_ntlmssp_state); 3288 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx); 3289 make_dup = true; 3290 break; 3291 case DCERPC_AUTH_TYPE_KRB5: 3292 gse_ctx = talloc_get_type_abort(a->auth_ctx, 3293 struct gse_context); 3294 sk = gse_get_session_key(mem_ctx, gse_ctx); 3295 make_dup = false; 3296 break; 3297 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: 3298 case DCERPC_AUTH_TYPE_NONE: 3299 sk = data_blob_const(a->user_session_key.data, 3300 a->user_session_key.length); 3301 make_dup = true; 3302 break; 3303 default: 3304 break; 3305 } 3306 3307 if (!sk.data) { 3308 return NT_STATUS_NO_USER_SESSION_KEY; 3309 } 3310 3311 if (make_dup) { 3312 *session_key = data_blob_dup_talloc(mem_ctx, &sk); 3313 } else { 3314 *session_key = sk; 4266 3315 } 4267 3316 -
vendor/current/source3/rpc_client/cli_samr.c
r597 r740 23 23 24 24 #include "includes.h" 25 #include "rpc_client/rpc_client.h" 25 26 #include "../libcli/auth/libcli_auth.h" 26 #include "../librpc/gen_ndr/cli_samr.h" 27 #include "../librpc/gen_ndr/ndr_samr_c.h" 28 #include "rpc_client/cli_samr.h" 29 #include "../lib/crypto/arcfour.h" 30 #include "rpc_client/init_lsa.h" 27 31 28 32 /* User change password */ 29 33 30 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,34 NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, 31 35 TALLOC_CTX *mem_ctx, 32 36 struct policy_handle *user_handle, 33 37 const char *newpassword, 34 const char *oldpassword) 35 { 36 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 38 const char *oldpassword, 39 NTSTATUS *presult) 40 { 41 NTSTATUS status; 37 42 struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6; 38 43 … … 62 67 E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); 63 68 64 result = rpccli_samr_ChangePasswordUser(cli, mem_ctx, 69 status = dcerpc_samr_ChangePasswordUser(h, 70 mem_ctx, 65 71 user_handle, 66 72 true, … … 73 79 &hash5, 74 80 true, 75 &hash6); 81 &hash6, 82 presult); 83 84 return status; 85 } 86 87 NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli, 88 TALLOC_CTX *mem_ctx, 89 struct policy_handle *user_handle, 90 const char *newpassword, 91 const char *oldpassword) 92 { 93 NTSTATUS status; 94 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 95 96 status = dcerpc_samr_chgpasswd_user(cli->binding_handle, 97 mem_ctx, 98 user_handle, 99 newpassword, 100 oldpassword, 101 &result); 102 if (!NT_STATUS_IS_OK(status)) { 103 return status; 104 } 76 105 77 106 return result; 78 107 } 79 108 80 81 109 /* User change password */ 82 110 83 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,111 NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, 84 112 TALLOC_CTX *mem_ctx, 113 const char *srv_name_slash, 85 114 const char *username, 86 115 const char *newpassword, 87 const char *oldpassword) 88 { 89 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 116 const char *oldpassword, 117 NTSTATUS *presult) 118 { 119 NTSTATUS status; 90 120 struct samr_CryptPassword new_nt_password; 91 121 struct samr_CryptPassword new_lm_password; … … 93 123 struct samr_Password old_lanman_hash_enc; 94 124 95 u charold_nt_hash[16];96 u charold_lanman_hash[16];97 u charnew_nt_hash[16];98 u charnew_lanman_hash[16];125 uint8_t old_nt_hash[16]; 126 uint8_t old_lanman_hash[16]; 127 uint8_t new_nt_hash[16]; 128 uint8_t new_lanman_hash[16]; 99 129 struct lsa_String server, account; 100 130 101 131 DEBUG(10,("rpccli_samr_chgpasswd_user2\n")); 102 132 103 init_lsa_String(&server, cli->srv_name_slash);133 init_lsa_String(&server, srv_name_slash); 104 134 init_lsa_String(&account, username); 105 135 … … 130 160 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); 131 161 132 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx, 162 status = dcerpc_samr_ChangePasswordUser2(h, 163 mem_ctx, 133 164 &server, 134 165 &account, … … 137 168 true, 138 169 &new_lm_password, 139 &old_lanman_hash_enc); 170 &old_lanman_hash_enc, 171 presult); 172 173 return status; 174 } 175 176 NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, 177 TALLOC_CTX *mem_ctx, 178 const char *username, 179 const char *newpassword, 180 const char *oldpassword) 181 { 182 NTSTATUS status; 183 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 184 185 status = dcerpc_samr_chgpasswd_user2(cli->binding_handle, 186 mem_ctx, 187 cli->srv_name_slash, 188 username, 189 newpassword, 190 oldpassword, 191 &result); 192 if (!NT_STATUS_IS_OK(status)) { 193 return status; 194 } 140 195 141 196 return result; … … 143 198 144 199 /* User change password given blobs */ 200 201 NTSTATUS dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle *h, 202 TALLOC_CTX *mem_ctx, 203 const char *srv_name_slash, 204 const char *username, 205 DATA_BLOB new_nt_password_blob, 206 DATA_BLOB old_nt_hash_enc_blob, 207 DATA_BLOB new_lm_password_blob, 208 DATA_BLOB old_lm_hash_enc_blob, 209 NTSTATUS *presult) 210 { 211 NTSTATUS status; 212 struct samr_CryptPassword new_nt_password; 213 struct samr_CryptPassword new_lm_password; 214 struct samr_Password old_nt_hash_enc; 215 struct samr_Password old_lm_hash_enc; 216 struct lsa_String server, account; 217 218 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n")); 219 220 ZERO_STRUCT(new_nt_password); 221 ZERO_STRUCT(new_lm_password); 222 ZERO_STRUCT(old_nt_hash_enc); 223 ZERO_STRUCT(old_lm_hash_enc); 224 225 init_lsa_String(&server, srv_name_slash); 226 init_lsa_String(&account, username); 227 228 if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) { 229 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516); 230 } 231 232 if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) { 233 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516); 234 } 235 236 if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) { 237 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16); 238 } 239 240 if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) { 241 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16); 242 } 243 244 status = dcerpc_samr_ChangePasswordUser2(h, 245 mem_ctx, 246 &server, 247 &account, 248 &new_nt_password, 249 &old_nt_hash_enc, 250 true, 251 &new_lm_password, 252 &old_lm_hash_enc, 253 presult); 254 255 return status; 256 } 145 257 146 258 NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli, … … 152 264 DATA_BLOB old_lm_hash_enc_blob) 153 265 { 266 NTSTATUS status; 154 267 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 155 struct samr_CryptPassword new_nt_password; 156 struct samr_CryptPassword new_lm_password; 157 struct samr_Password old_nt_hash_enc; 158 struct samr_Password old_lm_hash_enc; 159 struct lsa_String server, account; 160 161 ZERO_STRUCT(new_nt_password); 162 ZERO_STRUCT(new_lm_password); 163 ZERO_STRUCT(old_nt_hash_enc); 164 ZERO_STRUCT(old_lm_hash_enc); 165 166 DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n")); 167 168 init_lsa_String(&server, cli->srv_name_slash); 169 init_lsa_String(&account, username); 170 171 if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) { 172 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516); 173 } 174 if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) { 175 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516); 176 } 177 if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) { 178 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16); 179 } 180 if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) { 181 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16); 182 } 183 184 result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx, 185 &server, 186 &account, 187 &new_nt_password, 188 &old_nt_hash_enc, 189 true, 190 &new_lm_password, 191 &old_lm_hash_enc); 268 269 status = dcerpc_samr_chng_pswd_auth_crap(cli->binding_handle, 270 mem_ctx, 271 cli->srv_name_slash, 272 username, 273 new_nt_password_blob, 274 old_nt_hash_enc_blob, 275 new_lm_password_blob, 276 old_lm_hash_enc_blob, 277 &result); 278 if (!NT_STATUS_IS_OK(status)) { 279 return status; 280 } 281 192 282 return result; 193 283 } 194 284 195 196 285 /* change password 3 */ 197 286 198 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,287 NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, 199 288 TALLOC_CTX *mem_ctx, 289 const char *srv_name_slash, 200 290 const char *username, 201 291 const char *newpassword, 202 292 const char *oldpassword, 203 293 struct samr_DomInfo1 **dominfo1, 204 struct samr_ChangeReject **reject) 294 struct userPwdChangeFailureInformation **reject, 295 NTSTATUS *presult) 205 296 { 206 297 NTSTATUS status; … … 211 302 struct samr_Password old_lanman_hash_enc; 212 303 213 u charold_nt_hash[16];214 u charold_lanman_hash[16];215 u charnew_nt_hash[16];216 u charnew_lanman_hash[16];304 uint8_t old_nt_hash[16]; 305 uint8_t old_lanman_hash[16]; 306 uint8_t new_nt_hash[16]; 307 uint8_t new_lanman_hash[16]; 217 308 218 309 struct lsa_String server, account; … … 220 311 DEBUG(10,("rpccli_samr_chgpasswd_user3\n")); 221 312 222 init_lsa_String(&server, cli->srv_name_slash);313 init_lsa_String(&server, srv_name_slash); 223 314 init_lsa_String(&account, username); 224 315 … … 249 340 E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); 250 341 251 status = rpccli_samr_ChangePasswordUser3(cli, mem_ctx, 342 status = dcerpc_samr_ChangePasswordUser3(h, 343 mem_ctx, 252 344 &server, 253 345 &account, … … 259 351 NULL, 260 352 dominfo1, 261 reject); 353 reject, 354 presult); 355 262 356 return status; 357 } 358 359 NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli, 360 TALLOC_CTX *mem_ctx, 361 const char *username, 362 const char *newpassword, 363 const char *oldpassword, 364 struct samr_DomInfo1 **dominfo1, 365 struct userPwdChangeFailureInformation **reject) 366 { 367 NTSTATUS status; 368 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 369 370 status = dcerpc_samr_chgpasswd_user3(cli->binding_handle, 371 mem_ctx, 372 cli->srv_name_slash, 373 username, 374 newpassword, 375 oldpassword, 376 dominfo1, 377 reject, 378 &result); 379 if (!NT_STATUS_IS_OK(status)) { 380 return status; 381 } 382 383 return result; 263 384 } 264 385 … … 268 389 obtained by inspection using ethereal and NT4 running User Manager. */ 269 390 270 void get_query_dispinfo_params(int loop_count, uint32 *max_entries, 271 uint32 *max_size) 391 void dcerpc_get_query_dispinfo_params(int loop_count, 392 uint32_t *max_entries, 393 uint32_t *max_size) 272 394 { 273 395 switch(loop_count) { … … 295 417 } 296 418 297 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli,419 NTSTATUS dcerpc_try_samr_connects(struct dcerpc_binding_handle *h, 298 420 TALLOC_CTX *mem_ctx, 421 const char *srv_name_slash, 299 422 uint32_t access_mask, 300 struct policy_handle *connect_pol) 423 struct policy_handle *connect_pol, 424 NTSTATUS *presult) 301 425 { 302 426 NTSTATUS status; … … 310 434 info_in.info1 = info1; 311 435 312 status = rpccli_samr_Connect5(cli, mem_ctx, 313 cli->srv_name_slash, 436 status = dcerpc_samr_Connect5(h, 437 mem_ctx, 438 srv_name_slash, 314 439 access_mask, 315 440 1, … … 317 442 &lvl_out, 318 443 &info_out, 319 connect_pol); 320 if (NT_STATUS_IS_OK(status)) { 321 return status; 322 } 323 324 status = rpccli_samr_Connect4(cli, mem_ctx, 325 cli->srv_name_slash, 444 connect_pol, 445 presult); 446 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) { 447 return status; 448 } 449 450 status = dcerpc_samr_Connect4(h, 451 mem_ctx, 452 srv_name_slash, 326 453 SAMR_CONNECT_W2K, 327 454 access_mask, 328 connect_pol); 329 if (NT_STATUS_IS_OK(status)) { 330 return status; 331 } 332 333 status = rpccli_samr_Connect2(cli, mem_ctx, 334 cli->srv_name_slash, 455 connect_pol, 456 presult); 457 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) { 458 return status; 459 } 460 461 status = dcerpc_samr_Connect2(h, 462 mem_ctx, 463 srv_name_slash, 335 464 access_mask, 336 connect_pol); 465 connect_pol, 466 presult); 467 337 468 return status; 338 469 } 339 470 471 NTSTATUS rpccli_try_samr_connects(struct rpc_pipe_client *cli, 472 TALLOC_CTX *mem_ctx, 473 uint32_t access_mask, 474 struct policy_handle *connect_pol) 475 { 476 NTSTATUS status; 477 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 478 479 status = dcerpc_try_samr_connects(cli->binding_handle, 480 mem_ctx, 481 cli->srv_name_slash, 482 access_mask, 483 connect_pol, 484 &result); 485 if (!NT_STATUS_IS_OK(status)) { 486 return status; 487 } 488 489 return result; 490 } 491 492 /* vim: set ts=8 sw=8 noet cindent: */ -
vendor/current/source3/rpc_client/cli_spoolss.c
r427 r740 24 24 25 25 #include "includes.h" 26 #include "../librpc/gen_ndr/cli_spoolss.h" 26 #include "rpc_client/rpc_client.h" 27 #include "../librpc/gen_ndr/ndr_spoolss_c.h" 28 #include "rpc_client/cli_spoolss.h" 27 29 28 30 /********************************************************************** … … 41 43 union spoolss_UserLevel userlevel; 42 44 struct spoolss_UserLevel1 level1; 45 struct dcerpc_binding_handle *b = cli->binding_handle; 43 46 44 47 ZERO_STRUCT(devmode_ctr); … … 55 58 userlevel.level1 = &level1; 56 59 57 status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,60 status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx, 58 61 printername, 59 62 NULL, … … 65 68 &werror); 66 69 70 if (!NT_STATUS_IS_OK(status)) { 71 return ntstatus_to_werror(status); 72 } 73 67 74 if (!W_ERROR_IS_OK(werror)) { 68 75 return werror; 69 }70 71 if (!NT_STATUS_IS_OK(status)) {72 return ntstatus_to_werror(status);73 76 } 74 77 … … 92 95 uint32_t needed; 93 96 DATA_BLOB buffer; 94 95 if (offered > 0) { 96 buffer = data_blob_talloc_zero(mem_ctx, offered); 97 W_ERROR_HAVE_NO_MEMORY(buffer.data); 98 } 99 100 status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx, 97 struct dcerpc_binding_handle *b = cli->binding_handle; 98 99 if (offered > 0) { 100 buffer = data_blob_talloc_zero(mem_ctx, offered); 101 W_ERROR_HAVE_NO_MEMORY(buffer.data); 102 } 103 104 status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx, 101 105 handle, 102 106 architecture, … … 107 111 &needed, 108 112 &werror); 113 if (!NT_STATUS_IS_OK(status)) { 114 return ntstatus_to_werror(status); 115 } 109 116 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { 110 117 offered = needed; … … 112 119 W_ERROR_HAVE_NO_MEMORY(buffer.data); 113 120 114 status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,121 status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx, 115 122 handle, 116 123 architecture, … … 121 128 &needed, 122 129 &werror); 130 } 131 if (!NT_STATUS_IS_OK(status)) { 132 return ntstatus_to_werror(status); 123 133 } 124 134 … … 146 156 uint32_t needed; 147 157 DATA_BLOB buffer; 148 149 if (offered > 0) { 150 buffer = data_blob_talloc_zero(mem_ctx, offered); 151 W_ERROR_HAVE_NO_MEMORY(buffer.data); 152 } 153 154 status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx, 158 struct dcerpc_binding_handle *b = cli->binding_handle; 159 160 if (offered > 0) { 161 buffer = data_blob_talloc_zero(mem_ctx, offered); 162 W_ERROR_HAVE_NO_MEMORY(buffer.data); 163 } 164 165 status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx, 155 166 handle, 156 167 architecture, … … 165 176 server_minor_version, 166 177 &werror); 178 if (!NT_STATUS_IS_OK(status)) { 179 return ntstatus_to_werror(status); 180 } 181 167 182 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { 168 183 offered = needed; … … 170 185 W_ERROR_HAVE_NO_MEMORY(buffer.data); 171 186 172 status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,187 status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx, 173 188 handle, 174 189 architecture, … … 184 199 &werror); 185 200 } 201 if (!NT_STATUS_IS_OK(status)) { 202 return ntstatus_to_werror(status); 203 } 186 204 187 205 return werror; … … 203 221 struct spoolss_UserLevel1 level1; 204 222 struct policy_handle handle; 223 struct dcerpc_binding_handle *b = cli->binding_handle; 205 224 206 225 ZERO_STRUCT(devmode_ctr); … … 219 238 userlevel_ctr.user_info.level1 = &level1; 220 239 221 status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,240 status = dcerpc_spoolss_AddPrinterEx(b, mem_ctx, 222 241 cli->srv_name_slash, 223 242 info_ctr, … … 227 246 &handle, 228 247 &result); 248 if (!NT_STATUS_IS_OK(status)) { 249 return ntstatus_to_werror(status); 250 } 251 229 252 return result; 230 253 } … … 245 268 DATA_BLOB buffer; 246 269 uint32_t needed; 247 248 if (offered > 0) { 249 buffer = data_blob_talloc_zero(mem_ctx, offered); 250 W_ERROR_HAVE_NO_MEMORY(buffer.data); 251 } 252 253 status = rpccli_spoolss_GetPrinter(cli, mem_ctx, 270 struct dcerpc_binding_handle *b = cli->binding_handle; 271 272 if (offered > 0) { 273 buffer = data_blob_talloc_zero(mem_ctx, offered); 274 W_ERROR_HAVE_NO_MEMORY(buffer.data); 275 } 276 277 status = dcerpc_spoolss_GetPrinter(b, mem_ctx, 254 278 handle, 255 279 level, … … 259 283 &needed, 260 284 &werror); 261 262 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { 263 264 offered = needed; 265 buffer = data_blob_talloc_zero(mem_ctx, offered); 266 W_ERROR_HAVE_NO_MEMORY(buffer.data); 267 268 status = rpccli_spoolss_GetPrinter(cli, mem_ctx, 285 if (!NT_STATUS_IS_OK(status)) { 286 return ntstatus_to_werror(status); 287 } 288 289 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { 290 291 offered = needed; 292 buffer = data_blob_talloc_zero(mem_ctx, offered); 293 W_ERROR_HAVE_NO_MEMORY(buffer.data); 294 295 status = dcerpc_spoolss_GetPrinter(b, mem_ctx, 269 296 handle, 270 297 level, … … 275 302 &werror); 276 303 } 304 if (!NT_STATUS_IS_OK(status)) { 305 return ntstatus_to_werror(status); 306 } 277 307 278 308 return werror; … … 295 325 uint32_t needed; 296 326 DATA_BLOB buffer; 297 298 if (offered > 0) { 299 buffer = data_blob_talloc_zero(mem_ctx, offered); 300 W_ERROR_HAVE_NO_MEMORY(buffer.data); 301 } 302 303 status = rpccli_spoolss_GetJob(cli, mem_ctx, 327 struct dcerpc_binding_handle *b = cli->binding_handle; 328 329 if (offered > 0) { 330 buffer = data_blob_talloc_zero(mem_ctx, offered); 331 W_ERROR_HAVE_NO_MEMORY(buffer.data); 332 } 333 334 status = dcerpc_spoolss_GetJob(b, mem_ctx, 304 335 handle, 305 336 job_id, … … 310 341 &needed, 311 342 &werror); 343 if (!NT_STATUS_IS_OK(status)) { 344 return ntstatus_to_werror(status); 345 } 312 346 313 347 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 316 350 W_ERROR_HAVE_NO_MEMORY(buffer.data); 317 351 318 status = rpccli_spoolss_GetJob(cli, mem_ctx,352 status = dcerpc_spoolss_GetJob(b, mem_ctx, 319 353 handle, 320 354 job_id, … … 326 360 &werror); 327 361 } 362 if (!NT_STATUS_IS_OK(status)) { 363 return ntstatus_to_werror(status); 364 } 328 365 329 366 return werror; … … 346 383 uint32_t needed; 347 384 DATA_BLOB buffer; 348 349 if (offered > 0) { 350 buffer = data_blob_talloc_zero(mem_ctx, offered); 351 W_ERROR_HAVE_NO_MEMORY(buffer.data); 352 } 353 354 status = rpccli_spoolss_EnumForms(cli, mem_ctx, 385 struct dcerpc_binding_handle *b = cli->binding_handle; 386 387 if (offered > 0) { 388 buffer = data_blob_talloc_zero(mem_ctx, offered); 389 W_ERROR_HAVE_NO_MEMORY(buffer.data); 390 } 391 392 status = dcerpc_spoolss_EnumForms(b, mem_ctx, 355 393 handle, 356 394 level, … … 361 399 &needed, 362 400 &werror); 401 if (!NT_STATUS_IS_OK(status)) { 402 return ntstatus_to_werror(status); 403 } 363 404 364 405 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 367 408 W_ERROR_HAVE_NO_MEMORY(buffer.data); 368 409 369 status = rpccli_spoolss_EnumForms(cli, mem_ctx,410 status = dcerpc_spoolss_EnumForms(b, mem_ctx, 370 411 handle, 371 412 level, … … 377 418 &werror); 378 419 } 420 if (!NT_STATUS_IS_OK(status)) { 421 return ntstatus_to_werror(status); 422 } 379 423 380 424 return werror; … … 398 442 uint32_t needed; 399 443 DATA_BLOB buffer; 400 401 if (offered > 0) { 402 buffer = data_blob_talloc_zero(mem_ctx, offered); 403 W_ERROR_HAVE_NO_MEMORY(buffer.data); 404 } 405 406 status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx, 444 struct dcerpc_binding_handle *b = cli->binding_handle; 445 446 if (offered > 0) { 447 buffer = data_blob_talloc_zero(mem_ctx, offered); 448 W_ERROR_HAVE_NO_MEMORY(buffer.data); 449 } 450 451 status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx, 407 452 servername, 408 453 environment, … … 414 459 &needed, 415 460 &werror); 461 if (!NT_STATUS_IS_OK(status)) { 462 return ntstatus_to_werror(status); 463 } 416 464 417 465 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 420 468 W_ERROR_HAVE_NO_MEMORY(buffer.data); 421 469 422 status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,470 status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx, 423 471 servername, 424 472 environment, … … 431 479 &werror); 432 480 } 481 if (!NT_STATUS_IS_OK(status)) { 482 return ntstatus_to_werror(status); 483 } 433 484 434 485 return werror; … … 452 503 uint32_t needed; 453 504 DATA_BLOB buffer; 454 455 if (offered > 0) { 456 buffer = data_blob_talloc_zero(mem_ctx, offered); 457 W_ERROR_HAVE_NO_MEMORY(buffer.data); 458 } 459 460 status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx, 505 struct dcerpc_binding_handle *b = cli->binding_handle; 506 507 if (offered > 0) { 508 buffer = data_blob_talloc_zero(mem_ctx, offered); 509 W_ERROR_HAVE_NO_MEMORY(buffer.data); 510 } 511 512 status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx, 461 513 servername, 462 514 print_processor_name, … … 468 520 &needed, 469 521 &werror); 522 if (!NT_STATUS_IS_OK(status)) { 523 return ntstatus_to_werror(status); 524 } 470 525 471 526 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 474 529 W_ERROR_HAVE_NO_MEMORY(buffer.data); 475 530 476 status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,531 status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx, 477 532 servername, 478 533 print_processor_name, … … 485 540 &werror); 486 541 } 542 if (!NT_STATUS_IS_OK(status)) { 543 return ntstatus_to_werror(status); 544 } 487 545 488 546 return werror; … … 505 563 uint32_t needed; 506 564 DATA_BLOB buffer; 507 508 if (offered > 0) { 509 buffer = data_blob_talloc_zero(mem_ctx, offered); 510 W_ERROR_HAVE_NO_MEMORY(buffer.data); 511 } 512 513 status = rpccli_spoolss_EnumPorts(cli, mem_ctx, 565 struct dcerpc_binding_handle *b = cli->binding_handle; 566 567 if (offered > 0) { 568 buffer = data_blob_talloc_zero(mem_ctx, offered); 569 W_ERROR_HAVE_NO_MEMORY(buffer.data); 570 } 571 572 status = dcerpc_spoolss_EnumPorts(b, mem_ctx, 514 573 servername, 515 574 level, … … 520 579 &needed, 521 580 &werror); 581 if (!NT_STATUS_IS_OK(status)) { 582 return ntstatus_to_werror(status); 583 } 522 584 523 585 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 526 588 W_ERROR_HAVE_NO_MEMORY(buffer.data); 527 589 528 status = rpccli_spoolss_EnumPorts(cli, mem_ctx,590 status = dcerpc_spoolss_EnumPorts(b, mem_ctx, 529 591 servername, 530 592 level, … … 536 598 &werror); 537 599 } 600 if (!NT_STATUS_IS_OK(status)) { 601 return ntstatus_to_werror(status); 602 } 538 603 539 604 return werror; … … 556 621 uint32_t needed; 557 622 DATA_BLOB buffer; 558 559 if (offered > 0) { 560 buffer = data_blob_talloc_zero(mem_ctx, offered); 561 W_ERROR_HAVE_NO_MEMORY(buffer.data); 562 } 563 564 status = rpccli_spoolss_EnumMonitors(cli, mem_ctx, 623 struct dcerpc_binding_handle *b = cli->binding_handle; 624 625 if (offered > 0) { 626 buffer = data_blob_talloc_zero(mem_ctx, offered); 627 W_ERROR_HAVE_NO_MEMORY(buffer.data); 628 } 629 630 status = dcerpc_spoolss_EnumMonitors(b, mem_ctx, 565 631 servername, 566 632 level, … … 571 637 &needed, 572 638 &werror); 639 if (!NT_STATUS_IS_OK(status)) { 640 return ntstatus_to_werror(status); 641 } 573 642 574 643 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 577 646 W_ERROR_HAVE_NO_MEMORY(buffer.data); 578 647 579 status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,648 status = dcerpc_spoolss_EnumMonitors(b, mem_ctx, 580 649 servername, 581 650 level, … … 586 655 &needed, 587 656 &werror); 657 } 658 if (!NT_STATUS_IS_OK(status)) { 659 return ntstatus_to_werror(status); 588 660 } 589 661 … … 609 681 uint32_t needed; 610 682 DATA_BLOB buffer; 611 612 if (offered > 0) { 613 buffer = data_blob_talloc_zero(mem_ctx, offered); 614 W_ERROR_HAVE_NO_MEMORY(buffer.data); 615 } 616 617 status = rpccli_spoolss_EnumJobs(cli, mem_ctx, 683 struct dcerpc_binding_handle *b = cli->binding_handle; 684 685 if (offered > 0) { 686 buffer = data_blob_talloc_zero(mem_ctx, offered); 687 W_ERROR_HAVE_NO_MEMORY(buffer.data); 688 } 689 690 status = dcerpc_spoolss_EnumJobs(b, mem_ctx, 618 691 handle, 619 692 firstjob, … … 626 699 &needed, 627 700 &werror); 701 if (!NT_STATUS_IS_OK(status)) { 702 return ntstatus_to_werror(status); 703 } 628 704 629 705 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 632 708 W_ERROR_HAVE_NO_MEMORY(buffer.data); 633 709 634 status = rpccli_spoolss_EnumJobs(cli, mem_ctx,710 status = dcerpc_spoolss_EnumJobs(b, mem_ctx, 635 711 handle, 636 712 firstjob, … … 644 720 &werror); 645 721 } 722 if (!NT_STATUS_IS_OK(status)) { 723 return ntstatus_to_werror(status); 724 } 646 725 647 726 return werror; … … 665 744 uint32_t needed; 666 745 DATA_BLOB buffer; 667 668 if (offered > 0) { 669 buffer = data_blob_talloc_zero(mem_ctx, offered); 670 W_ERROR_HAVE_NO_MEMORY(buffer.data); 671 } 672 673 status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx, 746 struct dcerpc_binding_handle *b = cli->binding_handle; 747 748 if (offered > 0) { 749 buffer = data_blob_talloc_zero(mem_ctx, offered); 750 W_ERROR_HAVE_NO_MEMORY(buffer.data); 751 } 752 753 status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx, 674 754 server, 675 755 environment, … … 681 761 &needed, 682 762 &werror); 763 if (!NT_STATUS_IS_OK(status)) { 764 return ntstatus_to_werror(status); 765 } 683 766 684 767 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 687 770 W_ERROR_HAVE_NO_MEMORY(buffer.data); 688 771 689 status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,772 status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx, 690 773 server, 691 774 environment, … … 698 781 &werror); 699 782 } 783 if (!NT_STATUS_IS_OK(status)) { 784 return ntstatus_to_werror(status); 785 } 700 786 701 787 return werror; … … 719 805 uint32_t needed; 720 806 DATA_BLOB buffer; 721 722 if (offered > 0) { 723 buffer = data_blob_talloc_zero(mem_ctx, offered); 724 W_ERROR_HAVE_NO_MEMORY(buffer.data); 725 } 726 727 status = rpccli_spoolss_EnumPrinters(cli, mem_ctx, 807 struct dcerpc_binding_handle *b = cli->binding_handle; 808 809 if (offered > 0) { 810 buffer = data_blob_talloc_zero(mem_ctx, offered); 811 W_ERROR_HAVE_NO_MEMORY(buffer.data); 812 } 813 814 status = dcerpc_spoolss_EnumPrinters(b, mem_ctx, 728 815 flags, 729 816 server, … … 735 822 &needed, 736 823 &werror); 824 if (!NT_STATUS_IS_OK(status)) { 825 return ntstatus_to_werror(status); 826 } 737 827 738 828 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { … … 741 831 W_ERROR_HAVE_NO_MEMORY(buffer.data); 742 832 743 status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,833 status = dcerpc_spoolss_EnumPrinters(b, mem_ctx, 744 834 flags, 745 835 server, … … 752 842 &werror); 753 843 } 844 if (!NT_STATUS_IS_OK(status)) { 845 return ntstatus_to_werror(status); 846 } 754 847 755 848 return werror; … … 773 866 uint32_t needed; 774 867 uint8_t *data; 868 struct dcerpc_binding_handle *b = cli->binding_handle; 775 869 776 870 data = talloc_zero_array(mem_ctx, uint8_t, offered); 777 871 W_ERROR_HAVE_NO_MEMORY(data); 778 872 779 status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,873 status = dcerpc_spoolss_GetPrinterData(b, mem_ctx, 780 874 handle, 781 875 value_name, … … 785 879 &needed, 786 880 &werror); 881 if (!NT_STATUS_IS_OK(status)) { 882 return ntstatus_to_werror(status); 883 } 787 884 788 885 if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { … … 791 888 W_ERROR_HAVE_NO_MEMORY(data); 792 889 793 status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,890 status = dcerpc_spoolss_GetPrinterData(b, mem_ctx, 794 891 handle, 795 892 value_name, … … 800 897 &werror); 801 898 } 899 if (!NT_STATUS_IS_OK(status)) { 900 return ntstatus_to_werror(status); 901 } 802 902 803 903 *data_p = data; … … 823 923 union spoolss_KeyNames _key_buffer; 824 924 uint32_t _ndr_size; 825 826 status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx, 925 struct dcerpc_binding_handle *b = cli->binding_handle; 926 927 status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx, 827 928 handle, 828 929 key_name, … … 832 933 &needed, 833 934 &werror); 935 if (!NT_STATUS_IS_OK(status)) { 936 return ntstatus_to_werror(status); 937 } 834 938 835 939 if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { 836 940 offered = needed; 837 status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,941 status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx, 838 942 handle, 839 943 key_name, … … 844 948 &werror); 845 949 } 950 if (!NT_STATUS_IS_OK(status)) { 951 return ntstatus_to_werror(status); 952 } 846 953 847 954 *key_buffer = _key_buffer.string_array; … … 865 972 WERROR werror; 866 973 uint32_t needed; 867 868 status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx, 974 struct dcerpc_binding_handle *b = cli->binding_handle; 975 976 status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx, 869 977 handle, 870 978 key_name, … … 874 982 &needed, 875 983 &werror); 984 if (!NT_STATUS_IS_OK(status)) { 985 return ntstatus_to_werror(status); 986 } 876 987 877 988 if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) { 878 989 offered = needed; 879 990 880 status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,991 status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx, 881 992 handle, 882 993 key_name, … … 887 998 &werror); 888 999 } 889 890 return werror; 891 } 1000 if (!NT_STATUS_IS_OK(status)) { 1001 return ntstatus_to_werror(status); 1002 } 1003 1004 return werror; 1005 } -
vendor/current/source3/rpc_client/init_lsa.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "rpc_client/init_lsa.h" 22 #include "../librpc/gen_ndr/lsa.h" 21 23 22 24 /******************************************************************* -
vendor/current/source3/rpc_client/init_netlogon.c
r414 r740 20 20 #include "includes.h" 21 21 #include "../libcli/auth/libcli_auth.h" 22 #include "../lib/crypto/arcfour.h" 23 #include "rpc_client/init_netlogon.h" 22 24 23 25 /************************************************************************* -
vendor/current/source3/rpc_client/init_samr.c
r414 r740 20 20 #include "includes.h" 21 21 #include "../libcli/auth/libcli_auth.h" 22 #include "../lib/crypto/md5.h" 23 #include "../lib/crypto/arcfour.h" 24 #include "rpc_client/init_samr.h" 22 25 23 26 /************************************************************************* -
vendor/current/source3/rpc_client/init_spoolss.c
r587 r740 19 19 20 20 #include "includes.h" 21 #include "../librpc/gen_ndr/ndr_spoolss.h" 22 #include "rpc_client/init_spoolss.h" 23 #include "../libcli/security/security.h" 24 #include "secrets.h" 25 #include "passdb/machine_sid.h" 21 26 22 27 /******************************************************************* … … 42 47 } 43 48 49 time_t spoolss_Time_to_time_t(const struct spoolss_Time *r) 50 { 51 struct tm unixtime; 52 53 unixtime.tm_year = r->year - 1900; 54 unixtime.tm_mon = r->month - 1; 55 unixtime.tm_wday = r->day_of_week; 56 unixtime.tm_mday = r->day; 57 unixtime.tm_hour = r->hour; 58 unixtime.tm_min = r->minute; 59 unixtime.tm_sec = r->second; 60 61 return mktime(&unixtime); 62 } 63 44 64 /******************************************************************* 45 65 ********************************************************************/ … … 51 71 { 52 72 enum ndr_err_code ndr_err; 53 ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL,data, type,73 ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type, 54 74 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData); 55 75 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 67 87 { 68 88 enum ndr_err_code ndr_err; 69 ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL,data, type,89 ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type, 70 90 (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData); 71 91 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 103 123 s->averageppm = i->averageppm; 104 124 } 125 126 /**************************************************************************** 127 ****************************************************************************/ 128 129 bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, 130 struct spoolss_DriverInfo8 *_info8) 131 { 132 struct spoolss_DriverInfo8 info8; 133 134 ZERO_STRUCT(info8); 135 136 switch (r->level) { 137 case 3: 138 info8.version = r->info.info3->version; 139 info8.driver_name = r->info.info3->driver_name; 140 info8.architecture = r->info.info3->architecture; 141 info8.driver_path = r->info.info3->driver_path; 142 info8.data_file = r->info.info3->data_file; 143 info8.config_file = r->info.info3->config_file; 144 info8.help_file = r->info.info3->help_file; 145 info8.monitor_name = r->info.info3->monitor_name; 146 info8.default_datatype = r->info.info3->default_datatype; 147 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { 148 info8.dependent_files = r->info.info3->dependent_files->string; 149 } 150 break; 151 case 6: 152 info8.version = r->info.info6->version; 153 info8.driver_name = r->info.info6->driver_name; 154 info8.architecture = r->info.info6->architecture; 155 info8.driver_path = r->info.info6->driver_path; 156 info8.data_file = r->info.info6->data_file; 157 info8.config_file = r->info.info6->config_file; 158 info8.help_file = r->info.info6->help_file; 159 info8.monitor_name = r->info.info6->monitor_name; 160 info8.default_datatype = r->info.info6->default_datatype; 161 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { 162 info8.dependent_files = r->info.info6->dependent_files->string; 163 } 164 info8.driver_date = r->info.info6->driver_date; 165 info8.driver_version = r->info.info6->driver_version; 166 info8.manufacturer_name = r->info.info6->manufacturer_name; 167 info8.manufacturer_url = r->info.info6->manufacturer_url; 168 info8.hardware_id = r->info.info6->hardware_id; 169 info8.provider = r->info.info6->provider; 170 break; 171 case 8: 172 info8.version = r->info.info8->version; 173 info8.driver_name = r->info.info8->driver_name; 174 info8.architecture = r->info.info8->architecture; 175 info8.driver_path = r->info.info8->driver_path; 176 info8.data_file = r->info.info8->data_file; 177 info8.config_file = r->info.info8->config_file; 178 info8.help_file = r->info.info8->help_file; 179 info8.monitor_name = r->info.info8->monitor_name; 180 info8.default_datatype = r->info.info8->default_datatype; 181 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { 182 info8.dependent_files = r->info.info8->dependent_files->string; 183 } 184 if (r->info.info8->previous_names && r->info.info8->previous_names->string) { 185 info8.previous_names = r->info.info8->previous_names->string; 186 } 187 info8.driver_date = r->info.info8->driver_date; 188 info8.driver_version = r->info.info8->driver_version; 189 info8.manufacturer_name = r->info.info8->manufacturer_name; 190 info8.manufacturer_url = r->info.info8->manufacturer_url; 191 info8.hardware_id = r->info.info8->hardware_id; 192 info8.provider = r->info.info8->provider; 193 info8.print_processor = r->info.info8->print_processor; 194 info8.vendor_setup = r->info.info8->vendor_setup; 195 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { 196 info8.color_profiles = r->info.info8->color_profiles->string; 197 } 198 info8.inf_path = r->info.info8->inf_path; 199 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; 200 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { 201 info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; 202 } 203 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; 204 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; 205 break; 206 default: 207 return false; 208 } 209 210 *_info8 = info8; 211 212 return true; 213 } 214 215 /**************************************************************************** 216 Create and allocate a default devicemode. 217 ****************************************************************************/ 218 219 WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, 220 const char *devicename, 221 struct spoolss_DeviceMode **devmode) 222 { 223 struct spoolss_DeviceMode *dm; 224 char *dname; 225 226 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); 227 if (dm == NULL) { 228 return WERR_NOMEM; 229 } 230 231 dname = talloc_asprintf(dm, "%s", devicename); 232 if (dname == NULL) { 233 return WERR_NOMEM; 234 } 235 if (strlen(dname) > MAXDEVICENAME) { 236 dname[MAXDEVICENAME] = '\0'; 237 } 238 dm->devicename = dname; 239 240 dm->formname = talloc_strdup(dm, "Letter"); 241 if (dm->formname == NULL) { 242 return WERR_NOMEM; 243 } 244 245 dm->specversion = DMSPEC_NT4_AND_ABOVE; 246 dm->driverversion = 0x0400; 247 dm->size = 0x00DC; 248 dm->__driverextra_length = 0; 249 dm->fields = DEVMODE_FORMNAME | 250 DEVMODE_TTOPTION | 251 DEVMODE_PRINTQUALITY | 252 DEVMODE_DEFAULTSOURCE | 253 DEVMODE_COPIES | 254 DEVMODE_SCALE | 255 DEVMODE_PAPERSIZE | 256 DEVMODE_ORIENTATION; 257 dm->orientation = DMORIENT_PORTRAIT; 258 dm->papersize = DMPAPER_LETTER; 259 dm->paperlength = 0; 260 dm->paperwidth = 0; 261 dm->scale = 0x64; 262 dm->copies = 1; 263 dm->defaultsource = DMBIN_FORMSOURCE; 264 dm->printquality = DMRES_HIGH; /* 0x0258 */ 265 dm->color = DMRES_MONOCHROME; 266 dm->duplex = DMDUP_SIMPLEX; 267 dm->yresolution = 0; 268 dm->ttoption = DMTT_SUBDEV; 269 dm->collate = DMCOLLATE_FALSE; 270 dm->icmmethod = 0; 271 dm->icmintent = 0; 272 dm->mediatype = 0; 273 dm->dithertype = 0; 274 275 dm->logpixels = 0; 276 dm->bitsperpel = 0; 277 dm->pelswidth = 0; 278 dm->pelsheight = 0; 279 dm->displayflags = 0; 280 dm->displayfrequency = 0; 281 dm->reserved1 = 0; 282 dm->reserved2 = 0; 283 dm->panningwidth = 0; 284 dm->panningheight = 0; 285 286 dm->driverextra_data.data = NULL; 287 dm->driverextra_data.length = 0; 288 289 *devmode = dm; 290 return WERR_OK; 291 } 292 293 WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, 294 struct spoolss_security_descriptor **secdesc) 295 { 296 struct security_ace ace[7]; /* max number of ace entries */ 297 int i = 0; 298 uint32_t sa; 299 struct security_acl *psa = NULL; 300 struct security_descriptor *psd = NULL; 301 struct dom_sid adm_sid; 302 size_t sd_size; 303 304 /* Create an ACE where Everyone is allowed to print */ 305 306 sa = PRINTER_ACE_PRINT; 307 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, 308 sa, SEC_ACE_FLAG_CONTAINER_INHERIT); 309 310 /* Add the domain admins group if we are a DC */ 311 312 if ( IS_DC ) { 313 struct dom_sid domadmins_sid; 314 315 sid_compose(&domadmins_sid, get_global_sam_sid(), 316 DOMAIN_RID_ADMINS); 317 318 sa = PRINTER_ACE_FULL_CONTROL; 319 init_sec_ace(&ace[i++], &domadmins_sid, 320 SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 321 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); 322 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, 323 sa, SEC_ACE_FLAG_CONTAINER_INHERIT); 324 } 325 else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) { 326 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR); 327 328 sa = PRINTER_ACE_FULL_CONTROL; 329 init_sec_ace(&ace[i++], &adm_sid, 330 SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 331 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); 332 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, 333 sa, SEC_ACE_FLAG_CONTAINER_INHERIT); 334 } 335 336 /* add BUILTIN\Administrators as FULL CONTROL */ 337 338 sa = PRINTER_ACE_FULL_CONTROL; 339 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, 340 SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 341 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); 342 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, 343 SEC_ACE_TYPE_ACCESS_ALLOWED, 344 sa, SEC_ACE_FLAG_CONTAINER_INHERIT); 345 346 /* add BUILTIN\Print Operators as FULL CONTROL */ 347 348 sa = PRINTER_ACE_FULL_CONTROL; 349 init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, 350 SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 351 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); 352 init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, 353 SEC_ACE_TYPE_ACCESS_ALLOWED, 354 sa, SEC_ACE_FLAG_CONTAINER_INHERIT); 355 356 /* Make the security descriptor owned by the BUILTIN\Administrators */ 357 358 /* The ACL revision number in rpc_secdesc.h differs from the one 359 created by NT when setting ACE entries in printer 360 descriptors. NT4 complains about the property being edited by a 361 NT5 machine. */ 362 363 if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) { 364 psd = make_sec_desc(mem_ctx, 365 SD_REVISION, 366 SEC_DESC_SELF_RELATIVE, 367 &global_sid_Builtin_Administrators, 368 &global_sid_Builtin_Administrators, 369 NULL, 370 psa, 371 &sd_size); 372 } 373 374 if (psd == NULL) { 375 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n")); 376 return WERR_NOMEM; 377 } 378 379 DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 380 (unsigned int)sd_size)); 381 382 *secdesc = psd; 383 384 return WERR_OK; 385 } -
vendor/current/source3/rpc_client/rpc_transport_np.c
r427 r740 19 19 20 20 #include "includes.h" 21 #include "../lib/util/tevent_ntstatus.h" 22 #include "rpc_client/rpc_transport.h" 23 #include "libsmb/cli_np_tstream.h" 21 24 22 25 #undef DBGC_CLASS 23 26 #define DBGC_CLASS DBGC_RPC_CLI 24 27 25 struct rpc_transport_np_state {26 struct cli_state *cli;27 const char *pipe_name;28 uint16_t fnum;29 };30 31 static bool rpc_np_is_connected(void *priv)32 {33 struct rpc_transport_np_state *np_transport = talloc_get_type_abort(34 priv, struct rpc_transport_np_state);35 bool ok;36 37 if (np_transport->cli == NULL) {38 return false;39 }40 41 ok = cli_state_is_connected(np_transport->cli);42 if (!ok) {43 np_transport->cli = NULL;44 return false;45 }46 47 return true;48 }49 50 static unsigned int rpc_np_set_timeout(void *priv, unsigned int timeout)51 {52 struct rpc_transport_np_state *np_transport = talloc_get_type_abort(53 priv, struct rpc_transport_np_state);54 bool ok;55 56 if (np_transport->cli == NULL) {57 return false;58 }59 60 ok = rpc_np_is_connected(np_transport);61 if (!ok) {62 return 0;63 }64 65 return cli_set_timeout(np_transport->cli, timeout);66 }67 68 static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)69 {70 if (!rpc_np_is_connected(s)) {71 DEBUG(10, ("socket was closed, no need to send close request.\n"));72 return 0;73 }74 75 /* TODO: do not use a sync call with a destructor!!! */76 if (!NT_STATUS_IS_OK(cli_close(s->cli, s->fnum))) {77 DEBUG(1, ("rpc_transport_np_state_destructor: cli_close "78 "failed on pipe %s. Error was %s\n", s->pipe_name,79 cli_errstr(s->cli)));80 }81 DEBUG(10, ("rpc_pipe_destructor: closed %s\n", s->pipe_name));82 /*83 * We can't do much on failure84 */85 return 0;86 }87 88 struct rpc_np_write_state {89 struct rpc_transport_np_state *np_transport;90 size_t size;91 size_t written;92 };93 94 static void rpc_np_write_done(struct tevent_req *subreq);95 96 static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,97 struct event_context *ev,98 const uint8_t *data, size_t size,99 void *priv)100 {101 struct rpc_transport_np_state *np_transport = talloc_get_type_abort(102 priv, struct rpc_transport_np_state);103 struct tevent_req *req, *subreq;104 struct rpc_np_write_state *state;105 bool ok;106 107 req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state);108 if (req == NULL) {109 return NULL;110 }111 112 ok = rpc_np_is_connected(np_transport);113 if (!ok) {114 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);115 return tevent_req_post(req, ev);116 }117 118 state->np_transport = np_transport;119 state->size = size;120 121 122 subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli,123 np_transport->fnum,124 8, /* 8 means message mode. */125 data, 0, size);126 if (tevent_req_nomem(subreq, req)) {127 return tevent_req_post(req, ev);128 }129 tevent_req_set_callback(subreq, rpc_np_write_done, req);130 return req;131 }132 133 static void rpc_np_write_done(struct tevent_req *subreq)134 {135 struct tevent_req *req = tevent_req_callback_data(136 subreq, struct tevent_req);137 struct rpc_np_write_state *state = tevent_req_data(138 req, struct rpc_np_write_state);139 NTSTATUS status;140 141 status = cli_write_andx_recv(subreq, &state->written);142 TALLOC_FREE(subreq);143 if (!NT_STATUS_IS_OK(status)) {144 state->np_transport->cli = NULL;145 tevent_req_nterror(req, status);146 return;147 }148 tevent_req_done(req);149 }150 151 static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten)152 {153 struct rpc_np_write_state *state = tevent_req_data(154 req, struct rpc_np_write_state);155 NTSTATUS status;156 157 if (tevent_req_is_nterror(req, &status)) {158 return status;159 }160 *pwritten = state->written;161 return NT_STATUS_OK;162 }163 164 struct rpc_np_read_state {165 struct rpc_transport_np_state *np_transport;166 uint8_t *data;167 size_t size;168 ssize_t received;169 };170 171 static void rpc_np_read_done(struct tevent_req *subreq);172 173 static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,174 struct event_context *ev,175 uint8_t *data, size_t size,176 void *priv)177 {178 struct rpc_transport_np_state *np_transport = talloc_get_type_abort(179 priv, struct rpc_transport_np_state);180 struct tevent_req *req, *subreq;181 struct rpc_np_read_state *state;182 bool ok;183 184 req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state);185 if (req == NULL) {186 return NULL;187 }188 189 ok = rpc_np_is_connected(np_transport);190 if (!ok) {191 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);192 return tevent_req_post(req, ev);193 }194 195 state->np_transport = np_transport;196 state->data = data;197 state->size = size;198 199 subreq = cli_read_andx_send(mem_ctx, ev, np_transport->cli,200 np_transport->fnum, 0, size);201 if (subreq == NULL) {202 goto fail;203 }204 tevent_req_set_callback(subreq, rpc_np_read_done, req);205 return req;206 fail:207 TALLOC_FREE(req);208 return NULL;209 }210 211 static void rpc_np_read_done(struct tevent_req *subreq)212 {213 struct tevent_req *req = tevent_req_callback_data(214 subreq, struct tevent_req);215 struct rpc_np_read_state *state = tevent_req_data(216 req, struct rpc_np_read_state);217 NTSTATUS status;218 uint8_t *rcvbuf;219 220 /* We must free subreq in this function as there is221 a timer event attached to it. */222 223 status = cli_read_andx_recv(subreq, &state->received, &rcvbuf);224 /*225 * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a226 * child of that.227 */228 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {229 status = NT_STATUS_OK;230 }231 if (!NT_STATUS_IS_OK(status)) {232 TALLOC_FREE(subreq);233 state->np_transport->cli = NULL;234 tevent_req_nterror(req, status);235 return;236 }237 238 if (state->received > state->size) {239 TALLOC_FREE(subreq);240 state->np_transport->cli = NULL;241 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);242 return;243 }244 245 if (state->received == 0) {246 TALLOC_FREE(subreq);247 state->np_transport->cli = NULL;248 tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);249 return;250 }251 252 memcpy(state->data, rcvbuf, state->received);253 TALLOC_FREE(subreq);254 tevent_req_done(req);255 }256 257 static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived)258 {259 struct rpc_np_read_state *state = tevent_req_data(260 req, struct rpc_np_read_state);261 NTSTATUS status;262 263 if (tevent_req_is_nterror(req, &status)) {264 return status;265 }266 *preceived = state->received;267 return NT_STATUS_OK;268 }269 270 struct rpc_np_trans_state {271 struct rpc_transport_np_state *np_transport;272 uint16_t setup[2];273 uint32_t max_rdata_len;274 uint8_t *rdata;275 uint32_t rdata_len;276 };277 278 static void rpc_np_trans_done(struct tevent_req *subreq);279 280 static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,281 struct event_context *ev,282 uint8_t *data, size_t data_len,283 uint32_t max_rdata_len,284 void *priv)285 {286 struct rpc_transport_np_state *np_transport = talloc_get_type_abort(287 priv, struct rpc_transport_np_state);288 struct tevent_req *req, *subreq;289 struct rpc_np_trans_state *state;290 bool ok;291 292 req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state);293 if (req == NULL) {294 return NULL;295 }296 297 ok = rpc_np_is_connected(np_transport);298 if (!ok) {299 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);300 return tevent_req_post(req, ev);301 }302 303 state->np_transport = np_transport;304 state->max_rdata_len = max_rdata_len;305 306 SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD);307 SSVAL(state->setup+1, 0, np_transport->fnum);308 309 subreq = cli_trans_send(310 state, ev, np_transport->cli, SMBtrans,311 "\\PIPE\\", 0, 0, 0, state->setup, 2, 0,312 NULL, 0, 0, data, data_len, max_rdata_len);313 if (subreq == NULL) {314 goto fail;315 }316 tevent_req_set_callback(subreq, rpc_np_trans_done, req);317 return req;318 319 fail:320 TALLOC_FREE(req);321 return NULL;322 }323 324 static void rpc_np_trans_done(struct tevent_req *subreq)325 {326 struct tevent_req *req = tevent_req_callback_data(327 subreq, struct tevent_req);328 struct rpc_np_trans_state *state = tevent_req_data(329 req, struct rpc_np_trans_state);330 NTSTATUS status;331 332 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,333 &state->rdata, &state->rdata_len);334 TALLOC_FREE(subreq);335 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {336 status = NT_STATUS_OK;337 }338 if (!NT_STATUS_IS_OK(status)) {339 state->np_transport->cli = NULL;340 tevent_req_nterror(req, status);341 return;342 }343 344 if (state->rdata_len > state->max_rdata_len) {345 state->np_transport->cli = NULL;346 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);347 return;348 }349 350 if (state->rdata_len == 0) {351 state->np_transport->cli = NULL;352 tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);353 return;354 }355 356 tevent_req_done(req);357 }358 359 static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,360 uint8_t **prdata, uint32_t *prdata_len)361 {362 struct rpc_np_trans_state *state = tevent_req_data(363 req, struct rpc_np_trans_state);364 NTSTATUS status;365 366 if (tevent_req_is_nterror(req, &status)) {367 return status;368 }369 *prdata = talloc_move(mem_ctx, &state->rdata);370 *prdata_len = state->rdata_len;371 return NT_STATUS_OK;372 }373 374 28 struct rpc_transport_np_init_state { 375 29 struct rpc_cli_transport *transport; 376 struct rpc_transport_np_state *transport_np;377 30 }; 378 31 … … 384 37 const struct ndr_syntax_id *abstract_syntax) 385 38 { 386 struct tevent_req *req , *subreq;39 struct tevent_req *req; 387 40 struct rpc_transport_np_init_state *state; 388 bool ok; 41 const char *pipe_name; 42 struct tevent_req *subreq; 389 43 390 44 req = tevent_req_create(mem_ctx, &state, … … 394 48 } 395 49 396 ok = cli_state_is_connected(cli); 397 if (!ok) { 398 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); 50 pipe_name = get_pipe_name_from_syntax(state, abstract_syntax); 51 if (tevent_req_nomem(pipe_name, req)) { 399 52 return tevent_req_post(req, ev); 400 53 } 401 54 402 state->transport = talloc(state, struct rpc_cli_transport); 403 if (tevent_req_nomem(state->transport, req)) { 404 return tevent_req_post(req, ev); 405 } 406 state->transport_np = talloc(state->transport, 407 struct rpc_transport_np_state); 408 if (tevent_req_nomem(state->transport_np, req)) { 409 return tevent_req_post(req, ev); 410 } 411 state->transport->priv = state->transport_np; 412 413 state->transport_np->pipe_name = get_pipe_name_from_syntax( 414 state->transport_np, abstract_syntax); 415 state->transport_np->cli = cli; 416 417 subreq = cli_ntcreate_send( 418 state, ev, cli, state->transport_np->pipe_name, 0, 419 DESIRED_ACCESS_PIPE, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, 420 FILE_OPEN, 0, 0); 55 subreq = tstream_cli_np_open_send(state, ev, cli, pipe_name); 421 56 if (tevent_req_nomem(subreq, req)) { 422 57 return tevent_req_post(req, ev); 423 58 } 424 tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open, 425 req); 59 tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open, req); 60 426 61 return req; 427 62 } … … 434 69 req, struct rpc_transport_np_init_state); 435 70 NTSTATUS status; 71 struct tstream_context *stream; 436 72 437 status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);73 status = tstream_cli_np_open_recv(subreq, state, &stream); 438 74 TALLOC_FREE(subreq); 439 75 if (!NT_STATUS_IS_OK(status)) { … … 442 78 } 443 79 444 talloc_set_destructor(state->transport_np, 445 rpc_transport_np_state_destructor); 80 status = rpc_transport_tstream_init(state, 81 &stream, 82 &state->transport); 83 if (!NT_STATUS_IS_OK(status)) { 84 tevent_req_nterror(req, status); 85 return; 86 } 87 446 88 tevent_req_done(req); 447 89 } … … 458 100 return status; 459 101 } 460 461 state->transport->write_send = rpc_np_write_send;462 state->transport->write_recv = rpc_np_write_recv;463 state->transport->read_send = rpc_np_read_send;464 state->transport->read_recv = rpc_np_read_recv;465 state->transport->trans_send = rpc_np_trans_send;466 state->transport->trans_recv = rpc_np_trans_recv;467 state->transport->is_connected = rpc_np_is_connected;468 state->transport->set_timeout = rpc_np_set_timeout;469 102 470 103 *presult = talloc_move(mem_ctx, &state->transport); … … 503 136 return status; 504 137 } 505 506 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)507 {508 struct rpc_transport_np_state *state = talloc_get_type(509 p->transport->priv, struct rpc_transport_np_state);510 511 if (state == NULL) {512 return NULL;513 }514 return state->cli;515 } -
vendor/current/source3/rpc_client/rpc_transport_sock.c
r427 r740 19 19 20 20 #include "includes.h" 21 #include "../lib/tsocket/tsocket.h" 22 #include "rpc_client/rpc_transport.h" 21 23 22 24 #undef DBGC_CLASS 23 25 #define DBGC_CLASS DBGC_RPC_CLI 24 25 struct rpc_transport_sock_state {26 int fd;27 int timeout;28 };29 30 static void rpc_sock_disconnect(struct rpc_transport_sock_state *s)31 {32 if (s->fd != -1) {33 close(s->fd);34 s->fd = -1;35 }36 }37 38 static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s)39 {40 rpc_sock_disconnect(s);41 return 0;42 }43 44 static bool rpc_sock_is_connected(void *priv)45 {46 struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(47 priv, struct rpc_transport_sock_state);48 49 if (sock_transp->fd == -1) {50 return false;51 }52 53 return true;54 }55 56 static unsigned int rpc_sock_set_timeout(void *priv, unsigned int timeout)57 {58 struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(59 priv, struct rpc_transport_sock_state);60 int orig_timeout;61 bool ok;62 63 ok = rpc_sock_is_connected(sock_transp);64 if (!ok) {65 return 0;66 }67 68 orig_timeout = sock_transp->timeout;69 70 sock_transp->timeout = timeout;71 72 return orig_timeout;73 }74 75 struct rpc_sock_read_state {76 struct rpc_transport_sock_state *transp;77 ssize_t received;78 };79 80 static void rpc_sock_read_done(struct tevent_req *subreq);81 82 static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,83 struct event_context *ev,84 uint8_t *data, size_t size,85 void *priv)86 {87 struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(88 priv, struct rpc_transport_sock_state);89 struct tevent_req *req, *subreq;90 struct rpc_sock_read_state *state;91 struct timeval endtime;92 93 req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state);94 if (req == NULL) {95 return NULL;96 }97 if (!rpc_sock_is_connected(sock_transp)) {98 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);99 return tevent_req_post(req, ev);100 }101 state->transp = sock_transp;102 endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);103 subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0);104 if (subreq == NULL) {105 goto fail;106 }107 108 if (!tevent_req_set_endtime(subreq, ev, endtime)) {109 goto fail;110 }111 112 tevent_req_set_callback(subreq, rpc_sock_read_done, req);113 return req;114 fail:115 TALLOC_FREE(req);116 return NULL;117 }118 119 static void rpc_sock_read_done(struct tevent_req *subreq)120 {121 struct tevent_req *req = tevent_req_callback_data(122 subreq, struct tevent_req);123 struct rpc_sock_read_state *state = tevent_req_data(124 req, struct rpc_sock_read_state);125 int err;126 127 /* We must free subreq in this function as there is128 a timer event attached to it. */129 130 state->received = async_recv_recv(subreq, &err);131 132 if (state->received == -1) {133 TALLOC_FREE(subreq);134 rpc_sock_disconnect(state->transp);135 tevent_req_nterror(req, map_nt_error_from_unix(err));136 return;137 }138 TALLOC_FREE(subreq);139 tevent_req_done(req);140 }141 142 static NTSTATUS rpc_sock_read_recv(struct tevent_req *req, ssize_t *preceived)143 {144 struct rpc_sock_read_state *state = tevent_req_data(145 req, struct rpc_sock_read_state);146 NTSTATUS status;147 148 if (tevent_req_is_nterror(req, &status)) {149 return status;150 }151 *preceived = state->received;152 return NT_STATUS_OK;153 }154 155 struct rpc_sock_write_state {156 struct rpc_transport_sock_state *transp;157 ssize_t sent;158 };159 160 static void rpc_sock_write_done(struct tevent_req *subreq);161 162 static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,163 struct event_context *ev,164 const uint8_t *data, size_t size,165 void *priv)166 {167 struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort(168 priv, struct rpc_transport_sock_state);169 struct tevent_req *req, *subreq;170 struct rpc_sock_write_state *state;171 struct timeval endtime;172 173 req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state);174 if (req == NULL) {175 return NULL;176 }177 if (!rpc_sock_is_connected(sock_transp)) {178 tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);179 return tevent_req_post(req, ev);180 }181 state->transp = sock_transp;182 endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);183 subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);184 if (subreq == NULL) {185 goto fail;186 }187 188 if (!tevent_req_set_endtime(subreq, ev, endtime)) {189 goto fail;190 }191 192 tevent_req_set_callback(subreq, rpc_sock_write_done, req);193 return req;194 fail:195 TALLOC_FREE(req);196 return NULL;197 }198 199 static void rpc_sock_write_done(struct tevent_req *subreq)200 {201 struct tevent_req *req = tevent_req_callback_data(202 subreq, struct tevent_req);203 struct rpc_sock_write_state *state = tevent_req_data(204 req, struct rpc_sock_write_state);205 int err;206 207 /* We must free subreq in this function as there is208 a timer event attached to it. */209 210 state->sent = async_send_recv(subreq, &err);211 212 if (state->sent == -1) {213 TALLOC_FREE(subreq);214 rpc_sock_disconnect(state->transp);215 tevent_req_nterror(req, map_nt_error_from_unix(err));216 return;217 }218 TALLOC_FREE(subreq);219 tevent_req_done(req);220 }221 222 static NTSTATUS rpc_sock_write_recv(struct tevent_req *req, ssize_t *psent)223 {224 struct rpc_sock_write_state *state = tevent_req_data(225 req, struct rpc_sock_write_state);226 NTSTATUS status;227 228 if (tevent_req_is_nterror(req, &status)) {229 return status;230 }231 *psent = state->sent;232 return NT_STATUS_OK;233 }234 26 235 27 NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, … … 237 29 { 238 30 struct rpc_cli_transport *result; 239 struct rpc_transport_sock_state *state; 31 struct tstream_context *stream; 32 int ret; 33 NTSTATUS status; 240 34 241 result = talloc(mem_ctx, struct rpc_cli_transport); 242 if (result == NULL) { 243 return NT_STATUS_NO_MEMORY; 35 set_blocking(fd, false); 36 37 ret = tstream_bsd_existing_socket(mem_ctx, fd, &stream); 38 if (ret != 0) { 39 status = map_nt_error_from_unix(errno); 40 return status; 244 41 } 245 state = talloc(result, struct rpc_transport_sock_state); 246 if (state == NULL) { 247 TALLOC_FREE(result); 248 return NT_STATUS_NO_MEMORY; 42 43 status = rpc_transport_tstream_init(mem_ctx, 44 &stream, 45 &result); 46 if (!NT_STATUS_IS_OK(status)) { 47 TALLOC_FREE(stream); 48 return status; 249 49 } 250 result->priv = state;251 252 state->fd = fd;253 state->timeout = 10000; /* 10 seconds. */254 talloc_set_destructor(state, rpc_transport_sock_state_destructor);255 256 result->trans_send = NULL;257 result->trans_recv = NULL;258 result->write_send = rpc_sock_write_send;259 result->write_recv = rpc_sock_write_recv;260 result->read_send = rpc_sock_read_send;261 result->read_recv = rpc_sock_read_recv;262 result->is_connected = rpc_sock_is_connected;263 result->set_timeout = rpc_sock_set_timeout;264 50 265 51 *presult = result;
Note:
See TracChangeset
for help on using the changeset viewer.