1/* 2 Samba Unix/Linux SMB client library 3 Distributed SMB/CIFS Server Management Utility 4 Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) 5 Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) 6 Copyright (C) 2004 Guenther Deschner (gd@samba.org) 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 21 22#include "includes.h" 23#include "utils/net.h" 24 25/** 26 * @file net_rpc.c 27 * 28 * @brief RPC based subcommands for the 'net' utility. 29 * 30 * This file should contain much of the functionality that used to 31 * be found in rpcclient, execpt that the commands should change 32 * less often, and the fucntionality should be sane (the user is not 33 * expected to know a rid/sid before they conduct an operation etc.) 34 * 35 * @todo Perhaps eventually these should be split out into a number 36 * of files, as this could get quite big. 37 **/ 38 39 40/** 41 * Many of the RPC functions need the domain sid. This function gets 42 * it at the start of every run 43 * 44 * @param cli A cli_state already connected to the remote machine 45 * 46 * @return The Domain SID of the remote machine. 47 **/ 48 49static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **domain_name) 50{ 51 DOM_SID *domain_sid; 52 POLICY_HND pol; 53 NTSTATUS result = NT_STATUS_OK; 54 uint32 info_class = 5; 55 56 if (!cli_nt_session_open (cli, PI_LSARPC)) { 57 fprintf(stderr, "could not initialise lsa pipe\n"); 58 goto error; 59 } 60 61 result = cli_lsa_open_policy(cli, mem_ctx, False, 62 SEC_RIGHTS_MAXIMUM_ALLOWED, 63 &pol); 64 if (!NT_STATUS_IS_OK(result)) { 65 goto error; 66 } 67 68 result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 69 domain_name, &domain_sid); 70 if (!NT_STATUS_IS_OK(result)) { 71 error: 72 fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain); 73 74 if (!NT_STATUS_IS_OK(result)) { 75 fprintf(stderr, "error: %s\n", nt_errstr(result)); 76 } 77 78 exit(1); 79 } 80 81 cli_lsa_close(cli, mem_ctx, &pol); 82 cli_nt_session_close(cli); 83 84 return domain_sid; 85} 86 87/** 88 * Run a single RPC command, from start to finish. 89 * 90 * @param pipe_name the pipe to connect to (usually a PIPE_ constant) 91 * @param conn_flag a NET_FLAG_ combination. Passed to 92 * net_make_ipc_connection. 93 * @param argc Standard main() style argc 94 * @param argc Standard main() style argv. Initial components are already 95 * stripped 96 * @return A shell status integer (0 for success) 97 */ 98 99int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags, 100 rpc_command_fn fn, 101 int argc, const char **argv) 102{ 103 struct cli_state *cli = NULL; 104 TALLOC_CTX *mem_ctx; 105 NTSTATUS nt_status; 106 DOM_SID *domain_sid; 107 char *domain_name; 108 109 /* make use of cli_state handed over as an argument, if possible */ 110 if (!cli_arg) 111 cli = net_make_ipc_connection(conn_flags); 112 else 113 cli = cli_arg; 114 115 if (!cli) { 116 return -1; 117 } 118 119 /* Create mem_ctx */ 120 121 if (!(mem_ctx = talloc_init("run_rpc_command"))) { 122 DEBUG(0, ("talloc_init() failed\n")); 123 cli_shutdown(cli); 124 return -1; 125 } 126 127 domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name); 128 129 if (!(conn_flags & NET_FLAGS_NO_PIPE)) { 130 if (!cli_nt_session_open(cli, pipe_idx)) { 131 DEBUG(0, ("Could not initialise pipe\n")); 132 } 133 } 134 135 nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv); 136 137 if (!NT_STATUS_IS_OK(nt_status)) { 138 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status))); 139 } else { 140 DEBUG(5, ("rpc command function succedded\n")); 141 } 142 143 if (!(conn_flags & NET_FLAGS_NO_PIPE)) { 144 if (cli->nt_pipe_fnum[cli->pipe_idx]) 145 cli_nt_session_close(cli); 146 } 147 148 /* close the connection only if it was opened here */ 149 if (!cli_arg) 150 cli_shutdown(cli); 151 152 talloc_destroy(mem_ctx); 153 154 return (!NT_STATUS_IS_OK(nt_status)); 155} 156 157 158/****************************************************************************/ 159 160 161/** 162 * Force a change of the trust acccount password. 163 * 164 * All parameters are provided by the run_rpc_command function, except for 165 * argc, argv which are passes through. 166 * 167 * @param domain_sid The domain sid aquired from the remote server 168 * @param cli A cli_state connected to the server. 169 * @param mem_ctx Talloc context, destoyed on compleation of the function. 170 * @param argc Standard main() style argc 171 * @param argc Standard main() style argv. Initial components are already 172 * stripped 173 * 174 * @return Normal NTSTATUS return. 175 **/ 176 177static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name, 178 struct cli_state *cli, TALLOC_CTX *mem_ctx, 179 int argc, const char **argv) { 180 181 return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup); 182} 183 184/** 185 * Force a change of the trust acccount password. 186 * 187 * @param argc Standard main() style argc 188 * @param argc Standard main() style argv. Initial components are already 189 * stripped 190 * 191 * @return A shell status integer (0 for success) 192 **/ 193 194int net_rpc_changetrustpw(int argc, const char **argv) 195{ 196 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 197 rpc_changetrustpw_internals, 198 argc, argv); 199} 200 201 202/****************************************************************************/ 203 204 205/** 206 * Join a domain, the old way. 207 * 208 * This uses 'machinename' as the inital password, and changes it. 209 * 210 * The password should be created with 'server manager' or equiv first. 211 * 212 * All parameters are provided by the run_rpc_command function, except for 213 * argc, argv which are passes through. 214 * 215 * @param domain_sid The domain sid aquired from the remote server 216 * @param cli A cli_state connected to the server. 217 * @param mem_ctx Talloc context, destoyed on compleation of the function. 218 * @param argc Standard main() style argc 219 * @param argc Standard main() style argv. Initial components are already 220 * stripped 221 * 222 * @return Normal NTSTATUS return. 223 **/ 224 225static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name, 226 struct cli_state *cli, 227 TALLOC_CTX *mem_ctx, 228 int argc, const char **argv) { 229 230 fstring trust_passwd; 231 unsigned char orig_trust_passwd_hash[16]; 232 NTSTATUS result; 233 uint32 sec_channel_type; 234 235 /* 236 check what type of join - if the user want's to join as 237 a BDC, the server must agree that we are a BDC. 238 */ 239 if (argc >= 0) { 240 sec_channel_type = get_sec_channel_type(argv[0]); 241 } else { 242 sec_channel_type = get_sec_channel_type(NULL); 243 } 244 245 fstrcpy(trust_passwd, global_myname()); 246 strlower_m(trust_passwd); 247 248 /* 249 * Machine names can be 15 characters, but the max length on 250 * a password is 14. --jerry 251 */ 252 253 trust_passwd[14] = '\0'; 254 255 E_md4hash(trust_passwd, orig_trust_passwd_hash); 256 257 result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup, 258 orig_trust_passwd_hash, 259 sec_channel_type); 260 261 if (NT_STATUS_IS_OK(result)) 262 printf("Joined domain %s.\n",opt_target_workgroup); 263 264 265 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) { 266 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup)); 267 result = NT_STATUS_UNSUCCESSFUL; 268 } 269 270 return result; 271} 272 273/** 274 * Join a domain, the old way. 275 * 276 * @param argc Standard main() style argc 277 * @param argc Standard main() style argv. Initial components are already 278 * stripped 279 * 280 * @return A shell status integer (0 for success) 281 **/ 282 283static int net_rpc_perform_oldjoin(int argc, const char **argv) 284{ 285 return run_rpc_command(NULL, PI_NETLOGON, 286 NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 287 rpc_oldjoin_internals, 288 argc, argv); 289} 290 291/** 292 * Join a domain, the old way. This function exists to allow 293 * the message to be displayed when oldjoin was explicitly 294 * requested, but not when it was implied by "net rpc join" 295 * 296 * @param argc Standard main() style argc 297 * @param argc Standard main() style argv. Initial components are already 298 * stripped 299 * 300 * @return A shell status integer (0 for success) 301 **/ 302 303static int net_rpc_oldjoin(int argc, const char **argv) 304{ 305 int rc = net_rpc_perform_oldjoin(argc, argv); 306 307 if (rc) { 308 d_printf("Failed to join domain\n"); 309 } 310 311 return rc; 312} 313 314/** 315 * Basic usage function for 'net rpc join' 316 * @param argc Standard main() style argc 317 * @param argc Standard main() style argv. Initial components are already 318 * stripped 319 **/ 320 321static int rpc_join_usage(int argc, const char **argv) 322{ 323 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\ 324 "\t to join a domain with admin username & password\n"\ 325 "\t\t password will be prompted if needed and none is specified\n"\ 326 "\t <type> can be (default MEMBER)\n"\ 327 "\t\t BDC - Join as a BDC\n"\ 328 "\t\t PDC - Join as a PDC\n"\ 329 "\t\t MEMBER - Join as a MEMBER server\n"); 330 331 net_common_flags_usage(argc, argv); 332 return -1; 333} 334 335/** 336 * 'net rpc join' entrypoint. 337 * @param argc Standard main() style argc 338 * @param argc Standard main() style argv. Initial components are already 339 * stripped 340 * 341 * Main 'net_rpc_join()' (where the admain username/password is used) is 342 * in net_rpc_join.c 343 * Try to just change the password, but if that doesn't work, use/prompt 344 * for a username/password. 345 **/ 346 347int net_rpc_join(int argc, const char **argv) 348{ 349 if ((net_rpc_perform_oldjoin(argc, argv) == 0)) 350 return 0; 351 352 return net_rpc_join_newstyle(argc, argv); 353} 354 355 356 357/** 358 * display info about a rpc domain 359 * 360 * All parameters are provided by the run_rpc_command function, except for 361 * argc, argv which are passed through. 362 * 363 * @param domain_sid The domain sid acquired from the remote server 364 * @param cli A cli_state connected to the server. 365 * @param mem_ctx Talloc context, destoyed on completion of the function. 366 * @param argc Standard main() style argc 367 * @param argv Standard main() style argv. Initial components are already 368 * stripped 369 * 370 * @return Normal NTSTATUS return. 371 **/ 372 373static NTSTATUS 374rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name, 375 struct cli_state *cli, 376 TALLOC_CTX *mem_ctx, int argc, const char **argv) 377{ 378 POLICY_HND connect_pol, domain_pol; 379 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 380 SAM_UNK_CTR ctr; 381 fstring sid_str; 382 383 sid_to_string(sid_str, domain_sid); 384 385 /* Get sam policy handle */ 386 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 387 &connect_pol); 388 if (!NT_STATUS_IS_OK(result)) { 389 goto done; 390 } 391 392 /* Get domain policy handle */ 393 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 394 MAXIMUM_ALLOWED_ACCESS, 395 domain_sid, &domain_pol); 396 if (!NT_STATUS_IS_OK(result)) { 397 goto done; 398 } 399 400 ZERO_STRUCT(ctr); 401 result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol, 402 2, &ctr); 403 if (NT_STATUS_IS_OK(result)) { 404 TALLOC_CTX *ctx = talloc_init("rpc_info_internals"); 405 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain)); 406 d_printf("Domain SID: %s\n", sid_str); 407 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num.low); 408 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs); 409 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps); 410 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps); 411 talloc_destroy(ctx); 412 } 413 414 done: 415 return result; 416} 417 418 419/** 420 * 'net rpc info' entrypoint. 421 * @param argc Standard main() style argc 422 * @param argc Standard main() style argv. Initial components are already 423 * stripped 424 **/ 425int net_rpc_info(int argc, const char **argv) 426{ 427 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 428 rpc_info_internals, 429 argc, argv); 430} 431 432 433/** 434 * Fetch domain SID into the local secrets.tdb 435 * 436 * All parameters are provided by the run_rpc_command function, except for 437 * argc, argv which are passes through. 438 * 439 * @param domain_sid The domain sid acquired from the remote server 440 * @param cli A cli_state connected to the server. 441 * @param mem_ctx Talloc context, destoyed on completion of the function. 442 * @param argc Standard main() style argc 443 * @param argv Standard main() style argv. Initial components are already 444 * stripped 445 * 446 * @return Normal NTSTATUS return. 447 **/ 448 449static NTSTATUS 450rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name, 451 struct cli_state *cli, 452 TALLOC_CTX *mem_ctx, int argc, const char **argv) 453{ 454 fstring sid_str; 455 456 sid_to_string(sid_str, domain_sid); 457 d_printf("Storing SID %s for Domain %s in secrets.tdb\n", 458 sid_str, domain_name); 459 460 if (!secrets_store_domain_sid(domain_name, domain_sid)) { 461 DEBUG(0,("Can't store domain SID\n")); 462 return NT_STATUS_UNSUCCESSFUL; 463 } 464 465 return NT_STATUS_OK; 466} 467 468 469/** 470 * 'net rpc getsid' entrypoint. 471 * @param argc Standard main() style argc 472 * @param argc Standard main() style argv. Initial components are already 473 * stripped 474 **/ 475int net_rpc_getsid(int argc, const char **argv) 476{ 477 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 478 rpc_getsid_internals, 479 argc, argv); 480} 481 482 483/****************************************************************************/ 484 485/** 486 * Basic usage function for 'net rpc user' 487 * @param argc Standard main() style argc. 488 * @param argv Standard main() style argv. Initial components are already 489 * stripped. 490 **/ 491 492static int rpc_user_usage(int argc, const char **argv) 493{ 494 return net_help_user(argc, argv); 495} 496 497/** 498 * Add a new user to a remote RPC server 499 * 500 * All parameters are provided by the run_rpc_command function, except for 501 * argc, argv which are passes through. 502 * 503 * @param domain_sid The domain sid acquired from the remote server 504 * @param cli A cli_state connected to the server. 505 * @param mem_ctx Talloc context, destoyed on completion of the function. 506 * @param argc Standard main() style argc 507 * @param argv Standard main() style argv. Initial components are already 508 * stripped 509 * 510 * @return Normal NTSTATUS return. 511 **/ 512 513static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name, 514 struct cli_state *cli, TALLOC_CTX *mem_ctx, 515 int argc, const char **argv) { 516 517 POLICY_HND connect_pol, domain_pol, user_pol; 518 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 519 const char *acct_name; 520 uint16 acb_info; 521 uint32 unknown, user_rid; 522 523 if (argc != 1) { 524 d_printf("User must be specified\n"); 525 rpc_user_usage(argc, argv); 526 return NT_STATUS_OK; 527 } 528 529 acct_name = argv[0]; 530 531 /* Get sam policy handle */ 532 533 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 534 &connect_pol); 535 if (!NT_STATUS_IS_OK(result)) { 536 goto done; 537 } 538 539 /* Get domain policy handle */ 540 541 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 542 MAXIMUM_ALLOWED_ACCESS, 543 domain_sid, &domain_pol); 544 if (!NT_STATUS_IS_OK(result)) { 545 goto done; 546 } 547 548 /* Create domain user */ 549 550 acb_info = ACB_NORMAL; 551 unknown = 0xe005000b; /* No idea what this is - a permission mask? */ 552 553 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, 554 acct_name, acb_info, unknown, 555 &user_pol, &user_rid); 556 if (!NT_STATUS_IS_OK(result)) { 557 goto done; 558 } 559 560 done: 561 if (!NT_STATUS_IS_OK(result)) { 562 d_printf("Failed to add user %s - %s\n", acct_name, 563 nt_errstr(result)); 564 } else { 565 d_printf("Added user %s\n", acct_name); 566 } 567 return result; 568} 569 570/** 571 * Add a new user to a remote RPC server 572 * 573 * @param argc Standard main() style argc 574 * @param argv Standard main() style argv. Initial components are already 575 * stripped 576 * 577 * @return A shell status integer (0 for success) 578 **/ 579 580static int rpc_user_add(int argc, const char **argv) 581{ 582 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals, 583 argc, argv); 584} 585 586/** 587 * Delete a user from a remote RPC server 588 * 589 * All parameters are provided by the run_rpc_command function, except for 590 * argc, argv which are passes through. 591 * 592 * @param domain_sid The domain sid acquired from the remote server 593 * @param cli A cli_state connected to the server. 594 * @param mem_ctx Talloc context, destoyed on completion of the function. 595 * @param argc Standard main() style argc 596 * @param argv Standard main() style argv. Initial components are already 597 * stripped 598 * 599 * @return Normal NTSTATUS return. 600 **/ 601 602static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, 603 const char *domain_name, 604 struct cli_state *cli, 605 TALLOC_CTX *mem_ctx, 606 int argc, const char **argv) 607{ 608 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 609 POLICY_HND connect_pol, domain_pol, user_pol; 610 611 if (argc < 1) { 612 d_printf("User must be specified\n"); 613 rpc_user_usage(argc, argv); 614 return NT_STATUS_OK; 615 } 616 /* Get sam policy and domain handles */ 617 618 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 619 &connect_pol); 620 621 if (!NT_STATUS_IS_OK(result)) { 622 goto done; 623 } 624 625 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 626 MAXIMUM_ALLOWED_ACCESS, 627 domain_sid, &domain_pol); 628 629 if (!NT_STATUS_IS_OK(result)) { 630 goto done; 631 } 632 633 /* Get handle on user */ 634 635 { 636 uint32 *user_rids, num_rids, *name_types; 637 uint32 flags = 0x000003e8; /* Unknown */ 638 639 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 640 flags, 1, &argv[0], 641 &num_rids, &user_rids, 642 &name_types); 643 644 if (!NT_STATUS_IS_OK(result)) { 645 goto done; 646 } 647 648 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 649 MAXIMUM_ALLOWED_ACCESS, 650 user_rids[0], &user_pol); 651 652 if (!NT_STATUS_IS_OK(result)) { 653 goto done; 654 } 655 } 656 657 /* Delete user */ 658 659 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol); 660 661 if (!NT_STATUS_IS_OK(result)) { 662 goto done; 663 } 664 665 /* Display results */ 666 667 done: 668 return result; 669 670} 671 672/** 673 * Rename a user on a remote RPC server 674 * 675 * All parameters are provided by the run_rpc_command function, except for 676 * argc, argv which are passes through. 677 * 678 * @param domain_sid The domain sid acquired from the remote server 679 * @param cli A cli_state connected to the server. 680 * @param mem_ctx Talloc context, destoyed on completion of the function. 681 * @param argc Standard main() style argc 682 * @param argv Standard main() style argv. Initial components are already 683 * stripped 684 * 685 * @return Normal NTSTATUS return. 686 **/ 687 688static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char *domain_name, 689 struct cli_state *cli, TALLOC_CTX *mem_ctx, 690 int argc, const char **argv) { 691 692 POLICY_HND connect_pol, domain_pol, user_pol; 693 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 694 uint32 info_level = 7; 695 const char *old_name, *new_name; 696 uint32 *user_rid; 697 uint32 flags = 0x000003e8; /* Unknown */ 698 uint32 num_rids, *name_types; 699 uint32 num_names = 1; 700 const char **names; 701 SAM_USERINFO_CTR *user_ctr; 702 SAM_USERINFO_CTR ctr; 703 SAM_USER_INFO_7 info7; 704 705 if (argc != 2) { 706 d_printf("New and old username must be specified\n"); 707 rpc_user_usage(argc, argv); 708 return NT_STATUS_OK; 709 } 710 711 old_name = argv[0]; 712 new_name = argv[1]; 713 714 ZERO_STRUCT(ctr); 715 ZERO_STRUCT(user_ctr); 716 717 /* Get sam policy handle */ 718 719 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 720 &connect_pol); 721 if (!NT_STATUS_IS_OK(result)) { 722 goto done; 723 } 724 725 /* Get domain policy handle */ 726 727 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 728 MAXIMUM_ALLOWED_ACCESS, 729 domain_sid, &domain_pol); 730 if (!NT_STATUS_IS_OK(result)) { 731 goto done; 732 } 733 734 names = TALLOC_ARRAY(mem_ctx, const char *, num_names); 735 names[0] = old_name; 736 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 737 flags, num_names, names, 738 &num_rids, &user_rid, &name_types); 739 if (!NT_STATUS_IS_OK(result)) { 740 goto done; 741 } 742 743 /* Open domain user */ 744 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 745 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol); 746 747 if (!NT_STATUS_IS_OK(result)) { 748 goto done; 749 } 750 751 /* Query user info */ 752 result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, 753 info_level, &user_ctr); 754 755 if (!NT_STATUS_IS_OK(result)) { 756 goto done; 757 } 758 759 ctr.switch_value = info_level; 760 ctr.info.id7 = &info7; 761 762 init_sam_user_info7(&info7, new_name); 763 764 /* Set new name */ 765 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 766 info_level, &cli->user_session_key, &ctr); 767 768 if (!NT_STATUS_IS_OK(result)) { 769 goto done; 770 } 771 772 done: 773 if (!NT_STATUS_IS_OK(result)) { 774 d_printf("Failed to rename user from %s to %s - %s\n", old_name, new_name, 775 nt_errstr(result)); 776 } else { 777 d_printf("Renamed user from %s to %s\n", old_name, new_name); 778 } 779 return result; 780} 781 782 783/** 784 * Rename a user on a remote RPC server 785 * 786 * @param argc Standard main() style argc 787 * @param argv Standard main() style argv. Initial components are already 788 * stripped 789 * 790 * @return A shell status integer (0 for success) 791 **/ 792 793static int rpc_user_rename(int argc, const char **argv) 794{ 795 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals, 796 argc, argv); 797} 798 799/** 800 * Delete a user from a remote RPC server 801 * 802 * @param argc Standard main() style argc 803 * @param argv Standard main() style argv. Initial components are already 804 * stripped 805 * 806 * @return A shell status integer (0 for success) 807 **/ 808 809static int rpc_user_delete(int argc, const char **argv) 810{ 811 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals, 812 argc, argv); 813} 814 815/** 816 * Set a password for a user on a remote RPC server 817 * 818 * All parameters are provided by the run_rpc_command function, except for 819 * argc, argv which are passes through. 820 * 821 * @param domain_sid The domain sid acquired from the remote server 822 * @param cli A cli_state connected to the server. 823 * @param mem_ctx Talloc context, destoyed on completion of the function. 824 * @param argc Standard main() style argc 825 * @param argv Standard main() style argv. Initial components are already 826 * stripped 827 * 828 * @return Normal NTSTATUS return. 829 **/ 830 831static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, 832 const char *domain_name, 833 struct cli_state *cli, 834 TALLOC_CTX *mem_ctx, 835 int argc, const char **argv) 836{ 837 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 838 POLICY_HND connect_pol, domain_pol, user_pol; 839 SAM_USERINFO_CTR ctr; 840 SAM_USER_INFO_24 p24; 841 uchar pwbuf[516]; 842 const char *user; 843 const char *new_password; 844 char *prompt = NULL; 845 846 if (argc < 1) { 847 d_printf("User must be specified\n"); 848 rpc_user_usage(argc, argv); 849 return NT_STATUS_OK; 850 } 851 852 user = argv[0]; 853 854 if (argv[1]) { 855 new_password = argv[1]; 856 } else { 857 asprintf(&prompt, "Enter new password for %s:", user); 858 new_password = getpass(prompt); 859 SAFE_FREE(prompt); 860 } 861 862 /* Get sam policy and domain handles */ 863 864 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 865 &connect_pol); 866 867 if (!NT_STATUS_IS_OK(result)) { 868 goto done; 869 } 870 871 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 872 MAXIMUM_ALLOWED_ACCESS, 873 domain_sid, &domain_pol); 874 875 if (!NT_STATUS_IS_OK(result)) { 876 goto done; 877 } 878 879 /* Get handle on user */ 880 881 { 882 uint32 *user_rids, num_rids, *name_types; 883 uint32 flags = 0x000003e8; /* Unknown */ 884 885 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 886 flags, 1, &user, 887 &num_rids, &user_rids, 888 &name_types); 889 890 if (!NT_STATUS_IS_OK(result)) { 891 goto done; 892 } 893 894 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 895 MAXIMUM_ALLOWED_ACCESS, 896 user_rids[0], &user_pol); 897 898 if (!NT_STATUS_IS_OK(result)) { 899 goto done; 900 } 901 } 902 903 /* Set password on account */ 904 905 ZERO_STRUCT(ctr); 906 ZERO_STRUCT(p24); 907 908 encode_pw_buffer(pwbuf, new_password, STR_UNICODE); 909 910 init_sam_user_info24(&p24, (char *)pwbuf,24); 911 912 ctr.switch_value = 24; 913 ctr.info.id24 = &p24; 914 915 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, 916 &cli->user_session_key, &ctr); 917 918 if (!NT_STATUS_IS_OK(result)) { 919 goto done; 920 } 921 922 /* Display results */ 923 924 done: 925 return result; 926 927} 928 929/** 930 * Set a user's password on a remote RPC server 931 * 932 * @param argc Standard main() style argc 933 * @param argv Standard main() style argv. Initial components are already 934 * stripped 935 * 936 * @return A shell status integer (0 for success) 937 **/ 938 939static int rpc_user_password(int argc, const char **argv) 940{ 941 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals, 942 argc, argv); 943} 944 945/** 946 * List user's groups on a remote RPC server 947 * 948 * All parameters are provided by the run_rpc_command function, except for 949 * argc, argv which are passes through. 950 * 951 * @param domain_sid The domain sid acquired from the remote server 952 * @param cli A cli_state connected to the server. 953 * @param mem_ctx Talloc context, destoyed on completion of the function. 954 * @param argc Standard main() style argc 955 * @param argv Standard main() style argv. Initial components are already 956 * stripped 957 * 958 * @return Normal NTSTATUS return. 959 **/ 960 961static NTSTATUS 962rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name, 963 struct cli_state *cli, 964 TALLOC_CTX *mem_ctx, int argc, const char **argv) 965{ 966 POLICY_HND connect_pol, domain_pol, user_pol; 967 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 968 uint32 *rids, num_rids, *name_types, num_names; 969 uint32 flags = 0x000003e8; /* Unknown */ 970 int i; 971 char **names; 972 DOM_GID *user_gids; 973 974 if (argc < 1) { 975 d_printf("User must be specified\n"); 976 rpc_user_usage(argc, argv); 977 return NT_STATUS_OK; 978 } 979 /* Get sam policy handle */ 980 981 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 982 &connect_pol); 983 if (!NT_STATUS_IS_OK(result)) goto done; 984 985 /* Get domain policy handle */ 986 987 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 988 MAXIMUM_ALLOWED_ACCESS, 989 domain_sid, &domain_pol); 990 if (!NT_STATUS_IS_OK(result)) goto done; 991 992 /* Get handle on user */ 993 994 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 995 flags, 1, &argv[0], 996 &num_rids, &rids, &name_types); 997 998 if (!NT_STATUS_IS_OK(result)) goto done; 999 1000 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 1001 MAXIMUM_ALLOWED_ACCESS, 1002 rids[0], &user_pol); 1003 if (!NT_STATUS_IS_OK(result)) goto done; 1004 1005 result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol, 1006 &num_rids, &user_gids); 1007 1008 if (!NT_STATUS_IS_OK(result)) goto done; 1009 1010 /* Look up rids */ 1011 1012 if (num_rids) { 1013 rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids); 1014 1015 for (i = 0; i < num_rids; i++) 1016 rids[i] = user_gids[i].g_rid; 1017 1018 result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1019 num_rids, rids, 1020 &num_names, &names, &name_types); 1021 1022 if (!NT_STATUS_IS_OK(result)) { 1023 goto done; 1024 } 1025 1026 /* Display results */ 1027 1028 for (i = 0; i < num_names; i++) 1029 printf("%s\n", names[i]); 1030 } 1031 done: 1032 return result; 1033} 1034 1035/** 1036 * List a user's groups from a remote RPC server 1037 * 1038 * @param argc Standard main() style argc 1039 * @param argv Standard main() style argv. Initial components are already 1040 * stripped 1041 * 1042 * @return A shell status integer (0 for success) 1043 **/ 1044 1045static int rpc_user_info(int argc, const char **argv) 1046{ 1047 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals, 1048 argc, argv); 1049} 1050 1051/** 1052 * List users on a remote RPC server 1053 * 1054 * All parameters are provided by the run_rpc_command function, except for 1055 * argc, argv which are passes through. 1056 * 1057 * @param domain_sid The domain sid acquired from the remote server 1058 * @param cli A cli_state connected to the server. 1059 * @param mem_ctx Talloc context, destoyed on completion of the function. 1060 * @param argc Standard main() style argc 1061 * @param argv Standard main() style argv. Initial components are already 1062 * stripped 1063 * 1064 * @return Normal NTSTATUS return. 1065 **/ 1066 1067static NTSTATUS 1068rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name, 1069 struct cli_state *cli, 1070 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1071{ 1072 POLICY_HND connect_pol, domain_pol; 1073 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1074 uint32 start_idx=0, num_entries, i, loop_count = 0; 1075 SAM_DISPINFO_CTR ctr; 1076 SAM_DISPINFO_1 info1; 1077 1078 /* Get sam policy handle */ 1079 1080 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1081 &connect_pol); 1082 if (!NT_STATUS_IS_OK(result)) { 1083 goto done; 1084 } 1085 1086 /* Get domain policy handle */ 1087 1088 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1089 MAXIMUM_ALLOWED_ACCESS, 1090 domain_sid, &domain_pol); 1091 if (!NT_STATUS_IS_OK(result)) { 1092 goto done; 1093 } 1094 1095 /* Query domain users */ 1096 ZERO_STRUCT(ctr); 1097 ZERO_STRUCT(info1); 1098 ctr.sam.info1 = &info1; 1099 if (opt_long_list_entries) 1100 d_printf("\nUser name Comment"\ 1101 "\n-----------------------------\n"); 1102 do { 1103 fstring user, desc; 1104 uint32 max_entries, max_size; 1105 1106 get_query_dispinfo_params( 1107 loop_count, &max_entries, &max_size); 1108 1109 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol, 1110 &start_idx, 1, &num_entries, 1111 max_entries, max_size, &ctr); 1112 loop_count++; 1113 1114 for (i = 0; i < num_entries; i++) { 1115 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1); 1116 if (opt_long_list_entries) 1117 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1); 1118 1119 if (opt_long_list_entries) 1120 printf("%-21.21s %s\n", user, desc); 1121 else 1122 printf("%s\n", user); 1123 } 1124 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 1125 1126 done: 1127 return result; 1128} 1129 1130/** 1131 * 'net rpc user' entrypoint. 1132 * @param argc Standard main() style argc 1133 * @param argc Standard main() style argv. Initial components are already 1134 * stripped 1135 **/ 1136 1137int net_rpc_user(int argc, const char **argv) 1138{ 1139 struct functable func[] = { 1140 {"add", rpc_user_add}, 1141 {"info", rpc_user_info}, 1142 {"delete", rpc_user_delete}, 1143 {"password", rpc_user_password}, 1144 {"rename", rpc_user_rename}, 1145 {NULL, NULL} 1146 }; 1147 1148 if (argc == 0) { 1149 if (opt_long_list_entries) { 1150 } else { 1151 } 1152 return run_rpc_command(NULL,PI_SAMR, 0, 1153 rpc_user_list_internals, 1154 argc, argv); 1155 } 1156 1157 return net_run_function(argc, argv, func, rpc_user_usage); 1158} 1159 1160 1161/****************************************************************************/ 1162 1163/** 1164 * Basic usage function for 'net rpc group' 1165 * @param argc Standard main() style argc. 1166 * @param argv Standard main() style argv. Initial components are already 1167 * stripped. 1168 **/ 1169 1170static int rpc_group_usage(int argc, const char **argv) 1171{ 1172 return net_help_group(argc, argv); 1173} 1174 1175/** 1176 * Delete group on a remote RPC server 1177 * 1178 * All parameters are provided by the run_rpc_command function, except for 1179 * argc, argv which are passes through. 1180 * 1181 * @param domain_sid The domain sid acquired from the remote server 1182 * @param cli A cli_state connected to the server. 1183 * @param mem_ctx Talloc context, destoyed on completion of the function. 1184 * @param argc Standard main() style argc 1185 * @param argv Standard main() style argv. Initial components are already 1186 * stripped 1187 * 1188 * @return Normal NTSTATUS return. 1189 **/ 1190 1191static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid, 1192 const char *domain_name, 1193 struct cli_state *cli, 1194 TALLOC_CTX *mem_ctx, 1195 int argc, const char **argv) 1196{ 1197 POLICY_HND connect_pol, domain_pol, group_pol, user_pol; 1198 BOOL group_is_primary = False; 1199 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1200 1201 uint32 *group_rids, num_rids, *name_types, num_members, 1202 *group_attrs, group_rid; 1203 uint32 flags = 0x000003e8; /* Unknown */ 1204 /* char **names; */ 1205 int i; 1206 /* DOM_GID *user_gids; */ 1207 SAM_USERINFO_CTR *user_ctr; 1208 fstring temp; 1209 1210 if (argc < 1) { 1211 d_printf("specify group\n"); 1212 rpc_group_usage(argc,argv); 1213 return NT_STATUS_OK; /* ok? */ 1214 } 1215 1216 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1217 &connect_pol); 1218 1219 if (!NT_STATUS_IS_OK(result)) { 1220 d_printf("Request samr_connect failed\n"); 1221 goto done; 1222 } 1223 1224 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1225 MAXIMUM_ALLOWED_ACCESS, 1226 domain_sid, &domain_pol); 1227 1228 if (!NT_STATUS_IS_OK(result)) { 1229 d_printf("Request open_domain failed\n"); 1230 goto done; 1231 } 1232 1233 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1234 flags, 1, &argv[0], 1235 &num_rids, &group_rids, 1236 &name_types); 1237 1238 if (!NT_STATUS_IS_OK(result)) { 1239 d_printf("Lookup of '%s' failed\n",argv[0]); 1240 goto done; 1241 } 1242 1243 switch (name_types[0]) 1244 { 1245 case SID_NAME_DOM_GRP: 1246 result = cli_samr_open_group(cli, mem_ctx, &domain_pol, 1247 MAXIMUM_ALLOWED_ACCESS, 1248 group_rids[0], &group_pol); 1249 if (!NT_STATUS_IS_OK(result)) { 1250 d_printf("Request open_group failed"); 1251 goto done; 1252 } 1253 1254 group_rid = group_rids[0]; 1255 1256 result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol, 1257 &num_members, &group_rids, 1258 &group_attrs); 1259 1260 if (!NT_STATUS_IS_OK(result)) { 1261 d_printf("Unable to query group members of %s",argv[0]); 1262 goto done; 1263 } 1264 1265 if (opt_verbose) { 1266 d_printf("Domain Group %s (rid: %d) has %d members\n", 1267 argv[0],group_rid,num_members); 1268 } 1269 1270 /* Check if group is anyone's primary group */ 1271 for (i = 0; i < num_members; i++) 1272 { 1273 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 1274 MAXIMUM_ALLOWED_ACCESS, 1275 group_rids[i], &user_pol); 1276 1277 if (!NT_STATUS_IS_OK(result)) { 1278 d_printf("Unable to open group member %d\n",group_rids[i]); 1279 goto done; 1280 } 1281 1282 ZERO_STRUCT(user_ctr); 1283 1284 result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, 1285 21, &user_ctr); 1286 1287 if (!NT_STATUS_IS_OK(result)) { 1288 d_printf("Unable to lookup userinfo for group member %d\n",group_rids[i]); 1289 goto done; 1290 } 1291 1292 if (user_ctr->info.id21->group_rid == group_rid) { 1293 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name, 1294 sizeof(temp)-1); 1295 if (opt_verbose) 1296 d_printf("Group is primary group of %s\n",temp); 1297 group_is_primary = True; 1298 } 1299 1300 cli_samr_close(cli, mem_ctx, &user_pol); 1301 } 1302 1303 if (group_is_primary) { 1304 d_printf("Unable to delete group because some of it's " 1305 "members have it as primary group\n"); 1306 result = NT_STATUS_MEMBERS_PRIMARY_GROUP; 1307 goto done; 1308 } 1309 1310 /* remove all group members */ 1311 for (i = 0; i < num_members; i++) 1312 { 1313 if (opt_verbose) 1314 d_printf("Remove group member %d...",group_rids[i]); 1315 result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, group_rids[i]); 1316 1317 if (NT_STATUS_IS_OK(result)) { 1318 if (opt_verbose) 1319 d_printf("ok\n"); 1320 } else { 1321 if (opt_verbose) 1322 d_printf("failed\n"); 1323 goto done; 1324 } 1325 } 1326 1327 result = cli_samr_delete_dom_group(cli, mem_ctx, &group_pol); 1328 1329 break; 1330 /* removing a local group is easier... */ 1331 case SID_NAME_ALIAS: 1332 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, 1333 MAXIMUM_ALLOWED_ACCESS, 1334 group_rids[0], &group_pol); 1335 1336 if (!NT_STATUS_IS_OK(result)) { 1337 d_printf("Request open_alias failed\n"); 1338 goto done; 1339 } 1340 1341 result = cli_samr_delete_dom_alias(cli, mem_ctx, &group_pol); 1342 break; 1343 default: 1344 d_printf("%s is of type %s. This command is only for deleting local or global groups\n", 1345 argv[0],sid_type_lookup(name_types[0])); 1346 result = NT_STATUS_UNSUCCESSFUL; 1347 goto done; 1348 } 1349 1350 1351 if (NT_STATUS_IS_OK(result)) { 1352 if (opt_verbose) 1353 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]); 1354 } else { 1355 d_printf("Deleting of %s failed: %s\n",argv[0], 1356 get_friendly_nt_error_msg(result)); 1357 } 1358 1359 done: 1360 return result; 1361 1362} 1363 1364static int rpc_group_delete(int argc, const char **argv) 1365{ 1366 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals, 1367 argc,argv); 1368} 1369 1370static NTSTATUS 1371rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name, 1372 struct cli_state *cli, 1373 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1374{ 1375 POLICY_HND connect_pol, domain_pol, group_pol; 1376 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1377 GROUP_INFO_CTR group_info; 1378 1379 if (argc != 1) { 1380 d_printf("Group name must be specified\n"); 1381 rpc_group_usage(argc, argv); 1382 return NT_STATUS_OK; 1383 } 1384 1385 /* Get sam policy handle */ 1386 1387 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1388 &connect_pol); 1389 if (!NT_STATUS_IS_OK(result)) goto done; 1390 1391 /* Get domain policy handle */ 1392 1393 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1394 MAXIMUM_ALLOWED_ACCESS, 1395 domain_sid, &domain_pol); 1396 if (!NT_STATUS_IS_OK(result)) goto done; 1397 1398 /* Create the group */ 1399 1400 result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol, 1401 argv[0], MAXIMUM_ALLOWED_ACCESS, 1402 &group_pol); 1403 if (!NT_STATUS_IS_OK(result)) goto done; 1404 1405 if (strlen(opt_comment) == 0) goto done; 1406 1407 /* We've got a comment to set */ 1408 1409 group_info.switch_value1 = 4; 1410 init_samr_group_info4(&group_info.group.info4, opt_comment); 1411 1412 result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &group_info); 1413 if (!NT_STATUS_IS_OK(result)) goto done; 1414 1415 done: 1416 if (NT_STATUS_IS_OK(result)) 1417 DEBUG(5, ("add group succeeded\n")); 1418 else 1419 d_printf("add group failed: %s\n", nt_errstr(result)); 1420 1421 return result; 1422} 1423 1424static NTSTATUS 1425rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name, 1426 struct cli_state *cli, 1427 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1428{ 1429 POLICY_HND connect_pol, domain_pol, alias_pol; 1430 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1431 ALIAS_INFO_CTR alias_info; 1432 1433 if (argc != 1) { 1434 d_printf("Alias name must be specified\n"); 1435 rpc_group_usage(argc, argv); 1436 return NT_STATUS_OK; 1437 } 1438 1439 /* Get sam policy handle */ 1440 1441 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1442 &connect_pol); 1443 if (!NT_STATUS_IS_OK(result)) goto done; 1444 1445 /* Get domain policy handle */ 1446 1447 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1448 MAXIMUM_ALLOWED_ACCESS, 1449 domain_sid, &domain_pol); 1450 if (!NT_STATUS_IS_OK(result)) goto done; 1451 1452 /* Create the group */ 1453 1454 result = cli_samr_create_dom_alias(cli, mem_ctx, &domain_pol, 1455 argv[0], &alias_pol); 1456 if (!NT_STATUS_IS_OK(result)) goto done; 1457 1458 if (strlen(opt_comment) == 0) goto done; 1459 1460 /* We've got a comment to set */ 1461 1462 alias_info.switch_value1 = 3; 1463 alias_info.switch_value2 = 3; 1464 init_samr_alias_info3(&alias_info.alias.info3, opt_comment); 1465 1466 result = cli_samr_set_aliasinfo(cli, mem_ctx, &alias_pol, &alias_info); 1467 if (!NT_STATUS_IS_OK(result)) goto done; 1468 1469 done: 1470 if (NT_STATUS_IS_OK(result)) 1471 DEBUG(5, ("add alias succeeded\n")); 1472 else 1473 d_printf("add alias failed: %s\n", nt_errstr(result)); 1474 1475 return result; 1476} 1477 1478static int rpc_group_add(int argc, const char **argv) 1479{ 1480 if (opt_localgroup) 1481 return run_rpc_command(NULL, PI_SAMR, 0, 1482 rpc_alias_add_internals, 1483 argc, argv); 1484 1485 return run_rpc_command(NULL, PI_SAMR, 0, 1486 rpc_group_add_internals, 1487 argc, argv); 1488} 1489 1490static NTSTATUS 1491get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name, 1492 DOM_SID *sid, enum SID_NAME_USE *type) 1493{ 1494 int current_pipe = cli->pipe_idx; 1495 1496 DOM_SID *sids = NULL; 1497 uint32 *types = NULL; 1498 POLICY_HND lsa_pol; 1499 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1500 1501 if (current_pipe != PI_LSARPC) { 1502 1503 if (current_pipe != -1) 1504 cli_nt_session_close(cli); 1505 1506 if (!cli_nt_session_open(cli, PI_LSARPC)) 1507 goto done; 1508 } 1509 1510 result = cli_lsa_open_policy(cli, mem_ctx, False, 1511 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); 1512 1513 if (!NT_STATUS_IS_OK(result)) 1514 goto done; 1515 1516 result = cli_lsa_lookup_names(cli, mem_ctx, &lsa_pol, 1, 1517 &name, &sids, &types); 1518 1519 if (NT_STATUS_IS_OK(result)) { 1520 sid_copy(sid, &sids[0]); 1521 *type = types[0]; 1522 } 1523 1524 cli_lsa_close(cli, mem_ctx, &lsa_pol); 1525 1526 done: 1527 if (current_pipe != PI_LSARPC) { 1528 cli_nt_session_close(cli); 1529 if (current_pipe != -1) 1530 cli_nt_session_open(cli, current_pipe); 1531 } 1532 1533 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) { 1534 1535 /* Try as S-1-5-whatever */ 1536 1537 DOM_SID tmp_sid; 1538 1539 if (string_to_sid(&tmp_sid, name)) { 1540 sid_copy(sid, &tmp_sid); 1541 *type = SID_NAME_UNKNOWN; 1542 result = NT_STATUS_OK; 1543 } 1544 } 1545 1546 return result; 1547} 1548 1549static NTSTATUS 1550rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 1551 const DOM_SID *group_sid, const char *member) 1552{ 1553 POLICY_HND connect_pol, domain_pol; 1554 NTSTATUS result; 1555 uint32 group_rid; 1556 POLICY_HND group_pol; 1557 1558 uint32 num_rids; 1559 uint32 *rids = NULL; 1560 uint32 *rid_types = NULL; 1561 1562 DOM_SID sid; 1563 1564 sid_copy(&sid, group_sid); 1565 1566 if (!sid_split_rid(&sid, &group_rid)) 1567 return NT_STATUS_UNSUCCESSFUL; 1568 1569 /* Get sam policy handle */ 1570 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1571 &connect_pol); 1572 if (!NT_STATUS_IS_OK(result)) 1573 return result; 1574 1575 /* Get domain policy handle */ 1576 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1577 MAXIMUM_ALLOWED_ACCESS, 1578 &sid, &domain_pol); 1579 if (!NT_STATUS_IS_OK(result)) 1580 return result; 1581 1582 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, 1583 1, &member, 1584 &num_rids, &rids, &rid_types); 1585 1586 if (!NT_STATUS_IS_OK(result)) { 1587 d_printf("Could not lookup up group member %s\n", member); 1588 goto done; 1589 } 1590 1591 result = cli_samr_open_group(cli, mem_ctx, &domain_pol, 1592 MAXIMUM_ALLOWED_ACCESS, 1593 group_rid, &group_pol); 1594 1595 if (!NT_STATUS_IS_OK(result)) 1596 goto done; 1597 1598 result = cli_samr_add_groupmem(cli, mem_ctx, &group_pol, rids[0]); 1599 1600 done: 1601 cli_samr_close(cli, mem_ctx, &connect_pol); 1602 return result; 1603} 1604 1605static NTSTATUS 1606rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 1607 const DOM_SID *alias_sid, const char *member) 1608{ 1609 POLICY_HND connect_pol, domain_pol; 1610 NTSTATUS result; 1611 uint32 alias_rid; 1612 POLICY_HND alias_pol; 1613 1614 DOM_SID member_sid; 1615 enum SID_NAME_USE member_type; 1616 1617 DOM_SID sid; 1618 1619 sid_copy(&sid, alias_sid); 1620 1621 if (!sid_split_rid(&sid, &alias_rid)) 1622 return NT_STATUS_UNSUCCESSFUL; 1623 1624 result = get_sid_from_name(cli, mem_ctx, member, 1625 &member_sid, &member_type); 1626 1627 if (!NT_STATUS_IS_OK(result)) { 1628 d_printf("Could not lookup up group member %s\n", member); 1629 return result; 1630 } 1631 1632 /* Get sam policy handle */ 1633 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1634 &connect_pol); 1635 if (!NT_STATUS_IS_OK(result)) { 1636 goto done; 1637 } 1638 1639 /* Get domain policy handle */ 1640 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1641 MAXIMUM_ALLOWED_ACCESS, 1642 &sid, &domain_pol); 1643 if (!NT_STATUS_IS_OK(result)) { 1644 goto done; 1645 } 1646 1647 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, 1648 MAXIMUM_ALLOWED_ACCESS, 1649 alias_rid, &alias_pol); 1650 1651 if (!NT_STATUS_IS_OK(result)) 1652 return result; 1653 1654 result = cli_samr_add_aliasmem(cli, mem_ctx, &alias_pol, &member_sid); 1655 1656 if (!NT_STATUS_IS_OK(result)) 1657 return result; 1658 1659 done: 1660 cli_samr_close(cli, mem_ctx, &connect_pol); 1661 return result; 1662} 1663 1664static NTSTATUS 1665rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name, 1666 struct cli_state *cli, 1667 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1668{ 1669 DOM_SID group_sid; 1670 enum SID_NAME_USE group_type; 1671 1672 if (argc != 2) { 1673 d_printf("Usage: 'net rpc group addmem <group> <member>\n"); 1674 return NT_STATUS_UNSUCCESSFUL; 1675 } 1676 1677 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0], 1678 &group_sid, &group_type))) { 1679 d_printf("Could not lookup group name %s\n", argv[0]); 1680 return NT_STATUS_UNSUCCESSFUL; 1681 } 1682 1683 if (group_type == SID_NAME_DOM_GRP) { 1684 NTSTATUS result = rpc_add_groupmem(cli, mem_ctx, 1685 &group_sid, argv[1]); 1686 1687 if (!NT_STATUS_IS_OK(result)) { 1688 d_printf("Could not add %s to %s: %s\n", 1689 argv[1], argv[0], nt_errstr(result)); 1690 } 1691 return result; 1692 } 1693 1694 if (group_type == SID_NAME_ALIAS) { 1695 NTSTATUS result = rpc_add_aliasmem(cli, mem_ctx, 1696 &group_sid, argv[1]); 1697 1698 if (!NT_STATUS_IS_OK(result)) { 1699 d_printf("Could not add %s to %s: %s\n", 1700 argv[1], argv[0], nt_errstr(result)); 1701 } 1702 return result; 1703 } 1704 1705 d_printf("Can only add members to global or local groups which " 1706 "%s is not\n", argv[0]); 1707 1708 return NT_STATUS_UNSUCCESSFUL; 1709} 1710 1711static int rpc_group_addmem(int argc, const char **argv) 1712{ 1713 return run_rpc_command(NULL, PI_SAMR, 0, 1714 rpc_group_addmem_internals, 1715 argc, argv); 1716} 1717 1718static NTSTATUS 1719rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 1720 const DOM_SID *group_sid, const char *member) 1721{ 1722 POLICY_HND connect_pol, domain_pol; 1723 NTSTATUS result; 1724 uint32 group_rid; 1725 POLICY_HND group_pol; 1726 1727 uint32 num_rids; 1728 uint32 *rids = NULL; 1729 uint32 *rid_types = NULL; 1730 1731 DOM_SID sid; 1732 1733 sid_copy(&sid, group_sid); 1734 1735 if (!sid_split_rid(&sid, &group_rid)) 1736 return NT_STATUS_UNSUCCESSFUL; 1737 1738 /* Get sam policy handle */ 1739 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1740 &connect_pol); 1741 if (!NT_STATUS_IS_OK(result)) 1742 return result; 1743 1744 /* Get domain policy handle */ 1745 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1746 MAXIMUM_ALLOWED_ACCESS, 1747 &sid, &domain_pol); 1748 if (!NT_STATUS_IS_OK(result)) 1749 return result; 1750 1751 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, 1752 1, &member, 1753 &num_rids, &rids, &rid_types); 1754 1755 if (!NT_STATUS_IS_OK(result)) { 1756 d_printf("Could not lookup up group member %s\n", member); 1757 goto done; 1758 } 1759 1760 result = cli_samr_open_group(cli, mem_ctx, &domain_pol, 1761 MAXIMUM_ALLOWED_ACCESS, 1762 group_rid, &group_pol); 1763 1764 if (!NT_STATUS_IS_OK(result)) 1765 goto done; 1766 1767 result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, rids[0]); 1768 1769 done: 1770 cli_samr_close(cli, mem_ctx, &connect_pol); 1771 return result; 1772} 1773 1774static NTSTATUS 1775rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 1776 const DOM_SID *alias_sid, const char *member) 1777{ 1778 POLICY_HND connect_pol, domain_pol; 1779 NTSTATUS result; 1780 uint32 alias_rid; 1781 POLICY_HND alias_pol; 1782 1783 DOM_SID member_sid; 1784 enum SID_NAME_USE member_type; 1785 1786 DOM_SID sid; 1787 1788 sid_copy(&sid, alias_sid); 1789 1790 if (!sid_split_rid(&sid, &alias_rid)) 1791 return NT_STATUS_UNSUCCESSFUL; 1792 1793 result = get_sid_from_name(cli, mem_ctx, member, 1794 &member_sid, &member_type); 1795 1796 if (!NT_STATUS_IS_OK(result)) { 1797 d_printf("Could not lookup up group member %s\n", member); 1798 return result; 1799 } 1800 1801 /* Get sam policy handle */ 1802 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1803 &connect_pol); 1804 if (!NT_STATUS_IS_OK(result)) { 1805 goto done; 1806 } 1807 1808 /* Get domain policy handle */ 1809 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1810 MAXIMUM_ALLOWED_ACCESS, 1811 &sid, &domain_pol); 1812 if (!NT_STATUS_IS_OK(result)) { 1813 goto done; 1814 } 1815 1816 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, 1817 MAXIMUM_ALLOWED_ACCESS, 1818 alias_rid, &alias_pol); 1819 1820 if (!NT_STATUS_IS_OK(result)) 1821 return result; 1822 1823 result = cli_samr_del_aliasmem(cli, mem_ctx, &alias_pol, &member_sid); 1824 1825 if (!NT_STATUS_IS_OK(result)) 1826 return result; 1827 1828 done: 1829 cli_samr_close(cli, mem_ctx, &connect_pol); 1830 return result; 1831} 1832 1833static NTSTATUS 1834rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name, 1835 struct cli_state *cli, 1836 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1837{ 1838 DOM_SID group_sid; 1839 enum SID_NAME_USE group_type; 1840 1841 if (argc != 2) { 1842 d_printf("Usage: 'net rpc group delmem <group> <member>\n"); 1843 return NT_STATUS_UNSUCCESSFUL; 1844 } 1845 1846 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0], 1847 &group_sid, &group_type))) { 1848 d_printf("Could not lookup group name %s\n", argv[0]); 1849 return NT_STATUS_UNSUCCESSFUL; 1850 } 1851 1852 if (group_type == SID_NAME_DOM_GRP) { 1853 NTSTATUS result = rpc_del_groupmem(cli, mem_ctx, 1854 &group_sid, argv[1]); 1855 1856 if (!NT_STATUS_IS_OK(result)) { 1857 d_printf("Could not del %s from %s: %s\n", 1858 argv[1], argv[0], nt_errstr(result)); 1859 } 1860 return result; 1861 } 1862 1863 if (group_type == SID_NAME_ALIAS) { 1864 NTSTATUS result = rpc_del_aliasmem(cli, mem_ctx, 1865 &group_sid, argv[1]); 1866 1867 if (!NT_STATUS_IS_OK(result)) { 1868 d_printf("Could not del %s from %s: %s\n", 1869 argv[1], argv[0], nt_errstr(result)); 1870 } 1871 return result; 1872 } 1873 1874 d_printf("Can only delete members from global or local groups which " 1875 "%s is not\n", argv[0]); 1876 1877 return NT_STATUS_UNSUCCESSFUL; 1878} 1879 1880static int rpc_group_delmem(int argc, const char **argv) 1881{ 1882 return run_rpc_command(NULL, PI_SAMR, 0, 1883 rpc_group_delmem_internals, 1884 argc, argv); 1885} 1886 1887/** 1888 * List groups on a remote RPC server 1889 * 1890 * All parameters are provided by the run_rpc_command function, except for 1891 * argc, argv which are passes through. 1892 * 1893 * @param domain_sid The domain sid acquired from the remote server 1894 * @param cli A cli_state connected to the server. 1895 * @param mem_ctx Talloc context, destoyed on completion of the function. 1896 * @param argc Standard main() style argc 1897 * @param argv Standard main() style argv. Initial components are already 1898 * stripped 1899 * 1900 * @return Normal NTSTATUS return. 1901 **/ 1902 1903static NTSTATUS 1904rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, 1905 struct cli_state *cli, 1906 TALLOC_CTX *mem_ctx, int argc, const char **argv) 1907{ 1908 POLICY_HND connect_pol, domain_pol; 1909 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1910 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0; 1911 struct acct_info *groups; 1912 DOM_SID global_sid_Builtin; 1913 BOOL global = False; 1914 BOOL local = False; 1915 BOOL builtin = False; 1916 1917 if (argc == 0) { 1918 global = True; 1919 local = True; 1920 builtin = True; 1921 } 1922 1923 for (i=0; i<argc; i++) { 1924 if (strequal(argv[i], "global")) 1925 global = True; 1926 1927 if (strequal(argv[i], "local")) 1928 local = True; 1929 1930 if (strequal(argv[i], "builtin")) 1931 builtin = True; 1932 } 1933 1934 string_to_sid(&global_sid_Builtin, "S-1-5-32"); 1935 1936 /* Get sam policy handle */ 1937 1938 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 1939 &connect_pol); 1940 if (!NT_STATUS_IS_OK(result)) { 1941 goto done; 1942 } 1943 1944 /* Get domain policy handle */ 1945 1946 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 1947 MAXIMUM_ALLOWED_ACCESS, 1948 domain_sid, &domain_pol); 1949 if (!NT_STATUS_IS_OK(result)) { 1950 goto done; 1951 } 1952 1953 /* Query domain groups */ 1954 if (opt_long_list_entries) 1955 d_printf("\nGroup name Comment"\ 1956 "\n-----------------------------\n"); 1957 do { 1958 SAM_DISPINFO_CTR ctr; 1959 SAM_DISPINFO_3 info3; 1960 uint32 max_size; 1961 1962 ZERO_STRUCT(ctr); 1963 ZERO_STRUCT(info3); 1964 ctr.sam.info3 = &info3; 1965 1966 if (!global) break; 1967 1968 get_query_dispinfo_params( 1969 loop_count, &max_entries, &max_size); 1970 1971 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol, 1972 &start_idx, 3, &num_entries, 1973 max_entries, max_size, &ctr); 1974 1975 if (!NT_STATUS_IS_OK(result) && 1976 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 1977 break; 1978 1979 for (i = 0; i < num_entries; i++) { 1980 1981 fstring group, desc; 1982 1983 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1); 1984 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1); 1985 1986 if (opt_long_list_entries) 1987 printf("%-21.21s %-50.50s\n", 1988 group, desc); 1989 else 1990 printf("%s\n", group); 1991 } 1992 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 1993 /* query domain aliases */ 1994 start_idx = 0; 1995 do { 1996 if (!local) break; 1997 1998 /* The max_size field in cli_samr_enum_als_groups is more like 1999 * an account_control field with indiviual bits what to 2000 * retrieve. Set this to 0xffff as NT4 usrmgr.exe does to get 2001 * everything. I'm too lazy (sorry) to get this through to 2002 * rpc_parse/ etc. Volker */ 2003 2004 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, 2005 &start_idx, 0xffff, 2006 &groups, &num_entries); 2007 2008 if (!NT_STATUS_IS_OK(result) && 2009 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 2010 break; 2011 2012 for (i = 0; i < num_entries; i++) { 2013 2014 char *description = NULL; 2015 2016 if (opt_long_list_entries) { 2017 2018 POLICY_HND alias_pol; 2019 ALIAS_INFO_CTR ctr; 2020 2021 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx, 2022 &domain_pol, 2023 0x8, 2024 groups[i].rid, 2025 &alias_pol))) && 2026 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx, 2027 &alias_pol, 3, 2028 &ctr))) && 2029 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx, 2030 &alias_pol)))) { 2031 description = unistr2_tdup(mem_ctx, 2032 &ctr.alias.info3.uni_acct_desc); 2033 } 2034 } 2035 2036 if (description != NULL) { 2037 printf("%-21.21s %-50.50s\n", 2038 groups[i].acct_name, 2039 description); 2040 } else { 2041 printf("%s\n", groups[i].acct_name); 2042 } 2043 } 2044 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 2045 cli_samr_close(cli, mem_ctx, &domain_pol); 2046 /* Get builtin policy handle */ 2047 2048 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 2049 MAXIMUM_ALLOWED_ACCESS, 2050 &global_sid_Builtin, &domain_pol); 2051 if (!NT_STATUS_IS_OK(result)) { 2052 goto done; 2053 } 2054 /* query builtin aliases */ 2055 start_idx = 0; 2056 do { 2057 if (!builtin) break; 2058 2059 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, 2060 &start_idx, max_entries, 2061 &groups, &num_entries); 2062 2063 if (!NT_STATUS_IS_OK(result) && 2064 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 2065 break; 2066 2067 for (i = 0; i < num_entries; i++) { 2068 2069 char *description = NULL; 2070 2071 if (opt_long_list_entries) { 2072 2073 POLICY_HND alias_pol; 2074 ALIAS_INFO_CTR ctr; 2075 2076 if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx, 2077 &domain_pol, 2078 0x8, 2079 groups[i].rid, 2080 &alias_pol))) && 2081 (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx, 2082 &alias_pol, 3, 2083 &ctr))) && 2084 (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx, 2085 &alias_pol)))) { 2086 description = unistr2_tdup(mem_ctx, 2087 &ctr.alias.info3.uni_acct_desc); 2088 } 2089 } 2090 2091 if (description != NULL) { 2092 printf("%-21.21s %-50.50s\n", 2093 groups[i].acct_name, 2094 description); 2095 } else { 2096 printf("%s\n", groups[i].acct_name); 2097 } 2098 } 2099 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 2100 2101 done: 2102 return result; 2103} 2104 2105static int rpc_group_list(int argc, const char **argv) 2106{ 2107 return run_rpc_command(NULL, PI_SAMR, 0, 2108 rpc_group_list_internals, 2109 argc, argv); 2110} 2111 2112static NTSTATUS 2113rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx, 2114 const char *domain_name, const DOM_SID *domain_sid, 2115 POLICY_HND *domain_pol, uint32 rid) 2116{ 2117 NTSTATUS result; 2118 POLICY_HND group_pol; 2119 uint32 num_members, *group_rids, *group_attrs; 2120 uint32 num_names; 2121 char **names; 2122 uint32 *name_types; 2123 int i; 2124 2125 fstring sid_str; 2126 sid_to_string(sid_str, domain_sid); 2127 2128 result = cli_samr_open_group(cli, mem_ctx, domain_pol, 2129 MAXIMUM_ALLOWED_ACCESS, 2130 rid, &group_pol); 2131 2132 if (!NT_STATUS_IS_OK(result)) 2133 return result; 2134 2135 result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol, 2136 &num_members, &group_rids, 2137 &group_attrs); 2138 2139 if (!NT_STATUS_IS_OK(result)) 2140 return result; 2141 2142 while (num_members > 0) { 2143 int this_time = 512; 2144 2145 if (num_members < this_time) 2146 this_time = num_members; 2147 2148 result = cli_samr_lookup_rids(cli, mem_ctx, domain_pol, 2149 this_time, group_rids, 2150 &num_names, &names, &name_types); 2151 2152 if (!NT_STATUS_IS_OK(result)) 2153 return result; 2154 2155 /* We only have users as members, but make the output 2156 the same as the output of alias members */ 2157 2158 for (i = 0; i < this_time; i++) { 2159 2160 if (opt_long_list_entries) { 2161 printf("%s-%d %s\\%s %d\n", sid_str, 2162 group_rids[i], domain_name, names[i], 2163 SID_NAME_USER); 2164 } else { 2165 printf("%s\\%s\n", domain_name, names[i]); 2166 } 2167 } 2168 2169 num_members -= this_time; 2170 group_rids += 512; 2171 } 2172 2173 return NT_STATUS_OK; 2174} 2175 2176static NTSTATUS 2177rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx, 2178 POLICY_HND *domain_pol, uint32 rid) 2179{ 2180 NTSTATUS result; 2181 POLICY_HND alias_pol, lsa_pol; 2182 uint32 num_members; 2183 DOM_SID *alias_sids; 2184 char **domains; 2185 char **names; 2186 uint32 *types; 2187 int i; 2188 2189 result = cli_samr_open_alias(cli, mem_ctx, domain_pol, 2190 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol); 2191 2192 if (!NT_STATUS_IS_OK(result)) 2193 return result; 2194 2195 result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol, 2196 &num_members, &alias_sids); 2197 2198 if (!NT_STATUS_IS_OK(result)) { 2199 d_printf("Couldn't list alias members\n"); 2200 return result; 2201 } 2202 2203 if (num_members == 0) { 2204 return NT_STATUS_OK; 2205 } 2206 2207 cli_nt_session_close(cli); 2208 2209 if (!cli_nt_session_open(cli, PI_LSARPC)) { 2210 d_printf("Couldn't open LSA pipe\n"); 2211 return result; 2212 } 2213 2214 result = cli_lsa_open_policy(cli, mem_ctx, True, 2215 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); 2216 2217 if (!NT_STATUS_IS_OK(result)) { 2218 d_printf("Couldn't open LSA policy handle\n"); 2219 return result; 2220 } 2221 2222 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, num_members, 2223 alias_sids, 2224 &domains, &names, &types); 2225 2226 if (!NT_STATUS_IS_OK(result) && 2227 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 2228 d_printf("Couldn't lookup SIDs\n"); 2229 return result; 2230 } 2231 2232 for (i = 0; i < num_members; i++) { 2233 fstring sid_str; 2234 sid_to_string(sid_str, &alias_sids[i]); 2235 2236 if (opt_long_list_entries) { 2237 printf("%s %s\\%s %d\n", sid_str, 2238 domains[i] ? domains[i] : "*unknown*", 2239 names[i] ? names[i] : "*unknown*", types[i]); 2240 } else { 2241 if (domains[i]) 2242 printf("%s\\%s\n", domains[i], names[i]); 2243 else 2244 printf("%s\n", sid_str); 2245 } 2246 } 2247 2248 return NT_STATUS_OK; 2249} 2250 2251static NTSTATUS 2252rpc_group_members_internals(const DOM_SID *domain_sid, 2253 const char *domain_name, 2254 struct cli_state *cli, 2255 TALLOC_CTX *mem_ctx, int argc, const char **argv) 2256{ 2257 NTSTATUS result; 2258 POLICY_HND connect_pol, domain_pol; 2259 uint32 num_rids, *rids, *rid_types; 2260 2261 /* Get sam policy handle */ 2262 2263 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 2264 &connect_pol); 2265 2266 if (!NT_STATUS_IS_OK(result)) 2267 return result; 2268 2269 /* Get domain policy handle */ 2270 2271 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 2272 MAXIMUM_ALLOWED_ACCESS, 2273 domain_sid, &domain_pol); 2274 2275 if (!NT_STATUS_IS_OK(result)) 2276 return result; 2277 2278 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, 2279 1, argv, &num_rids, &rids, &rid_types); 2280 2281 if (!NT_STATUS_IS_OK(result)) { 2282 2283 /* Ok, did not find it in the global sam, try with builtin */ 2284 2285 DOM_SID sid_Builtin; 2286 2287 cli_samr_close(cli, mem_ctx, &domain_pol); 2288 2289 string_to_sid(&sid_Builtin, "S-1-5-32"); 2290 2291 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 2292 MAXIMUM_ALLOWED_ACCESS, 2293 &sid_Builtin, &domain_pol); 2294 2295 if (!NT_STATUS_IS_OK(result)) { 2296 d_printf("Couldn't find group %s\n", argv[0]); 2297 return result; 2298 } 2299 2300 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, 2301 1, argv, &num_rids, 2302 &rids, &rid_types); 2303 2304 if (!NT_STATUS_IS_OK(result)) { 2305 d_printf("Couldn't find group %s\n", argv[0]); 2306 return result; 2307 } 2308 } 2309 2310 if (num_rids != 1) { 2311 d_printf("Couldn't find group %s\n", argv[0]); 2312 return result; 2313 } 2314 2315 if (rid_types[0] == SID_NAME_DOM_GRP) { 2316 return rpc_list_group_members(cli, mem_ctx, domain_name, 2317 domain_sid, &domain_pol, 2318 rids[0]); 2319 } 2320 2321 if (rid_types[0] == SID_NAME_ALIAS) { 2322 return rpc_list_alias_members(cli, mem_ctx, &domain_pol, 2323 rids[0]); 2324 } 2325 2326 return NT_STATUS_NO_SUCH_GROUP; 2327} 2328 2329static int rpc_group_members(int argc, const char **argv) 2330{ 2331 if (argc != 1) { 2332 return rpc_group_usage(argc, argv); 2333 } 2334 2335 return run_rpc_command(NULL, PI_SAMR, 0, 2336 rpc_group_members_internals, 2337 argc, argv); 2338} 2339 2340static NTSTATUS 2341rpc_group_rename_internals(const DOM_SID *domain_sid, 2342 const char *domain_name, 2343 struct cli_state *cli, 2344 TALLOC_CTX *mem_ctx, int argc, const char **argv) 2345{ 2346 NTSTATUS result; 2347 POLICY_HND connect_pol, domain_pol, group_pol; 2348 uint32 num_rids, *rids, *rid_types; 2349 GROUP_INFO_CTR ctr; 2350 2351 if (argc != 2) { 2352 d_printf("Usage: 'net rpc group rename group newname'\n"); 2353 return NT_STATUS_UNSUCCESSFUL; 2354 } 2355 2356 /* Get sam policy handle */ 2357 2358 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 2359 &connect_pol); 2360 2361 if (!NT_STATUS_IS_OK(result)) 2362 return result; 2363 2364 /* Get domain policy handle */ 2365 2366 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 2367 MAXIMUM_ALLOWED_ACCESS, 2368 domain_sid, &domain_pol); 2369 2370 if (!NT_STATUS_IS_OK(result)) 2371 return result; 2372 2373 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000, 2374 1, argv, &num_rids, &rids, &rid_types); 2375 2376 if (num_rids != 1) { 2377 d_printf("Couldn't find group %s\n", argv[0]); 2378 return result; 2379 } 2380 2381 if (rid_types[0] != SID_NAME_DOM_GRP) { 2382 d_printf("Can only rename domain groups\n"); 2383 return NT_STATUS_UNSUCCESSFUL; 2384 } 2385 2386 result = cli_samr_open_group(cli, mem_ctx, &domain_pol, 2387 MAXIMUM_ALLOWED_ACCESS, 2388 rids[0], &group_pol); 2389 2390 if (!NT_STATUS_IS_OK(result)) 2391 return result; 2392 2393 ZERO_STRUCT(ctr); 2394 2395 ctr.switch_value1 = 2; 2396 init_samr_group_info2(&ctr.group.info2, argv[1]); 2397 2398 result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &ctr); 2399 2400 if (!NT_STATUS_IS_OK(result)) 2401 return result; 2402 2403 return NT_STATUS_NO_SUCH_GROUP; 2404} 2405 2406static int rpc_group_rename(int argc, const char **argv) 2407{ 2408 if (argc != 2) { 2409 return rpc_group_usage(argc, argv); 2410 } 2411 2412 return run_rpc_command(NULL, PI_SAMR, 0, 2413 rpc_group_rename_internals, 2414 argc, argv); 2415} 2416 2417/** 2418 * 'net rpc group' entrypoint. 2419 * @param argc Standard main() style argc 2420 * @param argc Standard main() style argv. Initial components are already 2421 * stripped 2422 **/ 2423 2424int net_rpc_group(int argc, const char **argv) 2425{ 2426 struct functable func[] = { 2427 {"add", rpc_group_add}, 2428 {"delete", rpc_group_delete}, 2429 {"addmem", rpc_group_addmem}, 2430 {"delmem", rpc_group_delmem}, 2431 {"list", rpc_group_list}, 2432 {"members", rpc_group_members}, 2433 {"rename", rpc_group_rename}, 2434 {NULL, NULL} 2435 }; 2436 2437 if (argc == 0) { 2438 if (opt_long_list_entries) { 2439 } else { 2440 } 2441 return run_rpc_command(NULL, PI_SAMR, 0, 2442 rpc_group_list_internals, 2443 argc, argv); 2444 } 2445 2446 return net_run_function(argc, argv, func, rpc_group_usage); 2447} 2448 2449/****************************************************************************/ 2450 2451static int rpc_share_usage(int argc, const char **argv) 2452{ 2453 return net_help_share(argc, argv); 2454} 2455 2456/** 2457 * Add a share on a remote RPC server 2458 * 2459 * All parameters are provided by the run_rpc_command function, except for 2460 * argc, argv which are passes through. 2461 * 2462 * @param domain_sid The domain sid acquired from the remote server 2463 * @param cli A cli_state connected to the server. 2464 * @param mem_ctx Talloc context, destoyed on completion of the function. 2465 * @param argc Standard main() style argc 2466 * @param argv Standard main() style argv. Initial components are already 2467 * stripped 2468 * 2469 * @return Normal NTSTATUS return. 2470 **/ 2471static NTSTATUS 2472rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name, 2473 struct cli_state *cli, 2474 TALLOC_CTX *mem_ctx,int argc, const char **argv) 2475{ 2476 WERROR result; 2477 char *sharename=talloc_strdup(mem_ctx, argv[0]); 2478 char *path; 2479 uint32 type=0; /* only allow disk shares to be added */ 2480 uint32 num_users=0, perms=0; 2481 char *password=NULL; /* don't allow a share password */ 2482 uint32 level = 2; 2483 2484 path = strchr(sharename, '='); 2485 if (!path) 2486 return NT_STATUS_UNSUCCESSFUL; 2487 *path++ = '\0'; 2488 2489 result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type, 2490 opt_comment, perms, opt_maxusers, 2491 num_users, path, password, 2492 level, NULL); 2493 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 2494} 2495 2496static int rpc_share_add(int argc, const char **argv) 2497{ 2498 if ((argc < 1) || !strchr(argv[0], '=')) { 2499 DEBUG(1,("Sharename or path not specified on add\n")); 2500 return rpc_share_usage(argc, argv); 2501 } 2502 return run_rpc_command(NULL, PI_SRVSVC, 0, 2503 rpc_share_add_internals, 2504 argc, argv); 2505} 2506 2507/** 2508 * Delete a share on a remote RPC server 2509 * 2510 * All parameters are provided by the run_rpc_command function, except for 2511 * argc, argv which are passes through. 2512 * 2513 * @param domain_sid The domain sid acquired from the remote server 2514 * @param cli A cli_state connected to the server. 2515 * @param mem_ctx Talloc context, destoyed on completion of the function. 2516 * @param argc Standard main() style argc 2517 * @param argv Standard main() style argv. Initial components are already 2518 * stripped 2519 * 2520 * @return Normal NTSTATUS return. 2521 **/ 2522static NTSTATUS 2523rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name, 2524 struct cli_state *cli, 2525 TALLOC_CTX *mem_ctx,int argc, const char **argv) 2526{ 2527 WERROR result; 2528 2529 result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]); 2530 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 2531} 2532 2533/** 2534 * Delete a share on a remote RPC server 2535 * 2536 * @param domain_sid The domain sid acquired from the remote server 2537 * @param argc Standard main() style argc 2538 * @param argv Standard main() style argv. Initial components are already 2539 * stripped 2540 * 2541 * @return A shell status integer (0 for success) 2542 **/ 2543static int rpc_share_delete(int argc, const char **argv) 2544{ 2545 if (argc < 1) { 2546 DEBUG(1,("Sharename not specified on delete\n")); 2547 return rpc_share_usage(argc, argv); 2548 } 2549 return run_rpc_command(NULL, PI_SRVSVC, 0, 2550 rpc_share_del_internals, 2551 argc, argv); 2552} 2553 2554/** 2555 * Formatted print of share info 2556 * 2557 * @param info1 pointer to SRV_SHARE_INFO_1 to format 2558 **/ 2559 2560static void display_share_info_1(SRV_SHARE_INFO_1 *info1) 2561{ 2562 fstring netname = "", remark = ""; 2563 2564 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname); 2565 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark); 2566 2567 if (opt_long_list_entries) { 2568 d_printf("%-12s %-8.8s %-50s\n", 2569 netname, share_type[info1->info_1.type], remark); 2570 } else { 2571 d_printf("%s\n", netname); 2572 } 2573 2574} 2575 2576/** 2577 * List shares on a remote RPC server 2578 * 2579 * All parameters are provided by the run_rpc_command function, except for 2580 * argc, argv which are passes through. 2581 * 2582 * @param domain_sid The domain sid acquired from the remote server 2583 * @param cli A cli_state connected to the server. 2584 * @param mem_ctx Talloc context, destoyed on completion of the function. 2585 * @param argc Standard main() style argc 2586 * @param argv Standard main() style argv. Initial components are already 2587 * stripped 2588 * 2589 * @return Normal NTSTATUS return. 2590 **/ 2591 2592static NTSTATUS 2593rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name, 2594 struct cli_state *cli, 2595 TALLOC_CTX *mem_ctx, int argc, const char **argv) 2596{ 2597 SRV_SHARE_INFO_CTR ctr; 2598 WERROR result; 2599 ENUM_HND hnd; 2600 uint32 preferred_len = 0xffffffff, i; 2601 2602 init_enum_hnd(&hnd, 0); 2603 2604 result = cli_srvsvc_net_share_enum( 2605 cli, mem_ctx, 1, &ctr, preferred_len, &hnd); 2606 2607 if (!W_ERROR_IS_OK(result)) 2608 goto done; 2609 2610 /* Display results */ 2611 2612 if (opt_long_list_entries) { 2613 d_printf( 2614 "\nEnumerating shared resources (exports) on remote server:\n\n"\ 2615 "\nShare name Type Description\n"\ 2616 "---------- ---- -----------\n"); 2617 } 2618 for (i = 0; i < ctr.num_entries; i++) 2619 display_share_info_1(&ctr.share.info1[i]); 2620 done: 2621 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 2622} 2623 2624/** 2625 * Migrate shares from a remote RPC server to the local RPC srever 2626 * 2627 * All parameters are provided by the run_rpc_command function, except for 2628 * argc, argv which are passes through. 2629 * 2630 * @param domain_sid The domain sid acquired from the remote server 2631 * @param cli A cli_state connected to the server. 2632 * @param mem_ctx Talloc context, destoyed on completion of the function. 2633 * @param argc Standard main() style argc 2634 * @param argv Standard main() style argv. Initial components are already 2635 * stripped 2636 * 2637 * @return Normal NTSTATUS return. 2638 **/ 2639static NTSTATUS 2640rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain_name, 2641 struct cli_state *cli, TALLOC_CTX *mem_ctx, 2642 int argc, const char **argv) 2643{ 2644 WERROR result; 2645 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 2646 SRV_SHARE_INFO_CTR ctr_src; 2647 ENUM_HND hnd; 2648 uint32 type = 0; /* only allow disk shares to be added */ 2649 uint32 num_uses = 0, perms = 0, max_uses = 0; 2650 char *password = NULL; /* don't allow a share password */ 2651 uint32 preferred_len = 0xffffffff, i; 2652 BOOL got_dst_srvsvc_pipe = False; 2653 struct cli_state *cli_dst = NULL; 2654 uint32 level = 502; /* includes secdesc */ 2655 SEC_DESC *share_sd = NULL; 2656 2657 init_enum_hnd(&hnd, 0); 2658 2659 result = cli_srvsvc_net_share_enum( 2660 cli, mem_ctx, level, &ctr_src, preferred_len, &hnd); 2661 if (!W_ERROR_IS_OK(result)) 2662 goto done; 2663 2664 /* connect local PI_SRVSVC */ 2665 nt_status = connect_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe); 2666 if (!NT_STATUS_IS_OK(nt_status)) 2667 return nt_status; 2668 2669 2670 for (i = 0; i < ctr_src.num_entries; i++) { 2671 2672 fstring netname = "", remark = "", path = ""; 2673 /* reset error-code */ 2674 nt_status = NT_STATUS_UNSUCCESSFUL; 2675 2676 rpcstr_pull_unistr2_fstring( 2677 netname, &ctr_src.share.info502[i].info_502_str.uni_netname); 2678 rpcstr_pull_unistr2_fstring( 2679 remark, &ctr_src.share.info502[i].info_502_str.uni_remark); 2680 rpcstr_pull_unistr2_fstring( 2681 path, &ctr_src.share.info502[i].info_502_str.uni_path); 2682 num_uses = ctr_src.share.info502[i].info_502.num_uses; 2683 max_uses = ctr_src.share.info502[i].info_502.max_uses; 2684 perms = ctr_src.share.info502[i].info_502.perms; 2685 2686 2687 if (opt_acls) 2688 share_sd = dup_sec_desc( 2689 mem_ctx, ctr_src.share.info502[i].info_502_str.sd); 2690 2691 /* since we do not have NetShareGetInfo implemented in samba3 we 2692 only can skip inside the enum-ctr_src */ 2693 if (argc == 1) { 2694 char *one_share = talloc_strdup(mem_ctx, argv[0]); 2695 if (!strequal(netname, one_share)) 2696 continue; 2697 } 2698 2699 /* skip builtin shares */ 2700 /* FIXME: should print$ be added too ? */ 2701 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") || 2702 strequal(netname,"global")) 2703 continue; 2704 2705 /* only work with file-shares */ 2706 if (!cli_send_tconX(cli, netname, "A:", "", 0)) { 2707 d_printf("skipping [%s]: not a file share.\n", netname); 2708 continue; 2709 } 2710 2711 if (!cli_tdis(cli)) 2712 goto done; 2713 2714 2715 /* finallly add the share on the dst server 2716 please note that samba currently does not allow to 2717 add a share without existing directory */ 2718 2719 printf("migrating: [%s], path: %s, comment: %s, %s share-ACLs\n", 2720 netname, path, remark, opt_acls ? "including" : "without" ); 2721 2722 if (opt_verbose && opt_acls) 2723 display_sec_desc(share_sd); 2724 2725 result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type, 2726 remark, perms, max_uses, 2727 num_uses, path, password, 2728 level, share_sd); 2729 2730 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) { 2731 printf(" [%s] does already exist\n", netname); 2732 continue; 2733 } 2734 2735 if (!W_ERROR_IS_OK(result)) { 2736 printf("cannot add share: %s\n", dos_errstr(result)); 2737 goto done; 2738 } 2739 2740 } 2741 2742 nt_status = NT_STATUS_OK; 2743 2744done: 2745 if (got_dst_srvsvc_pipe) { 2746 cli_nt_session_close(cli_dst); 2747 cli_shutdown(cli_dst); 2748 } 2749 2750 return nt_status; 2751 2752} 2753 2754/** 2755 * Migrate shares from a rpc-server to another 2756 * 2757 * @param argc Standard main() style argc 2758 * @param argv Standard main() style argv. Initial components are already 2759 * stripped 2760 * 2761 * @return A shell status integer (0 for success) 2762 **/ 2763static int rpc_share_migrate_shares(int argc, const char **argv) 2764{ 2765 2766 if (!opt_host) { 2767 printf("no server to migrate\n"); 2768 return -1; 2769 } 2770 2771 return run_rpc_command(NULL, PI_SRVSVC, 0, 2772 rpc_share_migrate_shares_internals, 2773 argc, argv); 2774} 2775 2776typedef struct copy_clistate { 2777 TALLOC_CTX *mem_ctx; 2778 struct cli_state *cli_share_src; 2779 struct cli_state *cli_share_dst; 2780 const char *cwd; 2781} copy_clistate; 2782 2783 2784/** 2785 * Copy a file/dir 2786 * 2787 * @param f file_info 2788 * @param mask current search mask 2789 * @param state arg-pointer 2790 * 2791 **/ 2792static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state) 2793{ 2794 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 2795 struct copy_clistate *local_state = (struct copy_clistate *)state; 2796 fstring filename, new_mask, dir; 2797 2798 if (strequal(f->name, ".") || strequal(f->name, "..")) 2799 return; 2800 2801 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name)); 2802 2803 /* DIRECTORY */ 2804 if (f->mode & aDIR) { 2805 2806 DEBUG(3,("got dir: %s\n", f->name)); 2807 2808 fstrcpy(dir, local_state->cwd); 2809 fstrcat(dir, "\\"); 2810 fstrcat(dir, f->name); 2811 2812 /* create that directory */ 2813 nt_status = net_copy_file(local_state->mem_ctx, 2814 local_state->cli_share_src, 2815 local_state->cli_share_dst, 2816 dir, dir, 2817 opt_acls? True : False, 2818 opt_attrs? True : False, 2819 opt_timestamps? True : False, 2820 False); 2821 2822 if (!NT_STATUS_IS_OK(nt_status)) 2823 printf("could not copy dir %s: %s\n", 2824 dir, nt_errstr(nt_status)); 2825 2826 /* search below that directory */ 2827 fstrcpy(new_mask, dir); 2828 fstrcat(new_mask, "\\*"); 2829 2830 if (!sync_files(local_state->mem_ctx, 2831 local_state->cli_share_src, 2832 local_state->cli_share_dst, 2833 new_mask, dir)) 2834 2835 printf("could not sync files\n"); 2836 2837 return; 2838 } 2839 2840 2841 /* FILE */ 2842 fstrcpy(filename, local_state->cwd); 2843 fstrcat(filename, "\\"); 2844 fstrcat(filename, f->name); 2845 2846 DEBUG(3,("got file: %s\n", filename)); 2847 2848 nt_status = net_copy_file(local_state->mem_ctx, 2849 local_state->cli_share_src, 2850 local_state->cli_share_dst, 2851 filename, filename, 2852 opt_acls? True : False, 2853 opt_attrs? True : False, 2854 opt_timestamps? True: False, 2855 True); 2856 2857 if (!NT_STATUS_IS_OK(nt_status)) 2858 printf("could not copy file %s: %s\n", 2859 filename, nt_errstr(nt_status)); 2860 2861} 2862 2863/** 2864 * sync files, can be called recursivly to list files 2865 * and then call copy_fn for each file 2866 * 2867 * @param mem_ctx TALLOC_CTX 2868 * @param cli_share_src a connected share on the originating server 2869 * @param cli_share_dst a connected share on the destination server 2870 * @param mask the current search mask 2871 * @param cwd the current path 2872 * 2873 * @return Boolean result 2874 **/ 2875BOOL sync_files(TALLOC_CTX *mem_ctx, 2876 struct cli_state *cli_share_src, 2877 struct cli_state *cli_share_dst, 2878 pstring mask, fstring cwd) 2879 2880{ 2881 2882 uint16 attribute = aSYSTEM | aHIDDEN | aDIR; 2883 struct copy_clistate clistate; 2884 2885 clistate.mem_ctx = mem_ctx; 2886 clistate.cli_share_src = cli_share_src; 2887 clistate.cli_share_dst = cli_share_dst; 2888 clistate.cwd = cwd; 2889 2890 DEBUG(3,("calling cli_list with mask: %s\n", mask)); 2891 2892 if (cli_list(cli_share_src, mask, attribute, copy_fn, &clistate) == -1) { 2893 d_printf("listing %s failed with error: %s\n", 2894 mask, cli_errstr(cli_share_src)); 2895 return False; 2896 } 2897 2898 return True; 2899} 2900 2901 2902/** 2903 * Sync all files inside a remote share to another share (over smb) 2904 * 2905 * All parameters are provided by the run_rpc_command function, except for 2906 * argc, argv which are passes through. 2907 * 2908 * @param domain_sid The domain sid acquired from the remote server 2909 * @param cli A cli_state connected to the server. 2910 * @param mem_ctx Talloc context, destoyed on completion of the function. 2911 * @param argc Standard main() style argc 2912 * @param argv Standard main() style argv. Initial components are already 2913 * stripped 2914 * 2915 * @return Normal NTSTATUS return. 2916 **/ 2917static NTSTATUS 2918rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_name, 2919 struct cli_state *cli, TALLOC_CTX *mem_ctx, 2920 int argc, const char **argv) 2921{ 2922 WERROR result; 2923 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 2924 SRV_SHARE_INFO_CTR ctr_src; 2925 ENUM_HND hnd; 2926 uint32 preferred_len = 0xffffffff, i; 2927 uint32 level = 2; 2928 struct cli_state *cli_share_src = NULL; 2929 struct cli_state *cli_share_dst = NULL; 2930 BOOL got_src_share = False; 2931 BOOL got_dst_share = False; 2932 pstring mask; 2933 char *dst = NULL; 2934 2935 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1"); 2936 2937 init_enum_hnd(&hnd, 0); 2938 2939 result = cli_srvsvc_net_share_enum( 2940 cli, mem_ctx, level, &ctr_src, preferred_len, &hnd); 2941 2942 if (!W_ERROR_IS_OK(result)) 2943 goto done; 2944 2945 for (i = 0; i < ctr_src.num_entries; i++) { 2946 2947 fstring netname = "", remark = "", path = ""; 2948 2949 rpcstr_pull_unistr2_fstring( 2950 netname, &ctr_src.share.info2[i].info_2_str.uni_netname); 2951 rpcstr_pull_unistr2_fstring( 2952 remark, &ctr_src.share.info2[i].info_2_str.uni_remark); 2953 rpcstr_pull_unistr2_fstring( 2954 path, &ctr_src.share.info2[i].info_2_str.uni_path); 2955 2956 /* since we do not have NetShareGetInfo implemented in samba3 we 2957 only can skip inside the enum-ctr_src */ 2958 if (argc == 1) { 2959 char *one_share = talloc_strdup(mem_ctx, argv[0]); 2960 if (!strequal(netname, one_share)) 2961 continue; 2962 } 2963 2964 /* skip builtin and hidden shares 2965 In particular, one might not want to mirror whole discs :) */ 2966 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$")) 2967 continue; 2968 2969 if (strequal(netname, "print$") || netname[1] == '$') { 2970 d_printf("skipping [%s]: builtin/hidden share\n", netname); 2971 continue; 2972 } 2973 2974 if (opt_exclude && in_list(netname, (char *)opt_exclude, False)) { 2975 printf("excluding [%s]\n", netname); 2976 continue; 2977 } 2978 2979 /* only work with file-shares */ 2980 if (!cli_send_tconX(cli, netname, "A:", "", 0)) { 2981 d_printf("skipping [%s]: not a file share.\n", netname); 2982 continue; 2983 } 2984 2985 if (!cli_tdis(cli)) 2986 return NT_STATUS_UNSUCCESSFUL; 2987 2988 printf("syncing [%s] files and directories %s ACLs, %s DOS Attributes %s\n", 2989 netname, 2990 opt_acls ? "including" : "without", 2991 opt_attrs ? "including" : "without", 2992 opt_timestamps ? "(preserving timestamps)" : ""); 2993 2994 2995 /* open share source */ 2996 nt_status = connect_to_service(&cli_share_src, &cli->dest_ip, 2997 cli->desthost, netname, "A:"); 2998 if (!NT_STATUS_IS_OK(nt_status)) 2999 goto done; 3000 3001 got_src_share = True; 3002 3003 3004 /* open share destination */ 3005 nt_status = connect_to_service(&cli_share_dst, NULL, 3006 dst, netname, "A:"); 3007 if (!NT_STATUS_IS_OK(nt_status)) 3008 goto done; 3009 3010 got_dst_share = True; 3011 3012 3013 /* now call the filesync */ 3014 pstrcpy(mask, "\\*"); 3015 3016 if (!sync_files(mem_ctx, cli_share_src, cli_share_dst, mask, NULL)) { 3017 d_printf("could not sync files for share: %s\n", netname); 3018 nt_status = NT_STATUS_UNSUCCESSFUL; 3019 goto done; 3020 } 3021 3022 } 3023 3024 nt_status = NT_STATUS_OK; 3025 3026done: 3027 3028 if (got_src_share) 3029 cli_shutdown(cli_share_src); 3030 3031 if (got_dst_share) 3032 cli_shutdown(cli_share_dst); 3033 3034 return nt_status; 3035 3036} 3037 3038static int rpc_share_migrate_files(int argc, const char **argv) 3039{ 3040 3041 if (!opt_host) { 3042 printf("no server to migrate\n"); 3043 return -1; 3044 } 3045 3046 return run_rpc_command(NULL, PI_SRVSVC, 0, 3047 rpc_share_migrate_files_internals, 3048 argc, argv); 3049} 3050 3051/** 3052 * Migrate shares (including share-definitions, share-acls and files with acls/attrs) 3053 * from one server to another 3054 * 3055 * @param argc Standard main() style argc 3056 * @param argv Standard main() style argv. Initial components are already 3057 * stripped 3058 * 3059 * @return A shell status integer (0 for success) 3060 * 3061 **/ 3062static int rpc_share_migrate_all(int argc, const char **argv) 3063{ 3064 int ret; 3065 3066 if (!opt_host) { 3067 printf("no server to migrate\n"); 3068 return -1; 3069 } 3070 3071 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv); 3072 if (ret) 3073 return ret; 3074#if 0 3075 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_security_internals, argc, argv); 3076 if (ret) 3077 return ret; 3078#endif 3079 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv); 3080} 3081 3082 3083/** 3084 * 'net rpc share migrate' entrypoint. 3085 * @param argc Standard main() style argc 3086 * @param argv Standard main() style argv. Initial components are already 3087 * stripped 3088 **/ 3089static int rpc_share_migrate(int argc, const char **argv) 3090{ 3091 3092 struct functable func[] = { 3093 {"all", rpc_share_migrate_all}, 3094 {"files", rpc_share_migrate_files}, 3095 {"help", rpc_share_usage}, 3096/* {"security", rpc_share_migrate_security},*/ 3097 {"shares", rpc_share_migrate_shares}, 3098 {NULL, NULL} 3099 }; 3100 3101 return net_run_function(argc, argv, func, rpc_share_usage); 3102} 3103 3104struct full_alias { 3105 DOM_SID sid; 3106 int num_members; 3107 DOM_SID *members; 3108}; 3109 3110static int num_server_aliases; 3111static struct full_alias *server_aliases; 3112 3113/* 3114 * Add an alias to the static list. 3115 */ 3116static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias) 3117{ 3118 if (server_aliases == NULL) 3119 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100); 3120 3121 server_aliases[num_server_aliases] = *alias; 3122 num_server_aliases += 1; 3123} 3124 3125/* 3126 * For a specific domain on the server, fetch all the aliases 3127 * and their members. Add all of them to the server_aliases. 3128 */ 3129static NTSTATUS 3130rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, 3131 POLICY_HND *connect_pol, 3132 const DOM_SID *domain_sid) 3133{ 3134 uint32 start_idx, max_entries, num_entries, i; 3135 struct acct_info *groups; 3136 NTSTATUS result; 3137 POLICY_HND domain_pol; 3138 3139 /* Get domain policy handle */ 3140 3141 result = cli_samr_open_domain(cli, mem_ctx, connect_pol, 3142 MAXIMUM_ALLOWED_ACCESS, 3143 domain_sid, &domain_pol); 3144 if (!NT_STATUS_IS_OK(result)) 3145 return result; 3146 3147 start_idx = 0; 3148 max_entries = 250; 3149 3150 do { 3151 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, 3152 &start_idx, max_entries, 3153 &groups, &num_entries); 3154 3155 for (i = 0; i < num_entries; i++) { 3156 3157 POLICY_HND alias_pol; 3158 struct full_alias alias; 3159 DOM_SID *members; 3160 int j; 3161 3162 result = cli_samr_open_alias(cli, mem_ctx, &domain_pol, 3163 MAXIMUM_ALLOWED_ACCESS, 3164 groups[i].rid, 3165 &alias_pol); 3166 if (!NT_STATUS_IS_OK(result)) 3167 goto done; 3168 3169 result = cli_samr_query_aliasmem(cli, mem_ctx, 3170 &alias_pol, 3171 &alias.num_members, 3172 &members); 3173 if (!NT_STATUS_IS_OK(result)) 3174 goto done; 3175 3176 result = cli_samr_close(cli, mem_ctx, &alias_pol); 3177 if (!NT_STATUS_IS_OK(result)) 3178 goto done; 3179 3180 alias.members = NULL; 3181 3182 if (alias.num_members > 0) { 3183 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members); 3184 3185 for (j = 0; j < alias.num_members; j++) 3186 sid_copy(&alias.members[j], 3187 &members[j]); 3188 } 3189 3190 sid_copy(&alias.sid, domain_sid); 3191 sid_append_rid(&alias.sid, groups[i].rid); 3192 3193 push_alias(mem_ctx, &alias); 3194 } 3195 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 3196 3197 result = NT_STATUS_OK; 3198 3199 done: 3200 cli_samr_close(cli, mem_ctx, &domain_pol); 3201 3202 return result; 3203} 3204 3205/* 3206 * Dump server_aliases as names for debugging purposes. 3207 */ 3208static NTSTATUS 3209rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name, 3210 struct cli_state *cli, TALLOC_CTX *mem_ctx, 3211 int argc, const char **argv) 3212{ 3213 int i; 3214 NTSTATUS result; 3215 POLICY_HND lsa_pol; 3216 3217 result = cli_lsa_open_policy(cli, mem_ctx, True, 3218 SEC_RIGHTS_MAXIMUM_ALLOWED, 3219 &lsa_pol); 3220 if (!NT_STATUS_IS_OK(result)) 3221 return result; 3222 3223 for (i=0; i<num_server_aliases; i++) { 3224 char **names; 3225 char **domains; 3226 uint32 *types; 3227 int j; 3228 3229 struct full_alias *alias = &server_aliases[i]; 3230 3231 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, 1, 3232 &alias->sid, 3233 &domains, &names, &types); 3234 if (!NT_STATUS_IS_OK(result)) 3235 continue; 3236 3237 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0])); 3238 3239 if (alias->num_members == 0) { 3240 DEBUG(1, ("\n")); 3241 continue; 3242 } 3243 3244 result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, 3245 alias->num_members, 3246 alias->members, 3247 &domains, &names, &types); 3248 3249 if (!NT_STATUS_IS_OK(result) && 3250 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) 3251 continue; 3252 3253 for (j=0; j<alias->num_members; j++) 3254 DEBUG(1, ("%s\\%s (%d); ", 3255 domains[j] ? domains[j] : "*unknown*", 3256 names[j] ? names[j] : "*unknown*",types[j])); 3257 DEBUG(1, ("\n")); 3258 } 3259 3260 cli_lsa_close(cli, mem_ctx, &lsa_pol); 3261 3262 return NT_STATUS_OK; 3263} 3264 3265/* 3266 * Fetch a list of all server aliases and their members into 3267 * server_aliases. 3268 */ 3269static NTSTATUS 3270rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name, 3271 struct cli_state *cli, TALLOC_CTX *mem_ctx, 3272 int argc, const char **argv) 3273{ 3274 NTSTATUS result; 3275 POLICY_HND connect_pol; 3276 DOM_SID global_sid_Builtin; 3277 3278 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 3279 &connect_pol); 3280 3281 if (!NT_STATUS_IS_OK(result)) 3282 goto done; 3283 3284 string_to_sid(&global_sid_Builtin, "S-1-5-32"); 3285 3286 result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol, 3287 &global_sid_Builtin); 3288 3289 if (!NT_STATUS_IS_OK(result)) 3290 goto done; 3291 3292 result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol, 3293 domain_sid); 3294 3295 cli_samr_close(cli, mem_ctx, &connect_pol); 3296 done: 3297 return result; 3298} 3299 3300static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid) 3301{ 3302 DOM_SID global_sid_World; 3303 DOM_SID global_sid_Network; 3304 DOM_SID global_sid_Authenticated_Users; 3305 3306 string_to_sid(&global_sid_World, "S-1-1-0"); 3307 string_to_sid(&global_sid_Network, "S-1-5-2"); 3308 string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11"); 3309 3310 token->num_sids = 4; 3311 3312 token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4); 3313 3314 token->user_sids[0] = *user_sid; 3315 sid_copy(&token->user_sids[1], &global_sid_World); 3316 sid_copy(&token->user_sids[2], &global_sid_Network); 3317 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users); 3318} 3319 3320static void free_user_token(NT_USER_TOKEN *token) 3321{ 3322 SAFE_FREE(token->user_sids); 3323} 3324 3325static BOOL is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid) 3326{ 3327 int i; 3328 3329 for (i=0; i<token->num_sids; i++) { 3330 if (sid_compare(sid, &token->user_sids[i]) == 0) 3331 return True; 3332 } 3333 return False; 3334} 3335 3336static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid) 3337{ 3338 if (is_sid_in_token(token, sid)) 3339 return; 3340 3341 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1); 3342 3343 sid_copy(&token->user_sids[token->num_sids], sid); 3344 3345 token->num_sids += 1; 3346} 3347 3348struct user_token { 3349 fstring name; 3350 NT_USER_TOKEN token; 3351}; 3352 3353static void dump_user_token(struct user_token *token) 3354{ 3355 int i; 3356 3357 d_printf("%s\n", token->name); 3358 3359 for (i=0; i<token->token.num_sids; i++) { 3360 d_printf(" %s\n", sid_string_static(&token->token.user_sids[i])); 3361 } 3362} 3363 3364static BOOL is_alias_member(DOM_SID *sid, struct full_alias *alias) 3365{ 3366 int i; 3367 3368 for (i=0; i<alias->num_members; i++) { 3369 if (sid_compare(sid, &alias->members[i]) == 0) 3370 return True; 3371 } 3372 3373 return False; 3374} 3375 3376static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid) 3377{ 3378 int i; 3379 3380 for (i=0; i<num_server_aliases; i++) { 3381 if (is_alias_member(&sid, &server_aliases[i])) 3382 add_sid_to_token(token, &server_aliases[i].sid); 3383 } 3384} 3385 3386/* 3387 * We got a user token with all the SIDs we can know about without asking the 3388 * server directly. These are the user and domain group sids. All of these can 3389 * be members of aliases. So scan the list of aliases for each of the SIDs and 3390 * add them to the token. 3391 */ 3392 3393static void collect_alias_memberships(NT_USER_TOKEN *token) 3394{ 3395 int num_global_sids = token->num_sids; 3396 int i; 3397 3398 for (i=0; i<num_global_sids; i++) { 3399 collect_sid_memberships(token, token->user_sids[i]); 3400 } 3401} 3402 3403static BOOL get_user_sids(const char *domain, const char *user, 3404 NT_USER_TOKEN *token) 3405{ 3406 struct winbindd_request request; 3407 struct winbindd_response response; 3408 fstring full_name; 3409 NSS_STATUS result; 3410 3411 DOM_SID user_sid; 3412 3413 int i; 3414 3415 fstr_sprintf(full_name, "%s%c%s", 3416 domain, *lp_winbind_separator(), user); 3417 3418 /* First let's find out the user sid */ 3419 3420 ZERO_STRUCT(request); 3421 ZERO_STRUCT(response); 3422 3423 fstrcpy(request.data.name.dom_name, domain); 3424 fstrcpy(request.data.name.name, user); 3425 3426 result = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response); 3427 3428 if (result != NSS_STATUS_SUCCESS) { 3429 DEBUG(1, ("winbind could not find %s\n", full_name)); 3430 return False; 3431 } 3432 3433 if (response.data.sid.type != SID_NAME_USER) { 3434 DEBUG(1, ("%s is not a user\n", full_name)); 3435 return False; 3436 } 3437 3438 string_to_sid(&user_sid, response.data.sid.sid); 3439 3440 init_user_token(token, &user_sid); 3441 3442 /* And now the groups winbind knows about */ 3443 3444 ZERO_STRUCT(response); 3445 3446 fstrcpy(request.data.username, full_name); 3447 3448 result = winbindd_request(WINBINDD_GETGROUPS, &request, &response); 3449 3450 if (result != NSS_STATUS_SUCCESS) { 3451 DEBUG(1, ("winbind could not get groups of %s\n", full_name)); 3452 return False; 3453 } 3454 3455 for (i = 0; i < response.data.num_entries; i++) { 3456 gid_t gid = ((gid_t *)response.extra_data)[i]; 3457 DOM_SID sid; 3458 3459 struct winbindd_request sidrequest; 3460 struct winbindd_response sidresponse; 3461 3462 ZERO_STRUCT(sidrequest); 3463 ZERO_STRUCT(sidresponse); 3464 3465 sidrequest.data.gid = gid; 3466 3467 result = winbindd_request(WINBINDD_GID_TO_SID, 3468 &sidrequest, &sidresponse); 3469 3470 if (result != NSS_STATUS_SUCCESS) { 3471 DEBUG(1, ("winbind could not find SID of gid %d\n", 3472 gid)); 3473 return False; 3474 } 3475 3476 DEBUG(3, (" %s\n", sidresponse.data.sid.sid)); 3477 3478 string_to_sid(&sid, sidresponse.data.sid.sid); 3479 add_sid_to_token(token, &sid); 3480 } 3481 3482 SAFE_FREE(response.extra_data); 3483 3484 return True; 3485} 3486 3487/** 3488 * Get a list of all user tokens we want to look at 3489 **/ 3490static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens) 3491{ 3492 struct winbindd_request request; 3493 struct winbindd_response response; 3494 const char *extra_data; 3495 fstring name; 3496 int i; 3497 struct user_token *result; 3498 3499 /* Send request to winbind daemon */ 3500 3501 ZERO_STRUCT(request); 3502 ZERO_STRUCT(response); 3503 3504 if (winbindd_request(WINBINDD_LIST_USERS, &request, &response) != 3505 NSS_STATUS_SUCCESS) 3506 return False; 3507 3508 /* Look through extra data */ 3509 3510 if (!response.extra_data) 3511 return False; 3512 3513 extra_data = (const char *)response.extra_data; 3514 *num_tokens = 0; 3515 3516 while(next_token(&extra_data, name, ",", sizeof(fstring))) { 3517 *num_tokens += 1; 3518 } 3519 3520 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens); 3521 3522 if (result == NULL) { 3523 DEBUG(1, ("Could not malloc sid array\n")); 3524 return False; 3525 } 3526 3527 extra_data = (const char *)response.extra_data; 3528 i=0; 3529 3530 while(next_token(&extra_data, name, ",", sizeof(fstring))) { 3531 3532 fstring domain, user; 3533 char *p; 3534 3535 fstrcpy(result[i].name, name); 3536 3537 p = strchr(name, *lp_winbind_separator()); 3538 3539 DEBUG(3, ("%s\n", name)); 3540 3541 if (p == NULL) 3542 continue; 3543 3544 *p++ = '\0'; 3545 3546 fstrcpy(domain, name); 3547 strupper_m(domain); 3548 fstrcpy(user, p); 3549 3550 get_user_sids(domain, user, &(result[i].token)); 3551 i+=1; 3552 } 3553 3554 SAFE_FREE(response.extra_data); 3555 3556 *user_tokens = result; 3557 3558 return True; 3559} 3560 3561static BOOL get_user_tokens_from_file(FILE *f, 3562 int *num_tokens, 3563 struct user_token **tokens) 3564{ 3565 struct user_token *token = NULL; 3566 3567 while (!feof(f)) { 3568 fstring line; 3569 3570 if (fgets(line, sizeof(line)-1, f) == NULL) { 3571 return True; 3572 } 3573 3574 if (line[strlen(line)-1] == '\n') 3575 line[strlen(line)-1] = '\0'; 3576 3577 if (line[0] == ' ') { 3578 /* We have a SID */ 3579 3580 DOM_SID sid; 3581 string_to_sid(&sid, &line[1]); 3582 3583 if (token == NULL) { 3584 DEBUG(0, ("File does not begin with username")); 3585 return False; 3586 } 3587 3588 add_sid_to_token(&token->token, &sid); 3589 continue; 3590 } 3591 3592 /* And a new user... */ 3593 3594 *num_tokens += 1; 3595 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens); 3596 if (*tokens == NULL) { 3597 DEBUG(0, ("Could not realloc tokens\n")); 3598 return False; 3599 } 3600 3601 token = &((*tokens)[*num_tokens-1]); 3602 3603 fstrcpy(token->name, line); 3604 token->token.num_sids = 0; 3605 token->token.user_sids = NULL; 3606 continue; 3607 } 3608 3609 return False; 3610} 3611 3612 3613/* 3614 * Show the list of all users that have access to a share 3615 */ 3616 3617static void show_userlist(struct cli_state *cli, 3618 TALLOC_CTX *mem_ctx, const char *netname, 3619 int num_tokens, struct user_token *tokens) 3620{ 3621 int fnum; 3622 SEC_DESC *share_sd = NULL; 3623 SEC_DESC *root_sd = NULL; 3624 int i; 3625 SRV_SHARE_INFO info; 3626 WERROR result; 3627 uint16 cnum; 3628 3629 result = cli_srvsvc_net_share_get_info(cli, mem_ctx, netname, 3630 502, &info); 3631 3632 if (!W_ERROR_IS_OK(result)) { 3633 DEBUG(1, ("Coult not query secdesc for share %s\n", 3634 netname)); 3635 return; 3636 } 3637 3638 share_sd = info.share.info502.info_502_str.sd; 3639 if (share_sd == NULL) { 3640 DEBUG(1, ("Got no secdesc for share %s\n", 3641 netname)); 3642 } 3643 3644 cnum = cli->cnum; 3645 3646 if (!cli_send_tconX(cli, netname, "A:", "", 0)) { 3647 return; 3648 } 3649 3650 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS); 3651 3652 if (fnum != -1) { 3653 root_sd = cli_query_secdesc(cli, fnum, mem_ctx); 3654 } 3655 3656 for (i=0; i<num_tokens; i++) { 3657 uint32 acc_granted; 3658 NTSTATUS status; 3659 3660 if (share_sd != NULL) { 3661 if (!se_access_check(share_sd, &tokens[i].token, 3662 1, &acc_granted, &status)) { 3663 DEBUG(1, ("Could not check share_sd for " 3664 "user %s\n", 3665 tokens[i].name)); 3666 continue; 3667 } 3668 3669 if (!NT_STATUS_IS_OK(status)) 3670 continue; 3671 } 3672 3673 if (root_sd == NULL) { 3674 d_printf(" %s\n", tokens[i].name); 3675 continue; 3676 } 3677 3678 if (!se_access_check(root_sd, &tokens[i].token, 3679 1, &acc_granted, &status)) { 3680 DEBUG(1, ("Could not check root_sd for user %s\n", 3681 tokens[i].name)); 3682 continue; 3683 } 3684 3685 if (!NT_STATUS_IS_OK(status)) 3686 continue; 3687 3688 d_printf(" %s\n", tokens[i].name); 3689 } 3690 3691 if (fnum != -1) 3692 cli_close(cli, fnum); 3693 cli_tdis(cli); 3694 cli->cnum = cnum; 3695 3696 return; 3697} 3698 3699struct share_list { 3700 int num_shares; 3701 char **shares; 3702}; 3703 3704static void collect_share(const char *name, uint32 m, 3705 const char *comment, void *state) 3706{ 3707 struct share_list *share_list = (struct share_list *)state; 3708 3709 if (m != STYPE_DISKTREE) 3710 return; 3711 3712 share_list->num_shares += 1; 3713 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares); 3714 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name); 3715} 3716 3717static void rpc_share_userlist_usage(void) 3718{ 3719 return; 3720} 3721 3722/** 3723 * List shares on a remote RPC server, including the security descriptors 3724 * 3725 * All parameters are provided by the run_rpc_command function, except for 3726 * argc, argv which are passes through. 3727 * 3728 * @param domain_sid The domain sid acquired from the remote server 3729 * @param cli A cli_state connected to the server. 3730 * @param mem_ctx Talloc context, destoyed on completion of the function. 3731 * @param argc Standard main() style argc 3732 * @param argv Standard main() style argv. Initial components are already 3733 * stripped 3734 * 3735 * @return Normal NTSTATUS return. 3736 **/ 3737 3738static NTSTATUS 3739rpc_share_allowedusers_internals(const DOM_SID *domain_sid, 3740 const char *domain_name, 3741 struct cli_state *cli, 3742 TALLOC_CTX *mem_ctx, 3743 int argc, const char **argv) 3744{ 3745 int ret; 3746 BOOL r; 3747 ENUM_HND hnd; 3748 uint32 i; 3749 FILE *f; 3750 3751 struct user_token *tokens = NULL; 3752 int num_tokens = 0; 3753 3754 struct share_list share_list; 3755 3756 if (argc > 1) { 3757 rpc_share_userlist_usage(); 3758 return NT_STATUS_UNSUCCESSFUL; 3759 } 3760 3761 if (argc == 0) { 3762 f = stdin; 3763 } else { 3764 f = fopen(argv[0], "r"); 3765 } 3766 3767 if (f == NULL) { 3768 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno))); 3769 return NT_STATUS_UNSUCCESSFUL; 3770 } 3771 3772 r = get_user_tokens_from_file(f, &num_tokens, &tokens); 3773 3774 if (f != stdin) 3775 fclose(f); 3776 3777 if (!r) { 3778 DEBUG(0, ("Could not read users from file\n")); 3779 return NT_STATUS_UNSUCCESSFUL; 3780 } 3781 3782 for (i=0; i<num_tokens; i++) 3783 collect_alias_memberships(&tokens[i].token); 3784 3785 init_enum_hnd(&hnd, 0); 3786 3787 share_list.num_shares = 0; 3788 share_list.shares = NULL; 3789 3790 ret = cli_RNetShareEnum(cli, collect_share, &share_list); 3791 3792 if (ret == -1) { 3793 DEBUG(0, ("Error returning browse list: %s\n", 3794 cli_errstr(cli))); 3795 goto done; 3796 } 3797 3798 for (i = 0; i < share_list.num_shares; i++) { 3799 char *netname = share_list.shares[i]; 3800 3801 if (netname[strlen(netname)-1] == '$') 3802 continue; 3803 3804 d_printf("%s\n", netname); 3805 3806 show_userlist(cli, mem_ctx, netname, 3807 num_tokens, tokens); 3808 } 3809 done: 3810 for (i=0; i<num_tokens; i++) { 3811 free_user_token(&tokens[i].token); 3812 } 3813 SAFE_FREE(tokens); 3814 SAFE_FREE(share_list.shares); 3815 3816 return NT_STATUS_OK; 3817} 3818 3819static int 3820rpc_share_allowedusers(int argc, const char **argv) 3821{ 3822 int result; 3823 3824 result = run_rpc_command(NULL, PI_SAMR, 0, 3825 rpc_aliaslist_internals, 3826 argc, argv); 3827 if (result != 0) 3828 return result; 3829 3830 result = run_rpc_command(NULL, PI_LSARPC, 0, 3831 rpc_aliaslist_dump, 3832 argc, argv); 3833 if (result != 0) 3834 return result; 3835 3836 return run_rpc_command(NULL, PI_SRVSVC, 0, 3837 rpc_share_allowedusers_internals, 3838 argc, argv); 3839} 3840 3841int net_usersidlist(int argc, const char **argv) 3842{ 3843 int num_tokens = 0; 3844 struct user_token *tokens = NULL; 3845 int i; 3846 3847 if (argc != 0) { 3848 net_usersidlist_usage(argc, argv); 3849 return 0; 3850 } 3851 3852 if (!get_user_tokens(&num_tokens, &tokens)) { 3853 DEBUG(0, ("Could not get the user/sid list\n")); 3854 return 0; 3855 } 3856 3857 for (i=0; i<num_tokens; i++) { 3858 dump_user_token(&tokens[i]); 3859 free_user_token(&tokens[i].token); 3860 } 3861 3862 SAFE_FREE(tokens); 3863 return 1; 3864} 3865 3866int net_usersidlist_usage(int argc, const char **argv) 3867{ 3868 d_printf("net usersidlist\n" 3869 "\tprints out a list of all users the running winbind knows\n" 3870 "\tabout, together with all their SIDs. This is used as\n" 3871 "\tinput to the 'net rpc share allowedusers' command.\n\n"); 3872 3873 net_common_flags_usage(argc, argv); 3874 return -1; 3875} 3876 3877/** 3878 * 'net rpc share' entrypoint. 3879 * @param argc Standard main() style argc 3880 * @param argv Standard main() style argv. Initial components are already 3881 * stripped 3882 **/ 3883 3884int net_rpc_share(int argc, const char **argv) 3885{ 3886 struct functable func[] = { 3887 {"add", rpc_share_add}, 3888 {"delete", rpc_share_delete}, 3889 {"allowedusers", rpc_share_allowedusers}, 3890 {"migrate", rpc_share_migrate}, 3891 {NULL, NULL} 3892 }; 3893 3894 if (argc == 0) 3895 return run_rpc_command(NULL, PI_SRVSVC, 0, 3896 rpc_share_list_internals, 3897 argc, argv); 3898 3899 return net_run_function(argc, argv, func, rpc_share_usage); 3900} 3901 3902/****************************************************************************/ 3903 3904static int rpc_file_usage(int argc, const char **argv) 3905{ 3906 return net_help_file(argc, argv); 3907} 3908 3909/** 3910 * Close a file on a remote RPC server 3911 * 3912 * All parameters are provided by the run_rpc_command function, except for 3913 * argc, argv which are passes through. 3914 * 3915 * @param domain_sid The domain sid acquired from the remote server 3916 * @param cli A cli_state connected to the server. 3917 * @param mem_ctx Talloc context, destoyed on completion of the function. 3918 * @param argc Standard main() style argc 3919 * @param argv Standard main() style argv. Initial components are already 3920 * stripped 3921 * 3922 * @return Normal NTSTATUS return. 3923 **/ 3924static NTSTATUS 3925rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name, 3926 struct cli_state *cli, 3927 TALLOC_CTX *mem_ctx, int argc, const char **argv) 3928{ 3929 WERROR result; 3930 result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0])); 3931 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 3932} 3933 3934/** 3935 * Close a file on a remote RPC server 3936 * 3937 * @param argc Standard main() style argc 3938 * @param argv Standard main() style argv. Initial components are already 3939 * stripped 3940 * 3941 * @return A shell status integer (0 for success) 3942 **/ 3943static int rpc_file_close(int argc, const char **argv) 3944{ 3945 if (argc < 1) { 3946 DEBUG(1, ("No fileid given on close\n")); 3947 return(rpc_file_usage(argc, argv)); 3948 } 3949 3950 return run_rpc_command(NULL, PI_SRVSVC, 0, 3951 rpc_file_close_internals, 3952 argc, argv); 3953} 3954 3955/** 3956 * Formatted print of open file info 3957 * 3958 * @param info3 FILE_INFO_3 contents 3959 * @param str3 strings for FILE_INFO_3 3960 **/ 3961 3962static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3) 3963{ 3964 fstring user = "", path = ""; 3965 3966 rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name); 3967 rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name); 3968 3969 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n", 3970 info3->id, user, info3->perms, info3->num_locks, path); 3971} 3972 3973/** 3974 * List open files on a remote RPC server 3975 * 3976 * All parameters are provided by the run_rpc_command function, except for 3977 * argc, argv which are passes through. 3978 * 3979 * @param domain_sid The domain sid acquired from the remote server 3980 * @param cli A cli_state connected to the server. 3981 * @param mem_ctx Talloc context, destoyed on completion of the function. 3982 * @param argc Standard main() style argc 3983 * @param argv Standard main() style argv. Initial components are already 3984 * stripped 3985 * 3986 * @return Normal NTSTATUS return. 3987 **/ 3988 3989static NTSTATUS 3990rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name, 3991 struct cli_state *cli, 3992 TALLOC_CTX *mem_ctx, int argc, const char **argv) 3993{ 3994 SRV_FILE_INFO_CTR ctr; 3995 WERROR result; 3996 ENUM_HND hnd; 3997 uint32 preferred_len = 0xffffffff, i; 3998 const char *username=NULL; 3999 4000 init_enum_hnd(&hnd, 0); 4001 4002 /* if argc > 0, must be user command */ 4003 if (argc > 0) 4004 username = smb_xstrdup(argv[0]); 4005 4006 result = cli_srvsvc_net_file_enum( 4007 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd); 4008 4009 if (!W_ERROR_IS_OK(result)) 4010 goto done; 4011 4012 /* Display results */ 4013 4014 d_printf( 4015 "\nEnumerating open files on remote server:\n\n"\ 4016 "\nFileId Opened by Perms Locks Path"\ 4017 "\n------ --------- ----- ----- ---- \n"); 4018 for (i = 0; i < ctr.num_entries; i++) 4019 display_file_info_3(&ctr.file.info3[i].info_3, 4020 &ctr.file.info3[i].info_3_str); 4021 done: 4022 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 4023} 4024 4025 4026/** 4027 * List files for a user on a remote RPC server 4028 * 4029 * @param argc Standard main() style argc 4030 * @param argv Standard main() style argv. Initial components are already 4031 * stripped 4032 * 4033 * @return A shell status integer (0 for success) 4034 **/ 4035static int rpc_file_user(int argc, const char **argv) 4036{ 4037 if (argc < 1) { 4038 DEBUG(1, ("No username given\n")); 4039 return(rpc_file_usage(argc, argv)); 4040 } 4041 4042 return run_rpc_command(NULL, PI_SRVSVC, 0, 4043 rpc_file_list_internals, 4044 argc, argv); 4045} 4046 4047 4048/** 4049 * 'net rpc file' entrypoint. 4050 * @param argc Standard main() style argc 4051 * @param argv Standard main() style argv. Initial components are already 4052 * stripped 4053 **/ 4054 4055int net_rpc_file(int argc, const char **argv) 4056{ 4057 struct functable func[] = { 4058 {"close", rpc_file_close}, 4059 {"user", rpc_file_user}, 4060#if 0 4061 {"info", rpc_file_info}, 4062#endif 4063 {NULL, NULL} 4064 }; 4065 4066 if (argc == 0) 4067 return run_rpc_command(NULL, PI_SRVSVC, 0, 4068 rpc_file_list_internals, 4069 argc, argv); 4070 4071 return net_run_function(argc, argv, func, rpc_file_usage); 4072} 4073 4074/****************************************************************************/ 4075 4076 4077 4078/** 4079 * ABORT the shutdown of a remote RPC Server over, initshutdown pipe 4080 * 4081 * All parameters are provided by the run_rpc_command function, except for 4082 * argc, argv which are passed through. 4083 * 4084 * @param domain_sid The domain sid aquired from the remote server 4085 * @param cli A cli_state connected to the server. 4086 * @param mem_ctx Talloc context, destoyed on compleation of the function. 4087 * @param argc Standard main() style argc 4088 * @param argv Standard main() style argv. Initial components are already 4089 * stripped 4090 * 4091 * @return Normal NTSTATUS return. 4092 **/ 4093 4094static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, 4095 const char *domain_name, 4096 struct cli_state *cli, 4097 TALLOC_CTX *mem_ctx, 4098 int argc, const char **argv) 4099{ 4100 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4101 4102 result = cli_shutdown_abort(cli, mem_ctx); 4103 4104 if (NT_STATUS_IS_OK(result)) { 4105 d_printf("\nShutdown successfully aborted\n"); 4106 DEBUG(5,("cmd_shutdown_abort: query succeeded\n")); 4107 } else 4108 DEBUG(5,("cmd_shutdown_abort: query failed\n")); 4109 4110 return result; 4111} 4112 4113 4114/** 4115 * ABORT the shutdown of a remote RPC Server, over winreg pipe 4116 * 4117 * All parameters are provided by the run_rpc_command function, except for 4118 * argc, argv which are passed through. 4119 * 4120 * @param domain_sid The domain sid aquired from the remote server 4121 * @param cli A cli_state connected to the server. 4122 * @param mem_ctx Talloc context, destoyed on compleation of the function. 4123 * @param argc Standard main() style argc 4124 * @param argv Standard main() style argv. Initial components are already 4125 * stripped 4126 * 4127 * @return Normal NTSTATUS return. 4128 **/ 4129 4130static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid, 4131 const char *domain_name, 4132 struct cli_state *cli, 4133 TALLOC_CTX *mem_ctx, 4134 int argc, const char **argv) 4135{ 4136 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4137 4138 result = werror_to_ntstatus(cli_reg_abort_shutdown(cli, mem_ctx)); 4139 4140 if (NT_STATUS_IS_OK(result)) { 4141 d_printf("\nShutdown successfully aborted\n"); 4142 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n")); 4143 } else 4144 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n")); 4145 4146 return result; 4147} 4148 4149/** 4150 * ABORT the Shut down of a remote RPC server 4151 * 4152 * @param argc Standard main() style argc 4153 * @param argv Standard main() style argv. Initial components are already 4154 * stripped 4155 * 4156 * @return A shell status integer (0 for success) 4157 **/ 4158 4159static int rpc_shutdown_abort(int argc, const char **argv) 4160{ 4161 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0, 4162 rpc_shutdown_abort_internals, 4163 argc, argv); 4164 4165 if (rc == 0) 4166 return rc; 4167 4168 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n")); 4169 4170 return run_rpc_command(NULL, PI_WINREG, 0, 4171 rpc_reg_shutdown_abort_internals, 4172 argc, argv); 4173} 4174 4175/** 4176 * Shut down a remote RPC Server via initshutdown pipe 4177 * 4178 * All parameters are provided by the run_rpc_command function, except for 4179 * argc, argv which are passes through. 4180 * 4181 * @param domain_sid The domain sid aquired from the remote server 4182 * @param cli A cli_state connected to the server. 4183 * @param mem_ctx Talloc context, destoyed on compleation of the function. 4184 * @param argc Standard main() style argc 4185 * @param argc Standard main() style argv. Initial components are already 4186 * stripped 4187 * 4188 * @return Normal NTSTATUS return. 4189 **/ 4190 4191static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid, 4192 const char *domain_name, 4193 struct cli_state *cli, 4194 TALLOC_CTX *mem_ctx, 4195 int argc, const char **argv) 4196{ 4197 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4198 const char *msg = "This machine will be shutdown shortly"; 4199 uint32 timeout = 20; 4200 4201 if (opt_comment) { 4202 msg = opt_comment; 4203 } 4204 if (opt_timeout) { 4205 timeout = opt_timeout; 4206 } 4207 4208 /* create an entry */ 4209 result = cli_shutdown_init(cli, mem_ctx, msg, timeout, opt_reboot, 4210 opt_force); 4211 4212 if (NT_STATUS_IS_OK(result)) { 4213 d_printf("\nShutdown of remote machine succeeded\n"); 4214 DEBUG(5,("Shutdown of remote machine succeeded\n")); 4215 } else 4216 DEBUG(0,("Shutdown of remote machine failed!\n")); 4217 4218 return result; 4219} 4220 4221/** 4222 * Shut down a remote RPC Server via winreg pipe 4223 * 4224 * All parameters are provided by the run_rpc_command function, except for 4225 * argc, argv which are passes through. 4226 * 4227 * @param domain_sid The domain sid aquired from the remote server 4228 * @param cli A cli_state connected to the server. 4229 * @param mem_ctx Talloc context, destoyed on compleation of the function. 4230 * @param argc Standard main() style argc 4231 * @param argc Standard main() style argv. Initial components are already 4232 * stripped 4233 * 4234 * @return Normal NTSTATUS return. 4235 **/ 4236 4237static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid, 4238 const char *domain_name, 4239 struct cli_state *cli, 4240 TALLOC_CTX *mem_ctx, 4241 int argc, const char **argv) 4242{ 4243 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4244 const char *msg = "This machine will be shutdown shortly"; 4245 uint32 timeout = 20; 4246#if 0 4247 poptContext pc; 4248 int rc; 4249 4250 struct poptOption long_options[] = { 4251 {"message", 'm', POPT_ARG_STRING, &msg}, 4252 {"timeout", 't', POPT_ARG_INT, &timeout}, 4253 {"reboot", 'r', POPT_ARG_NONE, &reboot}, 4254 {"force", 'f', POPT_ARG_NONE, &force}, 4255 { 0, 0, 0, 0} 4256 }; 4257 4258 pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 4259 POPT_CONTEXT_KEEP_FIRST); 4260 4261 rc = poptGetNextOpt(pc); 4262 4263 if (rc < -1) { 4264 /* an error occurred during option processing */ 4265 DEBUG(0, ("%s: %s\n", 4266 poptBadOption(pc, POPT_BADOPTION_NOALIAS), 4267 poptStrerror(rc))); 4268 return NT_STATUS_INVALID_PARAMETER; 4269 } 4270#endif 4271 if (opt_comment) { 4272 msg = opt_comment; 4273 } 4274 if (opt_timeout) { 4275 timeout = opt_timeout; 4276 } 4277 4278 /* create an entry */ 4279 result = werror_to_ntstatus(cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force)); 4280 4281 if (NT_STATUS_IS_OK(result)) { 4282 d_printf("\nShutdown of remote machine succeeded\n"); 4283 DEBUG(5,("Shutdown of remote machine succeeded\n")); 4284 } 4285 else 4286 DEBUG(0,("Shutdown of remote machine failed!\n")); 4287 4288 return result; 4289} 4290 4291/** 4292 * Shut down a remote RPC server 4293 * 4294 * @param argc Standard main() style argc 4295 * @param argc Standard main() style argv. Initial components are already 4296 * stripped 4297 * 4298 * @return A shell status integer (0 for success) 4299 **/ 4300 4301static int rpc_shutdown(int argc, const char **argv) 4302{ 4303 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0, 4304 rpc_init_shutdown_internals, 4305 argc, argv); 4306 if (rc == 0) 4307 return rc; 4308 4309 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n")); 4310 4311 return run_rpc_command(NULL, PI_WINREG, 0, rpc_reg_shutdown_internals, 4312 argc, argv); 4313} 4314 4315/*************************************************************************** 4316 NT Domain trusts code (i.e. 'net rpc trustdom' functionality) 4317 4318 ***************************************************************************/ 4319 4320/** 4321 * Add interdomain trust account to the RPC server. 4322 * All parameters (except for argc and argv) are passed by run_rpc_command 4323 * function. 4324 * 4325 * @param domain_sid The domain sid acquired from the server 4326 * @param cli A cli_state connected to the server. 4327 * @param mem_ctx Talloc context, destoyed on completion of the function. 4328 * @param argc Standard main() style argc 4329 * @param argc Standard main() style argv. Initial components are already 4330 * stripped 4331 * 4332 * @return normal NTSTATUS return code 4333 */ 4334 4335static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, 4336 const char *domain_name, 4337 struct cli_state *cli, TALLOC_CTX *mem_ctx, 4338 int argc, const char **argv) { 4339 4340 POLICY_HND connect_pol, domain_pol, user_pol; 4341 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4342 char *acct_name; 4343 uint16 acb_info; 4344 uint32 unknown, user_rid; 4345 4346 if (argc != 2) { 4347 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n"); 4348 return NT_STATUS_INVALID_PARAMETER; 4349 } 4350 4351 /* 4352 * Make valid trusting domain account (ie. uppercased and with '$' appended) 4353 */ 4354 4355 if (asprintf(&acct_name, "%s$", argv[0]) < 0) { 4356 return NT_STATUS_NO_MEMORY; 4357 } 4358 4359 strupper_m(acct_name); 4360 4361 /* Get samr policy handle */ 4362 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 4363 &connect_pol); 4364 if (!NT_STATUS_IS_OK(result)) { 4365 goto done; 4366 } 4367 4368 /* Get domain policy handle */ 4369 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 4370 MAXIMUM_ALLOWED_ACCESS, 4371 domain_sid, &domain_pol); 4372 if (!NT_STATUS_IS_OK(result)) { 4373 goto done; 4374 } 4375 4376 /* Create trusting domain's account */ 4377 acb_info = ACB_NORMAL; 4378 unknown = 0xe00500b0; /* No idea what this is - a permission mask? 4379 mimir: yes, most probably it is */ 4380 4381 result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol, 4382 acct_name, acb_info, unknown, 4383 &user_pol, &user_rid); 4384 if (!NT_STATUS_IS_OK(result)) { 4385 goto done; 4386 } 4387 4388 { 4389 SAM_USERINFO_CTR ctr; 4390 SAM_USER_INFO_23 p23; 4391 NTTIME notime; 4392 char nostr[] = ""; 4393 LOGON_HRS hrs; 4394 uchar pwbuf[516]; 4395 4396 encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE); 4397 4398 ZERO_STRUCT(ctr); 4399 ZERO_STRUCT(p23); 4400 ZERO_STRUCT(notime); 4401 hrs.max_len = 1260; 4402 hrs.offset = 0; 4403 hrs.len = 21; 4404 memset(hrs.hours, 0xFF, sizeof(hrs.hours)); 4405 acb_info = ACB_DOMTRUST; 4406 4407 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime, 4408 ¬ime, ¬ime, ¬ime, 4409 nostr, nostr, nostr, nostr, nostr, 4410 nostr, nostr, nostr, nostr, nostr, 4411 0, 0, acb_info, ACCT_FLAGS, 168, &hrs, 4412 0, 0, (char *)pwbuf); 4413 ctr.switch_value = 23; 4414 ctr.info.id23 = &p23; 4415 p23.passmustchange = 0; 4416 4417 result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 23, 4418 &cli->user_session_key, &ctr); 4419 4420 if (!NT_STATUS_IS_OK(result)) { 4421 DEBUG(0,("Could not set trust account password: %s\n", 4422 nt_errstr(result))); 4423 goto done; 4424 } 4425 } 4426 4427 done: 4428 SAFE_FREE(acct_name); 4429 return result; 4430} 4431 4432/** 4433 * Create interdomain trust account for a remote domain. 4434 * 4435 * @param argc standard argc 4436 * @param argv standard argv without initial components 4437 * 4438 * @return Integer status (0 means success) 4439 **/ 4440 4441static int rpc_trustdom_add(int argc, const char **argv) 4442{ 4443 if (argc > 0) { 4444 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals, 4445 argc, argv); 4446 } else { 4447 d_printf("Usage: net rpc trustdom add <domain>\n"); 4448 return -1; 4449 } 4450} 4451 4452/** 4453 * Remove interdomain trust account from the RPC server. 4454 * All parameters (except for argc and argv) are passed by run_rpc_command 4455 * function. 4456 * 4457 * @param domain_sid The domain sid acquired from the server 4458 * @param cli A cli_state connected to the server. 4459 * @param mem_ctx Talloc context, destoyed on completion of the function. 4460 * @param argc Standard main() style argc 4461 * @param argc Standard main() style argv. Initial components are already 4462 * stripped 4463 * 4464 * @return normal NTSTATUS return code 4465 */ 4466 4467static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid, 4468 const char *domain_name, 4469 struct cli_state *cli, TALLOC_CTX *mem_ctx, 4470 int argc, const char **argv) { 4471 4472 POLICY_HND connect_pol, domain_pol, user_pol; 4473 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 4474 char *acct_name; 4475 DOM_SID trust_acct_sid; 4476 uint32 *user_rids, num_rids, *name_types; 4477 uint32 flags = 0x000003e8; /* Unknown */ 4478 4479 if (argc != 1) { 4480 d_printf("Usage: net rpc trustdom del <domain_name>\n"); 4481 return NT_STATUS_INVALID_PARAMETER; 4482 } 4483 4484 /* 4485 * Make valid trusting domain account (ie. uppercased and with '$' appended) 4486 */ 4487 4488 if (asprintf(&acct_name, "%s$", argv[0]) < 0) { 4489 return NT_STATUS_NO_MEMORY; 4490 } 4491 4492 strupper_m(acct_name); 4493 4494 /* Get samr policy handle */ 4495 result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 4496 &connect_pol); 4497 if (!NT_STATUS_IS_OK(result)) { 4498 goto done; 4499 } 4500 4501 /* Get domain policy handle */ 4502 result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, 4503 MAXIMUM_ALLOWED_ACCESS, 4504 domain_sid, &domain_pol); 4505 if (!NT_STATUS_IS_OK(result)) { 4506 goto done; 4507 } 4508 4509 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, 1, 4510 &acct_name, &num_rids, &user_rids, 4511 &name_types); 4512 4513 if (!NT_STATUS_IS_OK(result)) { 4514 goto done; 4515 } 4516 4517 result = cli_samr_open_user(cli, mem_ctx, &domain_pol, 4518 MAXIMUM_ALLOWED_ACCESS, 4519 user_rids[0], &user_pol); 4520 4521 if (!NT_STATUS_IS_OK(result)) { 4522 goto done; 4523 } 4524 4525 /* append the rid to the domain sid */ 4526 sid_copy(&trust_acct_sid, domain_sid); 4527 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) { 4528 goto done; 4529 } 4530 4531 /* remove the sid */ 4532 4533 result = cli_samr_remove_sid_foreign_domain(cli, mem_ctx, &user_pol, 4534 &trust_acct_sid); 4535 4536 if (!NT_STATUS_IS_OK(result)) { 4537 goto done; 4538 } 4539 4540 /* Delete user */ 4541 4542 result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol); 4543 4544 if (!NT_STATUS_IS_OK(result)) { 4545 goto done; 4546 } 4547 4548 if (!NT_STATUS_IS_OK(result)) { 4549 DEBUG(0,("Could not set trust account password: %s\n", 4550 nt_errstr(result))); 4551 goto done; 4552 } 4553 4554 done: 4555 SAFE_FREE(acct_name); 4556 return result; 4557} 4558 4559/** 4560 * Delete interdomain trust account for a remote domain. 4561 * 4562 * @param argc standard argc 4563 * @param argv standard argv without initial components 4564 * 4565 * @return Integer status (0 means success) 4566 **/ 4567 4568static int rpc_trustdom_del(int argc, const char **argv) 4569{ 4570 if (argc > 0) { 4571 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals, 4572 argc, argv); 4573 } else { 4574 d_printf("Usage: net rpc trustdom del <domain>\n"); 4575 return -1; 4576 } 4577} 4578 4579/** 4580 * Establish trust relationship to a trusting domain. 4581 * Interdomain account must already be created on remote PDC. 4582 * 4583 * @param argc standard argc 4584 * @param argv standard argv without initial components 4585 * 4586 * @return Integer status (0 means success) 4587 **/ 4588 4589static int rpc_trustdom_establish(int argc, const char **argv) 4590{ 4591 struct cli_state *cli; 4592 struct in_addr server_ip; 4593 POLICY_HND connect_hnd; 4594 TALLOC_CTX *mem_ctx; 4595 NTSTATUS nt_status; 4596 DOM_SID *domain_sid; 4597 WKS_INFO_100 wks_info; 4598 4599 char* domain_name; 4600 char* domain_name_pol; 4601 char* acct_name; 4602 fstring pdc_name; 4603 4604 /* 4605 * Connect to \\server\ipc$ as 'our domain' account with password 4606 */ 4607 4608 if (argc != 1) { 4609 d_printf("Usage: net rpc trustdom establish <domain_name>\n"); 4610 return -1; 4611 } 4612 4613 domain_name = smb_xstrdup(argv[0]); 4614 strupper_m(domain_name); 4615 4616 /* account name used at first is our domain's name with '$' */ 4617 asprintf(&acct_name, "%s$", lp_workgroup()); 4618 strupper_m(acct_name); 4619 4620 /* 4621 * opt_workgroup will be used by connection functions further, 4622 * hence it should be set to remote domain name instead of ours 4623 */ 4624 if (opt_workgroup) { 4625 opt_workgroup = smb_xstrdup(domain_name); 4626 }; 4627 4628 opt_user_name = acct_name; 4629 4630 /* find the domain controller */ 4631 if (!net_find_pdc(&server_ip, pdc_name, domain_name)) { 4632 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name)); 4633 return -1; 4634 } 4635 4636 /* connect to ipc$ as username/password */ 4637 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name); 4638 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) { 4639 4640 /* Is it trusting domain account for sure ? */ 4641 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n", 4642 nt_errstr(nt_status))); 4643 return -1; 4644 } 4645 4646 /* 4647 * Connect to \\server\ipc$ again (this time anonymously) 4648 */ 4649 4650 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name); 4651 4652 if (NT_STATUS_IS_ERR(nt_status)) { 4653 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n", 4654 domain_name, nt_errstr(nt_status))); 4655 } 4656 4657 /* 4658 * Use NetServerEnum2 to make sure we're talking to a proper server 4659 */ 4660 4661 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) { 4662 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\ 4663 for domain %s\n", domain_name)); 4664 } 4665 4666 /* 4667 * Call WksQueryInfo to check remote server's capabilities 4668 * note: It is now used only to get unicode domain name 4669 */ 4670 4671 if (!cli_nt_session_open(cli, PI_WKSSVC)) { 4672 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n")); 4673 return -1; 4674 } 4675 4676 if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s", 4677 domain_name))) { 4678 DEBUG(0, ("talloc_init() failed\n")); 4679 cli_shutdown(cli); 4680 return -1; 4681 } 4682 4683 nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info); 4684 4685 if (NT_STATUS_IS_ERR(nt_status)) { 4686 DEBUG(0, ("WksQueryInfo call failed.\n")); 4687 return -1; 4688 } 4689 4690 if (cli->nt_pipe_fnum[cli->pipe_idx]) 4691 cli_nt_session_close(cli); 4692 4693 4694 /* 4695 * Call LsaOpenPolicy and LsaQueryInfo 4696 */ 4697 4698 if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) { 4699 DEBUG(0, ("talloc_init() failed\n")); 4700 cli_shutdown(cli); 4701 return -1; 4702 } 4703 4704 if (!cli_nt_session_open(cli, PI_LSARPC)) { 4705 DEBUG(0, ("Could not initialise lsa pipe\n")); 4706 cli_shutdown(cli); 4707 return -1; 4708 } 4709 4710 nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, 4711 &connect_hnd); 4712 if (NT_STATUS_IS_ERR(nt_status)) { 4713 DEBUG(0, ("Couldn't open policy handle. Error was %s\n", 4714 nt_errstr(nt_status))); 4715 return -1; 4716 } 4717 4718 /* Querying info level 5 */ 4719 4720 nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd, 4721 5 /* info level */, &domain_name_pol, 4722 &domain_sid); 4723 if (NT_STATUS_IS_ERR(nt_status)) { 4724 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", 4725 nt_errstr(nt_status))); 4726 return -1; 4727 } 4728 4729 4730 4731 4732 /* There should be actually query info level 3 (following nt serv behaviour), 4733 but I still don't know if it's _really_ necessary */ 4734 4735 /* 4736 * Store the password in secrets db 4737 */ 4738 4739 if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer, 4740 wks_info.uni_lan_grp.uni_str_len, opt_password, 4741 *domain_sid)) { 4742 DEBUG(0, ("Storing password for trusted domain failed.\n")); 4743 return -1; 4744 } 4745 4746 /* 4747 * Close the pipes and clean up 4748 */ 4749 4750 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd); 4751 if (NT_STATUS_IS_ERR(nt_status)) { 4752 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n", 4753 nt_errstr(nt_status))); 4754 return -1; 4755 } 4756 4757 if (cli->nt_pipe_fnum[cli->pipe_idx]) 4758 cli_nt_session_close(cli); 4759 4760 talloc_destroy(mem_ctx); 4761 4762 d_printf("Trust to domain %s established\n", domain_name); 4763 return 0; 4764} 4765 4766/** 4767 * Revoke trust relationship to the remote domain 4768 * 4769 * @param argc standard argc 4770 * @param argv standard argv without initial components 4771 * 4772 * @return Integer status (0 means success) 4773 **/ 4774 4775static int rpc_trustdom_revoke(int argc, const char **argv) 4776{ 4777 char* domain_name; 4778 4779 if (argc < 1) return -1; 4780 4781 /* generate upper cased domain name */ 4782 domain_name = smb_xstrdup(argv[0]); 4783 strupper_m(domain_name); 4784 4785 /* delete password of the trust */ 4786 if (!trusted_domain_password_delete(domain_name)) { 4787 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n", 4788 domain_name)); 4789 return -1; 4790 }; 4791 4792 return 0; 4793} 4794 4795/** 4796 * Usage for 'net rpc trustdom' command 4797 * 4798 * @param argc standard argc 4799 * @param argv standard argv without inital components 4800 * 4801 * @return Integer status returned to shell 4802 **/ 4803 4804static int rpc_trustdom_usage(int argc, const char **argv) 4805{ 4806 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n"); 4807 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n"); 4808 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n"); 4809 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n"); 4810 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n"); 4811 return -1; 4812} 4813 4814 4815static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, 4816 const char *domain_name, 4817 struct cli_state *cli, TALLOC_CTX *mem_ctx, 4818 int argc, const char **argv) 4819{ 4820 fstring str_sid; 4821 sid_to_string(str_sid, domain_sid); 4822 d_printf("%s\n", str_sid); 4823 return NT_STATUS_OK; 4824} 4825 4826 4827static int rpc_trustdom_list(int argc, const char **argv) 4828{ 4829 /* common variables */ 4830 TALLOC_CTX* mem_ctx; 4831 struct cli_state *cli, *remote_cli; 4832 NTSTATUS nt_status; 4833 const char *domain_name = NULL; 4834 DOM_SID *queried_dom_sid; 4835 fstring ascii_sid, padding; 4836 int ascii_dom_name_len; 4837 POLICY_HND connect_hnd; 4838 4839 /* trusted domains listing variables */ 4840 unsigned int num_domains, enum_ctx = 0; 4841 int i, pad_len, col_len = 20; 4842 DOM_SID *domain_sids; 4843 char **trusted_dom_names; 4844 fstring pdc_name; 4845 char *dummy; 4846 4847 /* trusting domains listing variables */ 4848 POLICY_HND domain_hnd; 4849 char **trusting_dom_names; 4850 uint32 *trusting_dom_rids; 4851 4852 /* 4853 * Listing trusted domains (stored in secrets.tdb, if local) 4854 */ 4855 4856 mem_ctx = talloc_init("trust relationships listing"); 4857 4858 /* 4859 * set domain and pdc name to local samba server (default) 4860 * or to remote one given in command line 4861 */ 4862 4863 if (StrCaseCmp(opt_workgroup, lp_workgroup())) { 4864 domain_name = opt_workgroup; 4865 opt_target_workgroup = opt_workgroup; 4866 } else { 4867 fstrcpy(pdc_name, global_myname()); 4868 domain_name = talloc_strdup(mem_ctx, lp_workgroup()); 4869 opt_target_workgroup = domain_name; 4870 }; 4871 4872 /* open \PIPE\lsarpc and open policy handle */ 4873 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) { 4874 DEBUG(0, ("Couldn't connect to domain controller\n")); 4875 return -1; 4876 }; 4877 4878 if (!cli_nt_session_open(cli, PI_LSARPC)) { 4879 DEBUG(0, ("Could not initialise lsa pipe\n")); 4880 return -1; 4881 }; 4882 4883 nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE, 4884 &connect_hnd); 4885 if (NT_STATUS_IS_ERR(nt_status)) { 4886 DEBUG(0, ("Couldn't open policy handle. Error was %s\n", 4887 nt_errstr(nt_status))); 4888 return -1; 4889 }; 4890 4891 /* query info level 5 to obtain sid of a domain being queried */ 4892 nt_status = cli_lsa_query_info_policy( 4893 cli, mem_ctx, &connect_hnd, 5 /* info level */, 4894 &dummy, &queried_dom_sid); 4895 4896 if (NT_STATUS_IS_ERR(nt_status)) { 4897 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n", 4898 nt_errstr(nt_status))); 4899 return -1; 4900 } 4901 4902 /* 4903 * Keep calling LsaEnumTrustdom over opened pipe until 4904 * the end of enumeration is reached 4905 */ 4906 4907 d_printf("Trusted domains list:\n\n"); 4908 4909 do { 4910 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx, 4911 &num_domains, 4912 &trusted_dom_names, &domain_sids); 4913 4914 if (NT_STATUS_IS_ERR(nt_status)) { 4915 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n", 4916 nt_errstr(nt_status))); 4917 return -1; 4918 }; 4919 4920 for (i = 0; i < num_domains; i++) { 4921 /* convert sid into ascii string */ 4922 sid_to_string(ascii_sid, &(domain_sids[i])); 4923 4924 /* calculate padding space for d_printf to look nicer */ 4925 pad_len = col_len - strlen(trusted_dom_names[i]); 4926 padding[pad_len] = 0; 4927 do padding[--pad_len] = ' '; while (pad_len); 4928 4929 d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid); 4930 }; 4931 4932 /* 4933 * in case of no trusted domains say something rather 4934 * than just display blank line 4935 */ 4936 if (!num_domains) d_printf("none\n"); 4937 4938 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); 4939 4940 /* close this connection before doing next one */ 4941 nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd); 4942 if (NT_STATUS_IS_ERR(nt_status)) { 4943 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n", 4944 nt_errstr(nt_status))); 4945 return -1; 4946 }; 4947 4948 cli_nt_session_close(cli); 4949 4950 /* 4951 * Listing trusting domains (stored in passdb backend, if local) 4952 */ 4953 4954 d_printf("\nTrusting domains list:\n\n"); 4955 4956 /* 4957 * Open \PIPE\samr and get needed policy handles 4958 */ 4959 if (!cli_nt_session_open(cli, PI_SAMR)) { 4960 DEBUG(0, ("Could not initialise samr pipe\n")); 4961 return -1; 4962 }; 4963 4964 /* SamrConnect */ 4965 nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN, 4966 &connect_hnd); 4967 if (!NT_STATUS_IS_OK(nt_status)) { 4968 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n", 4969 nt_errstr(nt_status))); 4970 return -1; 4971 }; 4972 4973 /* SamrOpenDomain - we have to open domain policy handle in order to be 4974 able to enumerate accounts*/ 4975 nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd, 4976 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 4977 queried_dom_sid, &domain_hnd); 4978 if (!NT_STATUS_IS_OK(nt_status)) { 4979 DEBUG(0, ("Couldn't open domain object. Error was %s\n", 4980 nt_errstr(nt_status))); 4981 return -1; 4982 }; 4983 4984 /* 4985 * perform actual enumeration 4986 */ 4987 4988 enum_ctx = 0; /* reset enumeration context from last enumeration */ 4989 do { 4990 4991 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd, 4992 &enum_ctx, ACB_DOMTRUST, 0xffff, 4993 &trusting_dom_names, &trusting_dom_rids, 4994 &num_domains); 4995 if (NT_STATUS_IS_ERR(nt_status)) { 4996 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n", 4997 nt_errstr(nt_status))); 4998 return -1; 4999 }; 5000 5001 for (i = 0; i < num_domains; i++) { 5002 5003 /* 5004 * get each single domain's sid (do we _really_ need this ?): 5005 * 1) connect to domain's pdc 5006 * 2) query the pdc for domain's sid 5007 */ 5008 5009 /* get rid of '$' tail */ 5010 ascii_dom_name_len = strlen(trusting_dom_names[i]); 5011 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN) 5012 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0'; 5013 5014 /* calculate padding space for d_printf to look nicer */ 5015 pad_len = col_len - strlen(trusting_dom_names[i]); 5016 padding[pad_len] = 0; 5017 do padding[--pad_len] = ' '; while (pad_len); 5018 5019 /* set opt_* variables to remote domain */ 5020 strupper_m(trusting_dom_names[i]); 5021 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]); 5022 opt_target_workgroup = opt_workgroup; 5023 5024 d_printf("%s%s", trusting_dom_names[i], padding); 5025 5026 /* connect to remote domain controller */ 5027 remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS); 5028 if (remote_cli) { 5029 /* query for domain's sid */ 5030 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv)) 5031 d_printf("couldn't get domain's sid\n"); 5032 5033 cli_shutdown(remote_cli); 5034 5035 } else { 5036 d_printf("domain controller is not responding\n"); 5037 }; 5038 }; 5039 5040 if (!num_domains) d_printf("none\n"); 5041 5042 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); 5043 5044 /* close opened samr and domain policy handles */ 5045 nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd); 5046 if (!NT_STATUS_IS_OK(nt_status)) { 5047 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name)); 5048 }; 5049 5050 nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd); 5051 if (!NT_STATUS_IS_OK(nt_status)) { 5052 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name)); 5053 }; 5054 5055 /* close samr pipe and connection to IPC$ */ 5056 cli_nt_session_close(cli); 5057 cli_shutdown(cli); 5058 5059 talloc_destroy(mem_ctx); 5060 return 0; 5061} 5062 5063/** 5064 * Entrypoint for 'net rpc trustdom' code 5065 * 5066 * @param argc standard argc 5067 * @param argv standard argv without initial components 5068 * 5069 * @return Integer status (0 means success) 5070 */ 5071 5072static int rpc_trustdom(int argc, const char **argv) 5073{ 5074 struct functable func[] = { 5075 {"add", rpc_trustdom_add}, 5076 {"del", rpc_trustdom_del}, 5077 {"establish", rpc_trustdom_establish}, 5078 {"revoke", rpc_trustdom_revoke}, 5079 {"help", rpc_trustdom_usage}, 5080 {"list", rpc_trustdom_list}, 5081 {NULL, NULL} 5082 }; 5083 5084 if (argc == 0) { 5085 rpc_trustdom_usage(argc, argv); 5086 return -1; 5087 } 5088 5089 return (net_run_function(argc, argv, func, rpc_user_usage)); 5090} 5091 5092/** 5093 * Check if a server will take rpc commands 5094 * @param flags Type of server to connect to (PDC, DMB, localhost) 5095 * if the host is not explicitly specified 5096 * @return BOOL (true means rpc supported) 5097 */ 5098BOOL net_rpc_check(unsigned flags) 5099{ 5100 struct cli_state cli; 5101 BOOL ret = False; 5102 struct in_addr server_ip; 5103 char *server_name = NULL; 5104 5105 /* flags (i.e. server type) may depend on command */ 5106 if (!net_find_server(flags, &server_ip, &server_name)) 5107 return False; 5108 5109 ZERO_STRUCT(cli); 5110 if (cli_initialise(&cli) == False) 5111 return False; 5112 5113 if (!cli_connect(&cli, server_name, &server_ip)) 5114 goto done; 5115 if (!attempt_netbios_session_request(&cli, global_myname(), 5116 server_name, &server_ip)) 5117 goto done; 5118 if (!cli_negprot(&cli)) 5119 goto done; 5120 if (cli.protocol < PROTOCOL_NT1) 5121 goto done; 5122 5123 ret = True; 5124 done: 5125 cli_shutdown(&cli); 5126 return ret; 5127} 5128 5129/* dump sam database via samsync rpc calls */ 5130static int rpc_samdump(int argc, const char **argv) { 5131 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals, 5132 argc, argv); 5133} 5134 5135/* syncronise sam database via samsync rpc calls */ 5136static int rpc_vampire(int argc, const char **argv) { 5137 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals, 5138 argc, argv); 5139} 5140 5141/** 5142 * Migrate everything from a print-server 5143 * 5144 * @param argc Standard main() style argc 5145 * @param argv Standard main() style argv. Initial components are already 5146 * stripped 5147 * 5148 * @return A shell status integer (0 for success) 5149 * 5150 * The order is important ! 5151 * To successfully add drivers the print-queues have to exist ! 5152 * Applying ACLs should be the last step, because you're easily locked out 5153 * 5154 **/ 5155static int rpc_printer_migrate_all(int argc, const char **argv) 5156{ 5157 int ret; 5158 5159 if (!opt_host) { 5160 printf("no server to migrate\n"); 5161 return -1; 5162 } 5163 5164 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv); 5165 if (ret) 5166 return ret; 5167 5168 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv); 5169 if (ret) 5170 return ret; 5171 5172 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv); 5173 if (ret) 5174 return ret; 5175 5176 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv); 5177 if (ret) 5178 return ret; 5179 5180 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv); 5181 5182} 5183 5184/** 5185 * Migrate print-drivers from a print-server 5186 * 5187 * @param argc Standard main() style argc 5188 * @param argv Standard main() style argv. Initial components are already 5189 * stripped 5190 * 5191 * @return A shell status integer (0 for success) 5192 **/ 5193static int rpc_printer_migrate_drivers(int argc, const char **argv) 5194{ 5195 if (!opt_host) { 5196 printf("no server to migrate\n"); 5197 return -1; 5198 } 5199 5200 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5201 rpc_printer_migrate_drivers_internals, 5202 argc, argv); 5203} 5204 5205/** 5206 * Migrate print-forms from a print-server 5207 * 5208 * @param argc Standard main() style argc 5209 * @param argv Standard main() style argv. Initial components are already 5210 * stripped 5211 * 5212 * @return A shell status integer (0 for success) 5213 **/ 5214static int rpc_printer_migrate_forms(int argc, const char **argv) 5215{ 5216 if (!opt_host) { 5217 printf("no server to migrate\n"); 5218 return -1; 5219 } 5220 5221 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5222 rpc_printer_migrate_forms_internals, 5223 argc, argv); 5224} 5225 5226/** 5227 * Migrate printers from a print-server 5228 * 5229 * @param argc Standard main() style argc 5230 * @param argv Standard main() style argv. Initial components are already 5231 * stripped 5232 * 5233 * @return A shell status integer (0 for success) 5234 **/ 5235static int rpc_printer_migrate_printers(int argc, const char **argv) 5236{ 5237 if (!opt_host) { 5238 printf("no server to migrate\n"); 5239 return -1; 5240 } 5241 5242 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5243 rpc_printer_migrate_printers_internals, 5244 argc, argv); 5245} 5246 5247/** 5248 * Migrate printer-ACLs from a print-server 5249 * 5250 * @param argc Standard main() style argc 5251 * @param argv Standard main() style argv. Initial components are already 5252 * stripped 5253 * 5254 * @return A shell status integer (0 for success) 5255 **/ 5256static int rpc_printer_migrate_security(int argc, const char **argv) 5257{ 5258 if (!opt_host) { 5259 printf("no server to migrate\n"); 5260 return -1; 5261 } 5262 5263 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5264 rpc_printer_migrate_security_internals, 5265 argc, argv); 5266} 5267 5268/** 5269 * Migrate printer-settings from a print-server 5270 * 5271 * @param argc Standard main() style argc 5272 * @param argv Standard main() style argv. Initial components are already 5273 * stripped 5274 * 5275 * @return A shell status integer (0 for success) 5276 **/ 5277static int rpc_printer_migrate_settings(int argc, const char **argv) 5278{ 5279 if (!opt_host) { 5280 printf("no server to migrate\n"); 5281 return -1; 5282 } 5283 5284 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5285 rpc_printer_migrate_settings_internals, 5286 argc, argv); 5287} 5288 5289/** 5290 * 'net rpc printer' entrypoint. 5291 * @param argc Standard main() style argc 5292 * @param argv Standard main() style argv. Initial components are already 5293 * stripped 5294 **/ 5295 5296int rpc_printer_migrate(int argc, const char **argv) 5297{ 5298 5299 /* ouch: when addriver and setdriver are called from within 5300 rpc_printer_migrate_drivers_internals, the printer-queue already 5301 *has* to exist */ 5302 5303 struct functable func[] = { 5304 {"all", rpc_printer_migrate_all}, 5305 {"drivers", rpc_printer_migrate_drivers}, 5306 {"forms", rpc_printer_migrate_forms}, 5307 {"help", rpc_printer_usage}, 5308 {"printers", rpc_printer_migrate_printers}, 5309 {"security", rpc_printer_migrate_security}, 5310 {"settings", rpc_printer_migrate_settings}, 5311 {NULL, NULL} 5312 }; 5313 5314 return net_run_function(argc, argv, func, rpc_printer_usage); 5315} 5316 5317 5318/** 5319 * List printers on a remote RPC server 5320 * 5321 * @param argc Standard main() style argc 5322 * @param argv Standard main() style argv. Initial components are already 5323 * stripped 5324 * 5325 * @return A shell status integer (0 for success) 5326 **/ 5327static int rpc_printer_list(int argc, const char **argv) 5328{ 5329 5330 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5331 rpc_printer_list_internals, 5332 argc, argv); 5333} 5334 5335/** 5336 * List printer-drivers on a remote RPC server 5337 * 5338 * @param argc Standard main() style argc 5339 * @param argv Standard main() style argv. Initial components are already 5340 * stripped 5341 * 5342 * @return A shell status integer (0 for success) 5343 **/ 5344static int rpc_printer_driver_list(int argc, const char **argv) 5345{ 5346 5347 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5348 rpc_printer_driver_list_internals, 5349 argc, argv); 5350} 5351 5352/** 5353 * Publish printer in ADS via MSRPC 5354 * 5355 * @param argc Standard main() style argc 5356 * @param argv Standard main() style argv. Initial components are already 5357 * stripped 5358 * 5359 * @return A shell status integer (0 for success) 5360 **/ 5361static int rpc_printer_publish_publish(int argc, const char **argv) 5362{ 5363 5364 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5365 rpc_printer_publish_publish_internals, 5366 argc, argv); 5367} 5368 5369/** 5370 * Update printer in ADS via MSRPC 5371 * 5372 * @param argc Standard main() style argc 5373 * @param argv Standard main() style argv. Initial components are already 5374 * stripped 5375 * 5376 * @return A shell status integer (0 for success) 5377 **/ 5378static int rpc_printer_publish_update(int argc, const char **argv) 5379{ 5380 5381 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5382 rpc_printer_publish_update_internals, 5383 argc, argv); 5384} 5385 5386/** 5387 * UnPublish printer in ADS via MSRPC 5388 * 5389 * @param argc Standard main() style argc 5390 * @param argv Standard main() style argv. Initial components are already 5391 * stripped 5392 * 5393 * @return A shell status integer (0 for success) 5394 **/ 5395static int rpc_printer_publish_unpublish(int argc, const char **argv) 5396{ 5397 5398 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5399 rpc_printer_publish_unpublish_internals, 5400 argc, argv); 5401} 5402 5403/** 5404 * List published printers via MSRPC 5405 * 5406 * @param argc Standard main() style argc 5407 * @param argv Standard main() style argv. Initial components are already 5408 * stripped 5409 * 5410 * @return A shell status integer (0 for success) 5411 **/ 5412static int rpc_printer_publish_list(int argc, const char **argv) 5413{ 5414 5415 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5416 rpc_printer_publish_list_internals, 5417 argc, argv); 5418} 5419 5420 5421/** 5422 * Publish printer in ADS 5423 * 5424 * @param argc Standard main() style argc 5425 * @param argv Standard main() style argv. Initial components are already 5426 * stripped 5427 * 5428 * @return A shell status integer (0 for success) 5429 **/ 5430static int rpc_printer_publish(int argc, const char **argv) 5431{ 5432 5433 struct functable func[] = { 5434 {"publish", rpc_printer_publish_publish}, 5435 {"update", rpc_printer_publish_update}, 5436 {"unpublish", rpc_printer_publish_unpublish}, 5437 {"list", rpc_printer_publish_list}, 5438 {"help", rpc_printer_usage}, 5439 {NULL, NULL} 5440 }; 5441 5442 if (argc == 0) 5443 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5444 rpc_printer_publish_list_internals, 5445 argc, argv); 5446 5447 return net_run_function(argc, argv, func, rpc_printer_usage); 5448 5449} 5450 5451 5452/** 5453 * Display rpc printer help page. 5454 * @param argc Standard main() style argc 5455 * @param argv Standard main() style argv. Initial components are already 5456 * stripped 5457 **/ 5458int rpc_printer_usage(int argc, const char **argv) 5459{ 5460 return net_help_printer(argc, argv); 5461} 5462 5463/** 5464 * 'net rpc printer' entrypoint. 5465 * @param argc Standard main() style argc 5466 * @param argv Standard main() style argv. Initial components are already 5467 * stripped 5468 **/ 5469int net_rpc_printer(int argc, const char **argv) 5470{ 5471 struct functable func[] = { 5472 {"list", rpc_printer_list}, 5473 {"migrate", rpc_printer_migrate}, 5474 {"driver", rpc_printer_driver_list}, 5475 {"publish", rpc_printer_publish}, 5476 {NULL, NULL} 5477 }; 5478 5479 if (argc == 0) 5480 return run_rpc_command(NULL, PI_SPOOLSS, 0, 5481 rpc_printer_list_internals, 5482 argc, argv); 5483 5484 return net_run_function(argc, argv, func, rpc_printer_usage); 5485} 5486 5487/****************************************************************************/ 5488 5489 5490/** 5491 * Basic usage function for 'net rpc' 5492 * @param argc Standard main() style argc 5493 * @param argv Standard main() style argv. Initial components are already 5494 * stripped 5495 **/ 5496 5497int net_rpc_usage(int argc, const char **argv) 5498{ 5499 d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); 5500 d_printf(" net rpc join \t\t\tto join a domain \n"); 5501 d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n"); 5502 d_printf(" net rpc testjoin \t\ttests that a join is valid\n"); 5503 d_printf(" net rpc user \t\t\tto add, delete and list users\n"); 5504 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n"); 5505 d_printf(" net rpc group \t\tto list groups\n"); 5506 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n"); 5507 d_printf(" net rpc printer \t\tto list and migrate printers\n"); 5508 d_printf(" net rpc file \t\t\tto list open files\n"); 5509 d_printf(" net rpc changetrustpw \tto change the trust account password\n"); 5510 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n"); 5511 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n"); 5512 d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n"); 5513 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n"); 5514 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n"); 5515 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n"); 5516 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n"); 5517 d_printf("\n"); 5518 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */ 5519 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n"); 5520 d_printf("\t-f or --force\trequest the remote server force its shutdown\n"); 5521 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n"); 5522 d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n"); 5523 return -1; 5524} 5525 5526 5527/** 5528 * Help function for 'net rpc'. Calls command specific help if requested 5529 * or displays usage of net rpc 5530 * @param argc Standard main() style argc 5531 * @param argv Standard main() style argv. Initial components are already 5532 * stripped 5533 **/ 5534 5535int net_rpc_help(int argc, const char **argv) 5536{ 5537 struct functable func[] = { 5538 {"join", rpc_join_usage}, 5539 {"user", rpc_user_usage}, 5540 {"group", rpc_group_usage}, 5541 {"share", rpc_share_usage}, 5542 /*{"changetrustpw", rpc_changetrustpw_usage}, */ 5543 {"trustdom", rpc_trustdom_usage}, 5544 /*{"abortshutdown", rpc_shutdown_abort_usage},*/ 5545 /*{"shutdown", rpc_shutdown_usage}, */ 5546 {NULL, NULL} 5547 }; 5548 5549 if (argc == 0) { 5550 net_rpc_usage(argc, argv); 5551 return -1; 5552 } 5553 5554 return (net_run_function(argc, argv, func, rpc_user_usage)); 5555} 5556 5557 5558/** 5559 * 'net rpc' entrypoint. 5560 * @param argc Standard main() style argc 5561 * @param argv Standard main() style argv. Initial components are already 5562 * stripped 5563 **/ 5564 5565int net_rpc(int argc, const char **argv) 5566{ 5567 struct functable func[] = { 5568 {"info", net_rpc_info}, 5569 {"join", net_rpc_join}, 5570 {"oldjoin", net_rpc_oldjoin}, 5571 {"testjoin", net_rpc_testjoin}, 5572 {"user", net_rpc_user}, 5573 {"password", rpc_user_password}, 5574 {"group", net_rpc_group}, 5575 {"share", net_rpc_share}, 5576 {"file", net_rpc_file}, 5577 {"printer", net_rpc_printer}, 5578 {"changetrustpw", net_rpc_changetrustpw}, 5579 {"trustdom", rpc_trustdom}, 5580 {"abortshutdown", rpc_shutdown_abort}, 5581 {"shutdown", rpc_shutdown}, 5582 {"samdump", rpc_samdump}, 5583 {"vampire", rpc_vampire}, 5584 {"getsid", net_rpc_getsid}, 5585 {"rights", net_rpc_rights}, 5586 {"help", net_rpc_help}, 5587 {NULL, NULL} 5588 }; 5589 return net_run_function(argc, argv, func, net_rpc_usage); 5590} 5591