00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024 #include "utils/net.h"
00025
00026 static int net_mode_share;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
00053 DOM_SID **domain_sid, char **domain_name)
00054 {
00055 struct rpc_pipe_client *lsa_pipe;
00056 POLICY_HND pol;
00057 NTSTATUS result = NT_STATUS_OK;
00058 uint32 info_class = 5;
00059
00060 lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
00061 if (!lsa_pipe) {
00062 d_fprintf(stderr, "Could not initialise lsa pipe\n");
00063 return result;
00064 }
00065
00066 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
00067 SEC_RIGHTS_MAXIMUM_ALLOWED,
00068 &pol);
00069 if (!NT_STATUS_IS_OK(result)) {
00070 d_fprintf(stderr, "open_policy failed: %s\n",
00071 nt_errstr(result));
00072 return result;
00073 }
00074
00075 result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol,
00076 info_class, domain_name,
00077 domain_sid);
00078 if (!NT_STATUS_IS_OK(result)) {
00079 d_fprintf(stderr, "lsaquery failed: %s\n",
00080 nt_errstr(result));
00081 return result;
00082 }
00083
00084 rpccli_lsa_close(lsa_pipe, mem_ctx, &pol);
00085 cli_rpc_pipe_close(lsa_pipe);
00086
00087 return NT_STATUS_OK;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 int run_rpc_command(struct cli_state *cli_arg,
00103 const int pipe_idx,
00104 int conn_flags,
00105 rpc_command_fn fn,
00106 int argc,
00107 const char **argv)
00108 {
00109 struct cli_state *cli = NULL;
00110 struct rpc_pipe_client *pipe_hnd = NULL;
00111 TALLOC_CTX *mem_ctx;
00112 NTSTATUS nt_status;
00113 DOM_SID *domain_sid;
00114 char *domain_name;
00115
00116
00117 if (!cli_arg) {
00118 cli = net_make_ipc_connection(conn_flags);
00119 } else {
00120 cli = cli_arg;
00121 }
00122
00123 if (!cli) {
00124 return -1;
00125 }
00126
00127
00128
00129 if (!(mem_ctx = talloc_init("run_rpc_command"))) {
00130 DEBUG(0, ("talloc_init() failed\n"));
00131 cli_shutdown(cli);
00132 return -1;
00133 }
00134
00135 nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
00136 &domain_name);
00137 if (!NT_STATUS_IS_OK(nt_status)) {
00138 cli_shutdown(cli);
00139 return -1;
00140 }
00141
00142 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
00143 if (lp_client_schannel() && (pipe_idx == PI_NETLOGON)) {
00144
00145 pipe_hnd = cli_rpc_pipe_open_schannel(cli, pipe_idx,
00146 PIPE_AUTH_LEVEL_PRIVACY,
00147 domain_name,
00148 &nt_status);
00149 if (!pipe_hnd) {
00150 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
00151 nt_errstr(nt_status) ));
00152 cli_shutdown(cli);
00153 return -1;
00154 }
00155 } else {
00156 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &nt_status);
00157 if (!pipe_hnd) {
00158 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
00159 cli_get_pipe_name(pipe_idx),
00160 nt_errstr(nt_status) ));
00161 cli_shutdown(cli);
00162 return -1;
00163 }
00164 }
00165 }
00166
00167 nt_status = fn(domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
00168
00169 if (!NT_STATUS_IS_OK(nt_status)) {
00170 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
00171 } else {
00172 DEBUG(5, ("rpc command function succedded\n"));
00173 }
00174
00175 if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
00176 if (pipe_hnd) {
00177 cli_rpc_pipe_close(pipe_hnd);
00178 }
00179 }
00180
00181
00182 if (!cli_arg) {
00183 cli_shutdown(cli);
00184 }
00185
00186 talloc_destroy(mem_ctx);
00187 return (!NT_STATUS_IS_OK(nt_status));
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid,
00207 const char *domain_name,
00208 struct cli_state *cli,
00209 struct rpc_pipe_client *pipe_hnd,
00210 TALLOC_CTX *mem_ctx,
00211 int argc,
00212 const char **argv)
00213 {
00214
00215 return trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int net_rpc_changetrustpw(int argc, const char **argv)
00229 {
00230 net_use_machine_account();
00231
00232 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
00233 rpc_changetrustpw_internals,
00234 argc, argv);
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid,
00258 const char *domain_name,
00259 struct cli_state *cli,
00260 struct rpc_pipe_client *pipe_hnd,
00261 TALLOC_CTX *mem_ctx,
00262 int argc,
00263 const char **argv)
00264 {
00265
00266 fstring trust_passwd;
00267 unsigned char orig_trust_passwd_hash[16];
00268 NTSTATUS result;
00269 uint32 sec_channel_type;
00270
00271 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
00272 if (!pipe_hnd) {
00273 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
00274 "error was %s\n",
00275 cli->desthost,
00276 nt_errstr(result) ));
00277 return result;
00278 }
00279
00280
00281
00282
00283
00284 if (argc >= 0) {
00285 sec_channel_type = get_sec_channel_type(argv[0]);
00286 } else {
00287 sec_channel_type = get_sec_channel_type(NULL);
00288 }
00289
00290 fstrcpy(trust_passwd, global_myname());
00291 strlower_m(trust_passwd);
00292
00293
00294
00295
00296
00297
00298 trust_passwd[14] = '\0';
00299
00300 E_md4hash(trust_passwd, orig_trust_passwd_hash);
00301
00302 result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup,
00303 orig_trust_passwd_hash,
00304 sec_channel_type);
00305
00306 if (NT_STATUS_IS_OK(result))
00307 printf("Joined domain %s.\n",opt_target_workgroup);
00308
00309
00310 if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
00311 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
00312 result = NT_STATUS_UNSUCCESSFUL;
00313 }
00314
00315 return result;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 static int net_rpc_perform_oldjoin(int argc, const char **argv)
00329 {
00330 return run_rpc_command(NULL, PI_NETLOGON,
00331 NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
00332 rpc_oldjoin_internals,
00333 argc, argv);
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 static int net_rpc_oldjoin(int argc, const char **argv)
00349 {
00350 int rc = net_rpc_perform_oldjoin(argc, argv);
00351
00352 if (rc) {
00353 d_fprintf(stderr, "Failed to join domain\n");
00354 }
00355
00356 return rc;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 static int rpc_join_usage(int argc, const char **argv)
00367 {
00368 d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
00369 "\t to join a domain with admin username & password\n"\
00370 "\t\t password will be prompted if needed and none is specified\n"\
00371 "\t <type> can be (default MEMBER)\n"\
00372 "\t\t BDC - Join as a BDC\n"\
00373 "\t\t PDC - Join as a PDC\n"\
00374 "\t\t MEMBER - Join as a MEMBER server\n");
00375
00376 net_common_flags_usage(argc, argv);
00377 return -1;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 int net_rpc_join(int argc, const char **argv)
00393 {
00394 if (lp_server_role() == ROLE_STANDALONE) {
00395 d_printf("cannot join as standalone machine\n");
00396 return -1;
00397 }
00398
00399 if (strlen(global_myname()) > 15) {
00400 d_printf("Our netbios name can be at most 15 chars long, "
00401 "\"%s\" is %u chars long\n",
00402 global_myname(), (unsigned int)strlen(global_myname()));
00403 return -1;
00404 }
00405
00406 if ((net_rpc_perform_oldjoin(argc, argv) == 0))
00407 return 0;
00408
00409 return net_rpc_join_newstyle(argc, argv);
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 NTSTATUS rpc_info_internals(const DOM_SID *domain_sid,
00429 const char *domain_name,
00430 struct cli_state *cli,
00431 struct rpc_pipe_client *pipe_hnd,
00432 TALLOC_CTX *mem_ctx,
00433 int argc,
00434 const char **argv)
00435 {
00436 POLICY_HND connect_pol, domain_pol;
00437 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00438 SAM_UNK_CTR ctr;
00439 fstring sid_str;
00440
00441 sid_to_string(sid_str, domain_sid);
00442
00443
00444 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
00445 &connect_pol);
00446 if (!NT_STATUS_IS_OK(result)) {
00447 d_fprintf(stderr, "Could not connect to SAM: %s\n", nt_errstr(result));
00448 goto done;
00449 }
00450
00451
00452 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
00453 MAXIMUM_ALLOWED_ACCESS,
00454 domain_sid, &domain_pol);
00455 if (!NT_STATUS_IS_OK(result)) {
00456 d_fprintf(stderr, "Could not open domain: %s\n", nt_errstr(result));
00457 goto done;
00458 }
00459
00460 ZERO_STRUCT(ctr);
00461 result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
00462 2, &ctr);
00463 if (NT_STATUS_IS_OK(result)) {
00464 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
00465 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
00466 d_printf("Domain SID: %s\n", sid_str);
00467 d_printf("Sequence number: %llu\n", (unsigned long long)ctr.info.inf2.seq_num);
00468 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
00469 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
00470 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
00471 talloc_destroy(ctx);
00472 }
00473
00474 done:
00475 return result;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485 int net_rpc_info(int argc, const char **argv)
00486 {
00487 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_PDC,
00488 rpc_info_internals,
00489 argc, argv);
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
00509 const char *domain_name,
00510 struct cli_state *cli,
00511 struct rpc_pipe_client *pipe_hnd,
00512 TALLOC_CTX *mem_ctx,
00513 int argc,
00514 const char **argv)
00515 {
00516 fstring sid_str;
00517
00518 sid_to_string(sid_str, domain_sid);
00519 d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
00520 sid_str, domain_name);
00521
00522 if (!secrets_store_domain_sid(domain_name, domain_sid)) {
00523 DEBUG(0,("Can't store domain SID\n"));
00524 return NT_STATUS_UNSUCCESSFUL;
00525 }
00526
00527 return NT_STATUS_OK;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537 int net_rpc_getsid(int argc, const char **argv)
00538 {
00539 return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
00540 rpc_getsid_internals,
00541 argc, argv);
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 static int rpc_user_usage(int argc, const char **argv)
00554 {
00555 return net_help_user(argc, argv);
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
00575 const char *domain_name,
00576 struct cli_state *cli,
00577 struct rpc_pipe_client *pipe_hnd,
00578 TALLOC_CTX *mem_ctx,
00579 int argc, const char **argv)
00580 {
00581
00582 POLICY_HND connect_pol, domain_pol, user_pol;
00583 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00584 const char *acct_name;
00585 uint32 acb_info;
00586 uint32 acct_flags=0;
00587 uint32 user_rid;
00588
00589 if (argc < 1) {
00590 d_printf("User must be specified\n");
00591 rpc_user_usage(argc, argv);
00592 return NT_STATUS_OK;
00593 }
00594
00595 acct_name = argv[0];
00596
00597
00598
00599 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
00600 &connect_pol);
00601 if (!NT_STATUS_IS_OK(result)) {
00602 goto done;
00603 }
00604
00605
00606
00607 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
00608 MAXIMUM_ALLOWED_ACCESS,
00609 domain_sid, &domain_pol);
00610 if (!NT_STATUS_IS_OK(result)) {
00611 goto done;
00612 }
00613
00614
00615
00616 acb_info = ACB_NORMAL;
00617 acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
00618 SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
00619 SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
00620 SAMR_USER_SETATTR;
00621 DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
00622
00623 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
00624 acct_name, acb_info, acct_flags,
00625 &user_pol, &user_rid);
00626 if (!NT_STATUS_IS_OK(result)) {
00627 goto done;
00628 }
00629
00630 if (argc == 2) {
00631
00632 uint32 *user_rids, num_rids, *name_types;
00633 uint32 flags = 0x000003e8;
00634 SAM_USERINFO_CTR ctr;
00635 SAM_USER_INFO_24 p24;
00636 uchar pwbuf[516];
00637
00638 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
00639 flags, 1, &acct_name,
00640 &num_rids, &user_rids,
00641 &name_types);
00642
00643 if (!NT_STATUS_IS_OK(result)) {
00644 goto done;
00645 }
00646
00647 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
00648 MAXIMUM_ALLOWED_ACCESS,
00649 user_rids[0], &user_pol);
00650
00651 if (!NT_STATUS_IS_OK(result)) {
00652 goto done;
00653 }
00654
00655
00656
00657 ZERO_STRUCT(ctr);
00658 ZERO_STRUCT(p24);
00659
00660 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
00661
00662 init_sam_user_info24(&p24, (char *)pwbuf,24);
00663
00664 ctr.switch_value = 24;
00665 ctr.info.id24 = &p24;
00666
00667 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
00668 &cli->user_session_key, &ctr);
00669
00670 if (!NT_STATUS_IS_OK(result)) {
00671 d_fprintf(stderr, "Failed to set password for user %s - %s\n",
00672 acct_name, nt_errstr(result));
00673
00674 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
00675
00676 if (!NT_STATUS_IS_OK(result)) {
00677 d_fprintf(stderr, "Failed to delete user %s - %s\n",
00678 acct_name, nt_errstr(result));
00679 return result;
00680 }
00681 }
00682
00683 }
00684 done:
00685 if (!NT_STATUS_IS_OK(result)) {
00686 d_fprintf(stderr, "Failed to add user %s - %s\n", acct_name,
00687 nt_errstr(result));
00688 } else {
00689 d_printf("Added user %s\n", acct_name);
00690 }
00691 return result;
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 static int rpc_user_add(int argc, const char **argv)
00705 {
00706 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
00707 argc, argv);
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
00727 const char *domain_name,
00728 struct cli_state *cli,
00729 struct rpc_pipe_client *pipe_hnd,
00730 TALLOC_CTX *mem_ctx,
00731 int argc,
00732 const char **argv)
00733 {
00734 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00735 POLICY_HND connect_pol, domain_pol, user_pol;
00736
00737 if (argc < 1) {
00738 d_printf("User must be specified\n");
00739 rpc_user_usage(argc, argv);
00740 return NT_STATUS_OK;
00741 }
00742
00743
00744 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
00745 &connect_pol);
00746
00747 if (!NT_STATUS_IS_OK(result)) {
00748 goto done;
00749 }
00750
00751 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
00752 MAXIMUM_ALLOWED_ACCESS,
00753 domain_sid, &domain_pol);
00754
00755 if (!NT_STATUS_IS_OK(result)) {
00756 goto done;
00757 }
00758
00759
00760
00761 {
00762 uint32 *user_rids, num_rids, *name_types;
00763 uint32 flags = 0x000003e8;
00764
00765 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
00766 flags, 1, &argv[0],
00767 &num_rids, &user_rids,
00768 &name_types);
00769
00770 if (!NT_STATUS_IS_OK(result)) {
00771 goto done;
00772 }
00773
00774 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
00775 MAXIMUM_ALLOWED_ACCESS,
00776 user_rids[0], &user_pol);
00777
00778 if (!NT_STATUS_IS_OK(result)) {
00779 goto done;
00780 }
00781 }
00782
00783
00784
00785 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
00786
00787 if (!NT_STATUS_IS_OK(result)) {
00788 goto done;
00789 }
00790
00791
00792 if (!NT_STATUS_IS_OK(result)) {
00793 d_fprintf(stderr, "Failed to delete user account - %s\n", nt_errstr(result));
00794 } else {
00795 d_printf("Deleted user account\n");
00796 }
00797
00798 done:
00799 return result;
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
00819 const char *domain_name,
00820 struct cli_state *cli,
00821 struct rpc_pipe_client *pipe_hnd,
00822 TALLOC_CTX *mem_ctx,
00823 int argc,
00824 const char **argv)
00825 {
00826 POLICY_HND connect_pol, domain_pol, user_pol;
00827 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00828 uint32 info_level = 7;
00829 const char *old_name, *new_name;
00830 uint32 *user_rid;
00831 uint32 flags = 0x000003e8;
00832 uint32 num_rids, *name_types;
00833 uint32 num_names = 1;
00834 const char **names;
00835 SAM_USERINFO_CTR *user_ctr;
00836 SAM_USERINFO_CTR ctr;
00837 SAM_USER_INFO_7 info7;
00838
00839 if (argc != 2) {
00840 d_printf("Old and new username must be specified\n");
00841 rpc_user_usage(argc, argv);
00842 return NT_STATUS_OK;
00843 }
00844
00845 old_name = argv[0];
00846 new_name = argv[1];
00847
00848 ZERO_STRUCT(ctr);
00849 ZERO_STRUCT(user_ctr);
00850
00851
00852
00853 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
00854 &connect_pol);
00855 if (!NT_STATUS_IS_OK(result)) {
00856 goto done;
00857 }
00858
00859
00860
00861 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
00862 MAXIMUM_ALLOWED_ACCESS,
00863 domain_sid, &domain_pol);
00864 if (!NT_STATUS_IS_OK(result)) {
00865 goto done;
00866 }
00867
00868 if ((names = TALLOC_ARRAY(mem_ctx, const char *, num_names)) == NULL) {
00869 result = NT_STATUS_NO_MEMORY;
00870 goto done;
00871 }
00872 names[0] = old_name;
00873 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
00874 flags, num_names, names,
00875 &num_rids, &user_rid, &name_types);
00876 if (!NT_STATUS_IS_OK(result)) {
00877 goto done;
00878 }
00879
00880
00881 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
00882 MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
00883
00884 if (!NT_STATUS_IS_OK(result)) {
00885 goto done;
00886 }
00887
00888
00889 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
00890 info_level, &user_ctr);
00891
00892 if (!NT_STATUS_IS_OK(result)) {
00893 goto done;
00894 }
00895
00896 ctr.switch_value = info_level;
00897 ctr.info.id7 = &info7;
00898
00899 init_sam_user_info7(&info7, new_name);
00900
00901
00902 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
00903 info_level, &cli->user_session_key, &ctr);
00904
00905 if (!NT_STATUS_IS_OK(result)) {
00906 goto done;
00907 }
00908
00909 done:
00910 if (!NT_STATUS_IS_OK(result)) {
00911 d_fprintf(stderr, "Failed to rename user from %s to %s - %s\n", old_name, new_name,
00912 nt_errstr(result));
00913 } else {
00914 d_printf("Renamed user from %s to %s\n", old_name, new_name);
00915 }
00916 return result;
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 static int rpc_user_rename(int argc, const char **argv)
00930 {
00931 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
00932 argc, argv);
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 static int rpc_user_delete(int argc, const char **argv)
00946 {
00947 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
00948 argc, argv);
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
00968 const char *domain_name,
00969 struct cli_state *cli,
00970 struct rpc_pipe_client *pipe_hnd,
00971 TALLOC_CTX *mem_ctx,
00972 int argc,
00973 const char **argv)
00974 {
00975 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00976 POLICY_HND connect_pol, domain_pol, user_pol;
00977 SAM_USERINFO_CTR ctr;
00978 SAM_USER_INFO_24 p24;
00979 uchar pwbuf[516];
00980 const char *user;
00981 const char *new_password;
00982 char *prompt = NULL;
00983
00984 if (argc < 1) {
00985 d_printf("User must be specified\n");
00986 rpc_user_usage(argc, argv);
00987 return NT_STATUS_OK;
00988 }
00989
00990 user = argv[0];
00991
00992 if (argv[1]) {
00993 new_password = argv[1];
00994 } else {
00995 asprintf(&prompt, "Enter new password for %s:", user);
00996 new_password = getpass(prompt);
00997 SAFE_FREE(prompt);
00998 }
00999
01000
01001
01002 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01003 &connect_pol);
01004
01005 if (!NT_STATUS_IS_OK(result)) {
01006 goto done;
01007 }
01008
01009 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01010 MAXIMUM_ALLOWED_ACCESS,
01011 domain_sid, &domain_pol);
01012
01013 if (!NT_STATUS_IS_OK(result)) {
01014 goto done;
01015 }
01016
01017
01018
01019 {
01020 uint32 *user_rids, num_rids, *name_types;
01021 uint32 flags = 0x000003e8;
01022
01023 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
01024 flags, 1, &user,
01025 &num_rids, &user_rids,
01026 &name_types);
01027
01028 if (!NT_STATUS_IS_OK(result)) {
01029 goto done;
01030 }
01031
01032 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
01033 MAXIMUM_ALLOWED_ACCESS,
01034 user_rids[0], &user_pol);
01035
01036 if (!NT_STATUS_IS_OK(result)) {
01037 goto done;
01038 }
01039 }
01040
01041
01042
01043 ZERO_STRUCT(ctr);
01044 ZERO_STRUCT(p24);
01045
01046 encode_pw_buffer(pwbuf, new_password, STR_UNICODE);
01047
01048 init_sam_user_info24(&p24, (char *)pwbuf,24);
01049
01050 ctr.switch_value = 24;
01051 ctr.info.id24 = &p24;
01052
01053 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
01054 &cli->user_session_key, &ctr);
01055
01056 if (!NT_STATUS_IS_OK(result)) {
01057 goto done;
01058 }
01059
01060
01061
01062 done:
01063 return result;
01064
01065 }
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077 static int rpc_user_password(int argc, const char **argv)
01078 {
01079 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_password_internals,
01080 argc, argv);
01081 }
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099 static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
01100 const char *domain_name,
01101 struct cli_state *cli,
01102 struct rpc_pipe_client *pipe_hnd,
01103 TALLOC_CTX *mem_ctx,
01104 int argc,
01105 const char **argv)
01106 {
01107 POLICY_HND connect_pol, domain_pol, user_pol;
01108 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01109 uint32 *rids, num_rids, *name_types, num_names;
01110 uint32 flags = 0x000003e8;
01111 int i;
01112 char **names;
01113 DOM_GID *user_gids;
01114
01115 if (argc < 1) {
01116 d_printf("User must be specified\n");
01117 rpc_user_usage(argc, argv);
01118 return NT_STATUS_OK;
01119 }
01120
01121
01122 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01123 &connect_pol);
01124 if (!NT_STATUS_IS_OK(result)) goto done;
01125
01126
01127
01128 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01129 MAXIMUM_ALLOWED_ACCESS,
01130 domain_sid, &domain_pol);
01131 if (!NT_STATUS_IS_OK(result)) goto done;
01132
01133
01134
01135 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
01136 flags, 1, &argv[0],
01137 &num_rids, &rids, &name_types);
01138
01139 if (!NT_STATUS_IS_OK(result)) goto done;
01140
01141 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
01142 MAXIMUM_ALLOWED_ACCESS,
01143 rids[0], &user_pol);
01144 if (!NT_STATUS_IS_OK(result)) goto done;
01145
01146 result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
01147 &num_rids, &user_gids);
01148
01149 if (!NT_STATUS_IS_OK(result)) goto done;
01150
01151
01152
01153 if (num_rids) {
01154 if ((rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids)) == NULL) {
01155 result = NT_STATUS_NO_MEMORY;
01156 goto done;
01157 }
01158
01159 for (i = 0; i < num_rids; i++)
01160 rids[i] = user_gids[i].g_rid;
01161
01162 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
01163 num_rids, rids,
01164 &num_names, &names, &name_types);
01165
01166 if (!NT_STATUS_IS_OK(result)) {
01167 goto done;
01168 }
01169
01170
01171
01172 for (i = 0; i < num_names; i++)
01173 printf("%s\n", names[i]);
01174 }
01175 done:
01176 return result;
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 static int rpc_user_info(int argc, const char **argv)
01190 {
01191 return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
01192 argc, argv);
01193 }
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
01212 const char *domain_name,
01213 struct cli_state *cli,
01214 struct rpc_pipe_client *pipe_hnd,
01215 TALLOC_CTX *mem_ctx,
01216 int argc,
01217 const char **argv)
01218 {
01219 POLICY_HND connect_pol, domain_pol;
01220 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01221 uint32 start_idx=0, num_entries, i, loop_count = 0;
01222 SAM_DISPINFO_CTR ctr;
01223 SAM_DISPINFO_1 info1;
01224
01225
01226
01227 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01228 &connect_pol);
01229 if (!NT_STATUS_IS_OK(result)) {
01230 goto done;
01231 }
01232
01233
01234
01235 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01236 MAXIMUM_ALLOWED_ACCESS,
01237 domain_sid, &domain_pol);
01238 if (!NT_STATUS_IS_OK(result)) {
01239 goto done;
01240 }
01241
01242
01243 ZERO_STRUCT(ctr);
01244 ZERO_STRUCT(info1);
01245 ctr.sam.info1 = &info1;
01246 if (opt_long_list_entries)
01247 d_printf("\nUser name Comment"\
01248 "\n-----------------------------\n");
01249 do {
01250 fstring user, desc;
01251 uint32 max_entries, max_size;
01252
01253 get_query_dispinfo_params(
01254 loop_count, &max_entries, &max_size);
01255
01256 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
01257 &start_idx, 1, &num_entries,
01258 max_entries, max_size, &ctr);
01259 loop_count++;
01260
01261 for (i = 0; i < num_entries; i++) {
01262 unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
01263 if (opt_long_list_entries)
01264 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
01265
01266 if (opt_long_list_entries)
01267 printf("%-21.21s %s\n", user, desc);
01268 else
01269 printf("%s\n", user);
01270 }
01271 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
01272
01273 done:
01274 return result;
01275 }
01276
01277
01278
01279
01280
01281
01282
01283
01284 int net_rpc_user(int argc, const char **argv)
01285 {
01286 struct functable func[] = {
01287 {"add", rpc_user_add},
01288 {"info", rpc_user_info},
01289 {"delete", rpc_user_delete},
01290 {"password", rpc_user_password},
01291 {"rename", rpc_user_rename},
01292 {NULL, NULL}
01293 };
01294
01295 if (argc == 0) {
01296 return run_rpc_command(NULL,PI_SAMR, 0,
01297 rpc_user_list_internals,
01298 argc, argv);
01299 }
01300
01301 return net_run_function(argc, argv, func, rpc_user_usage);
01302 }
01303
01304 static NTSTATUS rpc_sh_user_list(TALLOC_CTX *mem_ctx,
01305 struct rpc_sh_ctx *ctx,
01306 struct rpc_pipe_client *pipe_hnd,
01307 int argc, const char **argv)
01308 {
01309 return rpc_user_list_internals(ctx->domain_sid, ctx->domain_name,
01310 ctx->cli, pipe_hnd, mem_ctx,
01311 argc, argv);
01312 }
01313
01314 static NTSTATUS rpc_sh_user_info(TALLOC_CTX *mem_ctx,
01315 struct rpc_sh_ctx *ctx,
01316 struct rpc_pipe_client *pipe_hnd,
01317 int argc, const char **argv)
01318 {
01319 return rpc_user_info_internals(ctx->domain_sid, ctx->domain_name,
01320 ctx->cli, pipe_hnd, mem_ctx,
01321 argc, argv);
01322 }
01323
01324 static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx,
01325 struct rpc_sh_ctx *ctx,
01326 struct rpc_pipe_client *pipe_hnd,
01327 int argc, const char **argv,
01328 NTSTATUS (*fn)(
01329 TALLOC_CTX *mem_ctx,
01330 struct rpc_sh_ctx *ctx,
01331 struct rpc_pipe_client *pipe_hnd,
01332 const POLICY_HND *user_hnd,
01333 int argc, const char **argv))
01334
01335 {
01336 POLICY_HND connect_pol, domain_pol, user_pol;
01337 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01338 DOM_SID sid;
01339 uint32 rid;
01340 enum lsa_SidType type;
01341
01342 if (argc == 0) {
01343 d_fprintf(stderr, "usage: %s <username>\n", ctx->whoami);
01344 return NT_STATUS_INVALID_PARAMETER;
01345 }
01346
01347 ZERO_STRUCT(connect_pol);
01348 ZERO_STRUCT(domain_pol);
01349 ZERO_STRUCT(user_pol);
01350
01351 result = net_rpc_lookup_name(mem_ctx, pipe_hnd->cli, argv[0],
01352 NULL, NULL, &sid, &type);
01353 if (!NT_STATUS_IS_OK(result)) {
01354 d_fprintf(stderr, "Could not lookup %s: %s\n", argv[0],
01355 nt_errstr(result));
01356 goto done;
01357 }
01358
01359 if (type != SID_NAME_USER) {
01360 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
01361 sid_type_lookup(type));
01362 result = NT_STATUS_NO_SUCH_USER;
01363 goto done;
01364 }
01365
01366 if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
01367 d_fprintf(stderr, "%s is not in our domain\n", argv[0]);
01368 result = NT_STATUS_NO_SUCH_USER;
01369 goto done;
01370 }
01371
01372 result = rpccli_samr_connect(pipe_hnd, mem_ctx,
01373 MAXIMUM_ALLOWED_ACCESS, &connect_pol);
01374 if (!NT_STATUS_IS_OK(result)) {
01375 goto done;
01376 }
01377
01378 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01379 MAXIMUM_ALLOWED_ACCESS,
01380 ctx->domain_sid, &domain_pol);
01381 if (!NT_STATUS_IS_OK(result)) {
01382 goto done;
01383 }
01384
01385 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
01386 MAXIMUM_ALLOWED_ACCESS,
01387 rid, &user_pol);
01388 if (!NT_STATUS_IS_OK(result)) {
01389 goto done;
01390 }
01391
01392 result = fn(mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
01393
01394 done:
01395 if (is_valid_policy_hnd(&user_pol)) {
01396 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
01397 }
01398 if (is_valid_policy_hnd(&domain_pol)) {
01399 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
01400 }
01401 if (is_valid_policy_hnd(&connect_pol)) {
01402 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
01403 }
01404 return result;
01405 }
01406
01407 static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx,
01408 struct rpc_sh_ctx *ctx,
01409 struct rpc_pipe_client *pipe_hnd,
01410 const POLICY_HND *user_hnd,
01411 int argc, const char **argv)
01412 {
01413 NTSTATUS result;
01414 SAM_USERINFO_CTR *ctr;
01415 SAM_USER_INFO_21 *info;
01416
01417 if (argc != 0) {
01418 d_fprintf(stderr, "usage: %s show <username>\n", ctx->whoami);
01419 return NT_STATUS_INVALID_PARAMETER;
01420 }
01421
01422 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
01423 21, &ctr);
01424 if (!NT_STATUS_IS_OK(result)) {
01425 return result;
01426 }
01427
01428 info = ctr->info.id21;
01429
01430 d_printf("user rid: %d, group rid: %d\n", info->user_rid,
01431 info->group_rid);
01432
01433 return result;
01434 }
01435
01436 static NTSTATUS rpc_sh_user_show(TALLOC_CTX *mem_ctx,
01437 struct rpc_sh_ctx *ctx,
01438 struct rpc_pipe_client *pipe_hnd,
01439 int argc, const char **argv)
01440 {
01441 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
01442 rpc_sh_user_show_internals);
01443 }
01444
01445 #define FETCHSTR(name, rec) \
01446 do { if (strequal(ctx->thiscmd, name)) { \
01447 oldval = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_##rec); } \
01448 } while (0);
01449
01450 #define SETSTR(name, rec, flag) \
01451 do { if (strequal(ctx->thiscmd, name)) { \
01452 init_unistr2(&usr->uni_##rec, argv[0], UNI_STR_TERMINATE); \
01453 init_uni_hdr(&usr->hdr_##rec, &usr->uni_##rec); \
01454 usr->fields_present |= ACCT_##flag; } \
01455 } while (0);
01456
01457 static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx,
01458 struct rpc_sh_ctx *ctx,
01459 struct rpc_pipe_client *pipe_hnd,
01460 const POLICY_HND *user_hnd,
01461 int argc, const char **argv)
01462 {
01463 NTSTATUS result;
01464 SAM_USERINFO_CTR *ctr;
01465 SAM_USER_INFO_21 *usr;
01466 const char *username;
01467 const char *oldval = "";
01468
01469 if (argc > 1) {
01470 d_fprintf(stderr, "usage: %s <username> [new value|NULL]\n",
01471 ctx->whoami);
01472 return NT_STATUS_INVALID_PARAMETER;
01473 }
01474
01475 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
01476 21, &ctr);
01477 if (!NT_STATUS_IS_OK(result)) {
01478 return result;
01479 }
01480
01481 usr = ctr->info.id21;
01482
01483 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
01484
01485 FETCHSTR("fullname", full_name);
01486 FETCHSTR("homedir", home_dir);
01487 FETCHSTR("homedrive", dir_drive);
01488 FETCHSTR("logonscript", logon_script);
01489 FETCHSTR("profilepath", profile_path);
01490 FETCHSTR("description", acct_desc);
01491
01492 if (argc == 0) {
01493 d_printf("%s's %s: [%s]\n", username, ctx->thiscmd, oldval);
01494 goto done;
01495 }
01496
01497 ZERO_STRUCTP(usr);
01498
01499 if (strcmp(argv[0], "NULL") == 0) {
01500 argv[0] = "";
01501 }
01502
01503 SETSTR("fullname", full_name, FULL_NAME);
01504 SETSTR("homedir", home_dir, HOME_DIR);
01505 SETSTR("homedrive", dir_drive, HOME_DRIVE);
01506 SETSTR("logonscript", logon_script, LOGON_SCRIPT);
01507 SETSTR("profilepath", profile_path, PROFILE);
01508 SETSTR("description", acct_desc, DESCRIPTION);
01509
01510 result = rpccli_samr_set_userinfo2(
01511 pipe_hnd, mem_ctx, user_hnd, 21,
01512 &pipe_hnd->cli->user_session_key, ctr);
01513
01514 d_printf("Set %s's %s from [%s] to [%s]\n", username,
01515 ctx->thiscmd, oldval, argv[0]);
01516
01517 done:
01518
01519 return result;
01520 }
01521
01522 #define HANDLEFLG(name, rec) \
01523 do { if (strequal(ctx->thiscmd, name)) { \
01524 oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
01525 if (newval) { \
01526 newflags = oldflags | ACB_##rec; \
01527 } else { \
01528 newflags = oldflags & ~ACB_##rec; \
01529 } } } while (0);
01530
01531 static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx,
01532 struct rpc_sh_ctx *ctx,
01533 struct rpc_pipe_client *pipe_hnd,
01534 int argc, const char **argv)
01535 {
01536 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
01537 rpc_sh_user_str_edit_internals);
01538 }
01539
01540 static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx,
01541 struct rpc_sh_ctx *ctx,
01542 struct rpc_pipe_client *pipe_hnd,
01543 const POLICY_HND *user_hnd,
01544 int argc, const char **argv)
01545 {
01546 NTSTATUS result;
01547 SAM_USERINFO_CTR *ctr;
01548 SAM_USER_INFO_21 *usr;
01549 const char *username;
01550 const char *oldval = "unknown";
01551 uint32 oldflags, newflags;
01552 BOOL newval;
01553
01554 if ((argc > 1) ||
01555 ((argc == 1) && !strequal(argv[0], "yes") &&
01556 !strequal(argv[0], "no"))) {
01557 d_fprintf(stderr, "usage: %s <username> [yes|no]\n",
01558 ctx->whoami);
01559 return NT_STATUS_INVALID_PARAMETER;
01560 }
01561
01562 newval = strequal(argv[0], "yes");
01563
01564 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, user_hnd,
01565 21, &ctr);
01566 if (!NT_STATUS_IS_OK(result)) {
01567 return result;
01568 }
01569
01570 usr = ctr->info.id21;
01571
01572 username = rpcstr_pull_unistr2_talloc(mem_ctx, &usr->uni_user_name);
01573 oldflags = usr->acb_info;
01574 newflags = usr->acb_info;
01575
01576 HANDLEFLG("disabled", DISABLED);
01577 HANDLEFLG("pwnotreq", PWNOTREQ);
01578 HANDLEFLG("autolock", AUTOLOCK);
01579 HANDLEFLG("pwnoexp", PWNOEXP);
01580
01581 if (argc == 0) {
01582 d_printf("%s's %s flag: %s\n", username, ctx->thiscmd, oldval);
01583 goto done;
01584 }
01585
01586 ZERO_STRUCTP(usr);
01587
01588 usr->acb_info = newflags;
01589 usr->fields_present = ACCT_FLAGS;
01590
01591 result = rpccli_samr_set_userinfo2(
01592 pipe_hnd, mem_ctx, user_hnd, 21,
01593 &pipe_hnd->cli->user_session_key, ctr);
01594
01595 if (NT_STATUS_IS_OK(result)) {
01596 d_printf("Set %s's %s flag from [%s] to [%s]\n", username,
01597 ctx->thiscmd, oldval, argv[0]);
01598 }
01599
01600 done:
01601
01602 return result;
01603 }
01604
01605 static NTSTATUS rpc_sh_user_flag_edit(TALLOC_CTX *mem_ctx,
01606 struct rpc_sh_ctx *ctx,
01607 struct rpc_pipe_client *pipe_hnd,
01608 int argc, const char **argv)
01609 {
01610 return rpc_sh_handle_user(mem_ctx, ctx, pipe_hnd, argc, argv,
01611 rpc_sh_user_flag_edit_internals);
01612 }
01613
01614 struct rpc_sh_cmd *net_rpc_user_edit_cmds(TALLOC_CTX *mem_ctx,
01615 struct rpc_sh_ctx *ctx)
01616 {
01617 static struct rpc_sh_cmd cmds[] = {
01618
01619 { "fullname", NULL, PI_SAMR, rpc_sh_user_str_edit,
01620 "Show/Set a user's full name" },
01621
01622 { "homedir", NULL, PI_SAMR, rpc_sh_user_str_edit,
01623 "Show/Set a user's home directory" },
01624
01625 { "homedrive", NULL, PI_SAMR, rpc_sh_user_str_edit,
01626 "Show/Set a user's home drive" },
01627
01628 { "logonscript", NULL, PI_SAMR, rpc_sh_user_str_edit,
01629 "Show/Set a user's logon script" },
01630
01631 { "profilepath", NULL, PI_SAMR, rpc_sh_user_str_edit,
01632 "Show/Set a user's profile path" },
01633
01634 { "description", NULL, PI_SAMR, rpc_sh_user_str_edit,
01635 "Show/Set a user's description" },
01636
01637 { "disabled", NULL, PI_SAMR, rpc_sh_user_flag_edit,
01638 "Show/Set whether a user is disabled" },
01639
01640 { "autolock", NULL, PI_SAMR, rpc_sh_user_flag_edit,
01641 "Show/Set whether a user locked out" },
01642
01643 { "pwnotreq", NULL, PI_SAMR, rpc_sh_user_flag_edit,
01644 "Show/Set whether a user does not need a password" },
01645
01646 { "pwnoexp", NULL, PI_SAMR, rpc_sh_user_flag_edit,
01647 "Show/Set whether a user's password does not expire" },
01648
01649 { NULL, NULL, 0, NULL, NULL }
01650 };
01651
01652 return cmds;
01653 }
01654
01655 struct rpc_sh_cmd *net_rpc_user_cmds(TALLOC_CTX *mem_ctx,
01656 struct rpc_sh_ctx *ctx)
01657 {
01658 static struct rpc_sh_cmd cmds[] = {
01659
01660 { "list", NULL, PI_SAMR, rpc_sh_user_list,
01661 "List available users" },
01662
01663 { "info", NULL, PI_SAMR, rpc_sh_user_info,
01664 "List the domain groups a user is member of" },
01665
01666 { "show", NULL, PI_SAMR, rpc_sh_user_show,
01667 "Show info about a user" },
01668
01669 { "edit", net_rpc_user_edit_cmds, 0, NULL,
01670 "Show/Modify a user's fields" },
01671
01672 { NULL, NULL, 0, NULL, NULL }
01673 };
01674
01675 return cmds;
01676 }
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687 static int rpc_group_usage(int argc, const char **argv)
01688 {
01689 return net_help_group(argc, argv);
01690 }
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708 static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
01709 const char *domain_name,
01710 struct cli_state *cli,
01711 struct rpc_pipe_client *pipe_hnd,
01712 TALLOC_CTX *mem_ctx,
01713 int argc,
01714 const char **argv)
01715 {
01716 POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
01717 BOOL group_is_primary = False;
01718 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01719
01720 uint32 *group_rids, num_rids, *name_types, num_members,
01721 *group_attrs, group_rid;
01722 uint32 flags = 0x000003e8;
01723
01724 int i;
01725
01726 SAM_USERINFO_CTR *user_ctr;
01727 fstring temp;
01728
01729 if (argc < 1) {
01730 d_printf("specify group\n");
01731 rpc_group_usage(argc,argv);
01732 return NT_STATUS_OK;
01733 }
01734
01735 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01736 &connect_pol);
01737
01738 if (!NT_STATUS_IS_OK(result)) {
01739 d_fprintf(stderr, "Request samr_connect failed\n");
01740 goto done;
01741 }
01742
01743 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01744 MAXIMUM_ALLOWED_ACCESS,
01745 domain_sid, &domain_pol);
01746
01747 if (!NT_STATUS_IS_OK(result)) {
01748 d_fprintf(stderr, "Request open_domain failed\n");
01749 goto done;
01750 }
01751
01752 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
01753 flags, 1, &argv[0],
01754 &num_rids, &group_rids,
01755 &name_types);
01756
01757 if (!NT_STATUS_IS_OK(result)) {
01758 d_fprintf(stderr, "Lookup of '%s' failed\n",argv[0]);
01759 goto done;
01760 }
01761
01762 switch (name_types[0])
01763 {
01764 case SID_NAME_DOM_GRP:
01765 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
01766 MAXIMUM_ALLOWED_ACCESS,
01767 group_rids[0], &group_pol);
01768 if (!NT_STATUS_IS_OK(result)) {
01769 d_fprintf(stderr, "Request open_group failed");
01770 goto done;
01771 }
01772
01773 group_rid = group_rids[0];
01774
01775 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
01776 &num_members, &group_rids,
01777 &group_attrs);
01778
01779 if (!NT_STATUS_IS_OK(result)) {
01780 d_fprintf(stderr, "Unable to query group members of %s",argv[0]);
01781 goto done;
01782 }
01783
01784 if (opt_verbose) {
01785 d_printf("Domain Group %s (rid: %d) has %d members\n",
01786 argv[0],group_rid,num_members);
01787 }
01788
01789
01790 for (i = 0; i < num_members; i++)
01791 {
01792 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
01793 MAXIMUM_ALLOWED_ACCESS,
01794 group_rids[i], &user_pol);
01795
01796 if (!NT_STATUS_IS_OK(result)) {
01797 d_fprintf(stderr, "Unable to open group member %d\n",group_rids[i]);
01798 goto done;
01799 }
01800
01801 ZERO_STRUCT(user_ctr);
01802
01803 result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
01804 21, &user_ctr);
01805
01806 if (!NT_STATUS_IS_OK(result)) {
01807 d_fprintf(stderr, "Unable to lookup userinfo for group member %d\n",group_rids[i]);
01808 goto done;
01809 }
01810
01811 if (user_ctr->info.id21->group_rid == group_rid) {
01812 unistr2_to_ascii(temp, &(user_ctr->info.id21)->uni_user_name,
01813 sizeof(temp)-1);
01814 if (opt_verbose)
01815 d_printf("Group is primary group of %s\n",temp);
01816 group_is_primary = True;
01817 }
01818
01819 rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
01820 }
01821
01822 if (group_is_primary) {
01823 d_fprintf(stderr, "Unable to delete group because some "
01824 "of it's members have it as primary group\n");
01825 result = NT_STATUS_MEMBERS_PRIMARY_GROUP;
01826 goto done;
01827 }
01828
01829
01830 for (i = 0; i < num_members; i++)
01831 {
01832 if (opt_verbose)
01833 d_printf("Remove group member %d...",group_rids[i]);
01834 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
01835
01836 if (NT_STATUS_IS_OK(result)) {
01837 if (opt_verbose)
01838 d_printf("ok\n");
01839 } else {
01840 if (opt_verbose)
01841 d_printf("failed\n");
01842 goto done;
01843 }
01844 }
01845
01846 result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
01847
01848 break;
01849
01850 case SID_NAME_ALIAS:
01851 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
01852 MAXIMUM_ALLOWED_ACCESS,
01853 group_rids[0], &group_pol);
01854
01855 if (!NT_STATUS_IS_OK(result)) {
01856 d_fprintf(stderr, "Request open_alias failed\n");
01857 goto done;
01858 }
01859
01860 result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
01861 break;
01862 default:
01863 d_fprintf(stderr, "%s is of type %s. This command is only for deleting local or global groups\n",
01864 argv[0],sid_type_lookup(name_types[0]));
01865 result = NT_STATUS_UNSUCCESSFUL;
01866 goto done;
01867 }
01868
01869
01870 if (NT_STATUS_IS_OK(result)) {
01871 if (opt_verbose)
01872 d_printf("Deleted %s '%s'\n",sid_type_lookup(name_types[0]),argv[0]);
01873 } else {
01874 d_fprintf(stderr, "Deleting of %s failed: %s\n",argv[0],
01875 get_friendly_nt_error_msg(result));
01876 }
01877
01878 done:
01879 return result;
01880
01881 }
01882
01883 static int rpc_group_delete(int argc, const char **argv)
01884 {
01885 return run_rpc_command(NULL, PI_SAMR, 0, rpc_group_delete_internals,
01886 argc,argv);
01887 }
01888
01889 static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
01890 const char *domain_name,
01891 struct cli_state *cli,
01892 struct rpc_pipe_client *pipe_hnd,
01893 TALLOC_CTX *mem_ctx,
01894 int argc,
01895 const char **argv)
01896 {
01897 POLICY_HND connect_pol, domain_pol, group_pol;
01898 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01899 GROUP_INFO_CTR group_info;
01900
01901 if (argc != 1) {
01902 d_printf("Group name must be specified\n");
01903 rpc_group_usage(argc, argv);
01904 return NT_STATUS_OK;
01905 }
01906
01907
01908
01909 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01910 &connect_pol);
01911 if (!NT_STATUS_IS_OK(result)) goto done;
01912
01913
01914
01915 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01916 MAXIMUM_ALLOWED_ACCESS,
01917 domain_sid, &domain_pol);
01918 if (!NT_STATUS_IS_OK(result)) goto done;
01919
01920
01921
01922 result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
01923 argv[0], MAXIMUM_ALLOWED_ACCESS,
01924 &group_pol);
01925 if (!NT_STATUS_IS_OK(result)) goto done;
01926
01927 if (strlen(opt_comment) == 0) goto done;
01928
01929
01930
01931 group_info.switch_value1 = 4;
01932 init_samr_group_info4(&group_info.group.info4, opt_comment);
01933
01934 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
01935 if (!NT_STATUS_IS_OK(result)) goto done;
01936
01937 done:
01938 if (NT_STATUS_IS_OK(result))
01939 DEBUG(5, ("add group succeeded\n"));
01940 else
01941 d_fprintf(stderr, "add group failed: %s\n", nt_errstr(result));
01942
01943 return result;
01944 }
01945
01946 static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
01947 const char *domain_name,
01948 struct cli_state *cli,
01949 struct rpc_pipe_client *pipe_hnd,
01950 TALLOC_CTX *mem_ctx,
01951 int argc,
01952 const char **argv)
01953 {
01954 POLICY_HND connect_pol, domain_pol, alias_pol;
01955 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01956 ALIAS_INFO_CTR alias_info;
01957
01958 if (argc != 1) {
01959 d_printf("Alias name must be specified\n");
01960 rpc_group_usage(argc, argv);
01961 return NT_STATUS_OK;
01962 }
01963
01964
01965
01966 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
01967 &connect_pol);
01968 if (!NT_STATUS_IS_OK(result)) goto done;
01969
01970
01971
01972 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
01973 MAXIMUM_ALLOWED_ACCESS,
01974 domain_sid, &domain_pol);
01975 if (!NT_STATUS_IS_OK(result)) goto done;
01976
01977
01978
01979 result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
01980 argv[0], &alias_pol);
01981 if (!NT_STATUS_IS_OK(result)) goto done;
01982
01983 if (strlen(opt_comment) == 0) goto done;
01984
01985
01986
01987 alias_info.level = 3;
01988 init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
01989
01990 result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
01991 if (!NT_STATUS_IS_OK(result)) goto done;
01992
01993 done:
01994 if (NT_STATUS_IS_OK(result))
01995 DEBUG(5, ("add alias succeeded\n"));
01996 else
01997 d_fprintf(stderr, "add alias failed: %s\n", nt_errstr(result));
01998
01999 return result;
02000 }
02001
02002 static int rpc_group_add(int argc, const char **argv)
02003 {
02004 if (opt_localgroup)
02005 return run_rpc_command(NULL, PI_SAMR, 0,
02006 rpc_alias_add_internals,
02007 argc, argv);
02008
02009 return run_rpc_command(NULL, PI_SAMR, 0,
02010 rpc_group_add_internals,
02011 argc, argv);
02012 }
02013
02014 static NTSTATUS get_sid_from_name(struct cli_state *cli,
02015 TALLOC_CTX *mem_ctx,
02016 const char *name,
02017 DOM_SID *sid,
02018 enum lsa_SidType *type)
02019 {
02020 DOM_SID *sids = NULL;
02021 enum lsa_SidType *types = NULL;
02022 struct rpc_pipe_client *pipe_hnd;
02023 POLICY_HND lsa_pol;
02024 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
02025
02026 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
02027 if (!pipe_hnd) {
02028 goto done;
02029 }
02030
02031 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
02032 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
02033
02034 if (!NT_STATUS_IS_OK(result)) {
02035 goto done;
02036 }
02037
02038 result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
02039 &name, NULL, &sids, &types);
02040
02041 if (NT_STATUS_IS_OK(result)) {
02042 sid_copy(sid, &sids[0]);
02043 *type = types[0];
02044 }
02045
02046 rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
02047
02048 done:
02049 if (pipe_hnd) {
02050 cli_rpc_pipe_close(pipe_hnd);
02051 }
02052
02053 if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
02054
02055
02056
02057 DOM_SID tmp_sid;
02058
02059 if (string_to_sid(&tmp_sid, name)) {
02060 sid_copy(sid, &tmp_sid);
02061 *type = SID_NAME_UNKNOWN;
02062 result = NT_STATUS_OK;
02063 }
02064 }
02065
02066 return result;
02067 }
02068
02069 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
02070 TALLOC_CTX *mem_ctx,
02071 const DOM_SID *group_sid,
02072 const char *member)
02073 {
02074 POLICY_HND connect_pol, domain_pol;
02075 NTSTATUS result;
02076 uint32 group_rid;
02077 POLICY_HND group_pol;
02078
02079 uint32 num_rids;
02080 uint32 *rids = NULL;
02081 uint32 *rid_types = NULL;
02082
02083 DOM_SID sid;
02084
02085 sid_copy(&sid, group_sid);
02086
02087 if (!sid_split_rid(&sid, &group_rid)) {
02088 return NT_STATUS_UNSUCCESSFUL;
02089 }
02090
02091
02092 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02093 &connect_pol);
02094 if (!NT_STATUS_IS_OK(result)) {
02095 return result;
02096 }
02097
02098
02099 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02100 MAXIMUM_ALLOWED_ACCESS,
02101 &sid, &domain_pol);
02102 if (!NT_STATUS_IS_OK(result)) {
02103 return result;
02104 }
02105
02106 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
02107 1, &member,
02108 &num_rids, &rids, &rid_types);
02109
02110 if (!NT_STATUS_IS_OK(result)) {
02111 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
02112 goto done;
02113 }
02114
02115 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
02116 MAXIMUM_ALLOWED_ACCESS,
02117 group_rid, &group_pol);
02118
02119 if (!NT_STATUS_IS_OK(result)) {
02120 goto done;
02121 }
02122
02123 result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
02124
02125 done:
02126 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
02127 return result;
02128 }
02129
02130 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
02131 TALLOC_CTX *mem_ctx,
02132 const DOM_SID *alias_sid,
02133 const char *member)
02134 {
02135 POLICY_HND connect_pol, domain_pol;
02136 NTSTATUS result;
02137 uint32 alias_rid;
02138 POLICY_HND alias_pol;
02139
02140 DOM_SID member_sid;
02141 enum lsa_SidType member_type;
02142
02143 DOM_SID sid;
02144
02145 sid_copy(&sid, alias_sid);
02146
02147 if (!sid_split_rid(&sid, &alias_rid)) {
02148 return NT_STATUS_UNSUCCESSFUL;
02149 }
02150
02151 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
02152 &member_sid, &member_type);
02153
02154 if (!NT_STATUS_IS_OK(result)) {
02155 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
02156 return result;
02157 }
02158
02159
02160 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02161 &connect_pol);
02162 if (!NT_STATUS_IS_OK(result)) {
02163 goto done;
02164 }
02165
02166
02167 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02168 MAXIMUM_ALLOWED_ACCESS,
02169 &sid, &domain_pol);
02170 if (!NT_STATUS_IS_OK(result)) {
02171 goto done;
02172 }
02173
02174 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
02175 MAXIMUM_ALLOWED_ACCESS,
02176 alias_rid, &alias_pol);
02177
02178 if (!NT_STATUS_IS_OK(result)) {
02179 return result;
02180 }
02181
02182 result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
02183
02184 if (!NT_STATUS_IS_OK(result)) {
02185 return result;
02186 }
02187
02188 done:
02189 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
02190 return result;
02191 }
02192
02193 static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
02194 const char *domain_name,
02195 struct cli_state *cli,
02196 struct rpc_pipe_client *pipe_hnd,
02197 TALLOC_CTX *mem_ctx,
02198 int argc,
02199 const char **argv)
02200 {
02201 DOM_SID group_sid;
02202 enum lsa_SidType group_type;
02203
02204 if (argc != 2) {
02205 d_printf("Usage: 'net rpc group addmem <group> <member>\n");
02206 return NT_STATUS_UNSUCCESSFUL;
02207 }
02208
02209 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
02210 &group_sid, &group_type))) {
02211 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
02212 return NT_STATUS_UNSUCCESSFUL;
02213 }
02214
02215 if (group_type == SID_NAME_DOM_GRP) {
02216 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
02217 &group_sid, argv[1]);
02218
02219 if (!NT_STATUS_IS_OK(result)) {
02220 d_fprintf(stderr, "Could not add %s to %s: %s\n",
02221 argv[1], argv[0], nt_errstr(result));
02222 }
02223 return result;
02224 }
02225
02226 if (group_type == SID_NAME_ALIAS) {
02227 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
02228 &group_sid, argv[1]);
02229
02230 if (!NT_STATUS_IS_OK(result)) {
02231 d_fprintf(stderr, "Could not add %s to %s: %s\n",
02232 argv[1], argv[0], nt_errstr(result));
02233 }
02234 return result;
02235 }
02236
02237 d_fprintf(stderr, "Can only add members to global or local groups "
02238 "which %s is not\n", argv[0]);
02239
02240 return NT_STATUS_UNSUCCESSFUL;
02241 }
02242
02243 static int rpc_group_addmem(int argc, const char **argv)
02244 {
02245 return run_rpc_command(NULL, PI_SAMR, 0,
02246 rpc_group_addmem_internals,
02247 argc, argv);
02248 }
02249
02250 static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
02251 TALLOC_CTX *mem_ctx,
02252 const DOM_SID *group_sid,
02253 const char *member)
02254 {
02255 POLICY_HND connect_pol, domain_pol;
02256 NTSTATUS result;
02257 uint32 group_rid;
02258 POLICY_HND group_pol;
02259
02260 uint32 num_rids;
02261 uint32 *rids = NULL;
02262 uint32 *rid_types = NULL;
02263
02264 DOM_SID sid;
02265
02266 sid_copy(&sid, group_sid);
02267
02268 if (!sid_split_rid(&sid, &group_rid))
02269 return NT_STATUS_UNSUCCESSFUL;
02270
02271
02272 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02273 &connect_pol);
02274 if (!NT_STATUS_IS_OK(result))
02275 return result;
02276
02277
02278 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02279 MAXIMUM_ALLOWED_ACCESS,
02280 &sid, &domain_pol);
02281 if (!NT_STATUS_IS_OK(result))
02282 return result;
02283
02284 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
02285 1, &member,
02286 &num_rids, &rids, &rid_types);
02287
02288 if (!NT_STATUS_IS_OK(result)) {
02289 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
02290 goto done;
02291 }
02292
02293 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
02294 MAXIMUM_ALLOWED_ACCESS,
02295 group_rid, &group_pol);
02296
02297 if (!NT_STATUS_IS_OK(result))
02298 goto done;
02299
02300 result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
02301
02302 done:
02303 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
02304 return result;
02305 }
02306
02307 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
02308 TALLOC_CTX *mem_ctx,
02309 const DOM_SID *alias_sid,
02310 const char *member)
02311 {
02312 POLICY_HND connect_pol, domain_pol;
02313 NTSTATUS result;
02314 uint32 alias_rid;
02315 POLICY_HND alias_pol;
02316
02317 DOM_SID member_sid;
02318 enum lsa_SidType member_type;
02319
02320 DOM_SID sid;
02321
02322 sid_copy(&sid, alias_sid);
02323
02324 if (!sid_split_rid(&sid, &alias_rid))
02325 return NT_STATUS_UNSUCCESSFUL;
02326
02327 result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
02328 &member_sid, &member_type);
02329
02330 if (!NT_STATUS_IS_OK(result)) {
02331 d_fprintf(stderr, "Could not lookup up group member %s\n", member);
02332 return result;
02333 }
02334
02335
02336 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02337 &connect_pol);
02338 if (!NT_STATUS_IS_OK(result)) {
02339 goto done;
02340 }
02341
02342
02343 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02344 MAXIMUM_ALLOWED_ACCESS,
02345 &sid, &domain_pol);
02346 if (!NT_STATUS_IS_OK(result)) {
02347 goto done;
02348 }
02349
02350 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
02351 MAXIMUM_ALLOWED_ACCESS,
02352 alias_rid, &alias_pol);
02353
02354 if (!NT_STATUS_IS_OK(result))
02355 return result;
02356
02357 result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
02358
02359 if (!NT_STATUS_IS_OK(result))
02360 return result;
02361
02362 done:
02363 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
02364 return result;
02365 }
02366
02367 static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
02368 const char *domain_name,
02369 struct cli_state *cli,
02370 struct rpc_pipe_client *pipe_hnd,
02371 TALLOC_CTX *mem_ctx,
02372 int argc,
02373 const char **argv)
02374 {
02375 DOM_SID group_sid;
02376 enum lsa_SidType group_type;
02377
02378 if (argc != 2) {
02379 d_printf("Usage: 'net rpc group delmem <group> <member>\n");
02380 return NT_STATUS_UNSUCCESSFUL;
02381 }
02382
02383 if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
02384 &group_sid, &group_type))) {
02385 d_fprintf(stderr, "Could not lookup group name %s\n", argv[0]);
02386 return NT_STATUS_UNSUCCESSFUL;
02387 }
02388
02389 if (group_type == SID_NAME_DOM_GRP) {
02390 NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
02391 &group_sid, argv[1]);
02392
02393 if (!NT_STATUS_IS_OK(result)) {
02394 d_fprintf(stderr, "Could not del %s from %s: %s\n",
02395 argv[1], argv[0], nt_errstr(result));
02396 }
02397 return result;
02398 }
02399
02400 if (group_type == SID_NAME_ALIAS) {
02401 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
02402 &group_sid, argv[1]);
02403
02404 if (!NT_STATUS_IS_OK(result)) {
02405 d_fprintf(stderr, "Could not del %s from %s: %s\n",
02406 argv[1], argv[0], nt_errstr(result));
02407 }
02408 return result;
02409 }
02410
02411 d_fprintf(stderr, "Can only delete members from global or local groups "
02412 "which %s is not\n", argv[0]);
02413
02414 return NT_STATUS_UNSUCCESSFUL;
02415 }
02416
02417 static int rpc_group_delmem(int argc, const char **argv)
02418 {
02419 return run_rpc_command(NULL, PI_SAMR, 0,
02420 rpc_group_delmem_internals,
02421 argc, argv);
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
02441 const char *domain_name,
02442 struct cli_state *cli,
02443 struct rpc_pipe_client *pipe_hnd,
02444 TALLOC_CTX *mem_ctx,
02445 int argc,
02446 const char **argv)
02447 {
02448 POLICY_HND connect_pol, domain_pol;
02449 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
02450 uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
02451 struct acct_info *groups;
02452 BOOL global = False;
02453 BOOL local = False;
02454 BOOL builtin = False;
02455
02456 if (argc == 0) {
02457 global = True;
02458 local = True;
02459 builtin = True;
02460 }
02461
02462 for (i=0; i<argc; i++) {
02463 if (strequal(argv[i], "global"))
02464 global = True;
02465
02466 if (strequal(argv[i], "local"))
02467 local = True;
02468
02469 if (strequal(argv[i], "builtin"))
02470 builtin = True;
02471 }
02472
02473
02474
02475 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02476 &connect_pol);
02477 if (!NT_STATUS_IS_OK(result)) {
02478 goto done;
02479 }
02480
02481
02482
02483 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02484 MAXIMUM_ALLOWED_ACCESS,
02485 domain_sid, &domain_pol);
02486 if (!NT_STATUS_IS_OK(result)) {
02487 goto done;
02488 }
02489
02490
02491 if (opt_long_list_entries)
02492 d_printf("\nGroup name Comment"\
02493 "\n-----------------------------\n");
02494 do {
02495 SAM_DISPINFO_CTR ctr;
02496 SAM_DISPINFO_3 info3;
02497 uint32 max_size;
02498
02499 ZERO_STRUCT(ctr);
02500 ZERO_STRUCT(info3);
02501 ctr.sam.info3 = &info3;
02502
02503 if (!global) break;
02504
02505 get_query_dispinfo_params(
02506 loop_count, &max_entries, &max_size);
02507
02508 result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
02509 &start_idx, 3, &num_entries,
02510 max_entries, max_size, &ctr);
02511
02512 if (!NT_STATUS_IS_OK(result) &&
02513 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
02514 break;
02515
02516 for (i = 0; i < num_entries; i++) {
02517
02518 fstring group, desc;
02519
02520 unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
02521 unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
02522
02523 if (opt_long_list_entries)
02524 printf("%-21.21s %-50.50s\n",
02525 group, desc);
02526 else
02527 printf("%s\n", group);
02528 }
02529 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
02530
02531 start_idx = 0;
02532 do {
02533 if (!local) break;
02534
02535
02536
02537
02538
02539
02540
02541 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
02542 &start_idx, 0xffff,
02543 &groups, &num_entries);
02544
02545 if (!NT_STATUS_IS_OK(result) &&
02546 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
02547 break;
02548
02549 for (i = 0; i < num_entries; i++) {
02550
02551 char *description = NULL;
02552
02553 if (opt_long_list_entries) {
02554
02555 POLICY_HND alias_pol;
02556 ALIAS_INFO_CTR ctr;
02557
02558 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
02559 &domain_pol,
02560 0x8,
02561 groups[i].rid,
02562 &alias_pol))) &&
02563 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
02564 &alias_pol, 3,
02565 &ctr))) &&
02566 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
02567 &alias_pol)))) {
02568 description = unistr2_tdup(mem_ctx,
02569 ctr.alias.info3.description.string);
02570 }
02571 }
02572
02573 if (description != NULL) {
02574 printf("%-21.21s %-50.50s\n",
02575 groups[i].acct_name,
02576 description);
02577 } else {
02578 printf("%s\n", groups[i].acct_name);
02579 }
02580 }
02581 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
02582 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
02583
02584
02585 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02586 MAXIMUM_ALLOWED_ACCESS,
02587 &global_sid_Builtin, &domain_pol);
02588 if (!NT_STATUS_IS_OK(result)) {
02589 goto done;
02590 }
02591
02592 start_idx = 0;
02593 do {
02594 if (!builtin) break;
02595
02596 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
02597 &start_idx, max_entries,
02598 &groups, &num_entries);
02599
02600 if (!NT_STATUS_IS_OK(result) &&
02601 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
02602 break;
02603
02604 for (i = 0; i < num_entries; i++) {
02605
02606 char *description = NULL;
02607
02608 if (opt_long_list_entries) {
02609
02610 POLICY_HND alias_pol;
02611 ALIAS_INFO_CTR ctr;
02612
02613 if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
02614 &domain_pol,
02615 0x8,
02616 groups[i].rid,
02617 &alias_pol))) &&
02618 (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
02619 &alias_pol, 3,
02620 &ctr))) &&
02621 (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
02622 &alias_pol)))) {
02623 description = unistr2_tdup(mem_ctx,
02624 ctr.alias.info3.description.string);
02625 }
02626 }
02627
02628 if (description != NULL) {
02629 printf("%-21.21s %-50.50s\n",
02630 groups[i].acct_name,
02631 description);
02632 } else {
02633 printf("%s\n", groups[i].acct_name);
02634 }
02635 }
02636 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
02637
02638 done:
02639 return result;
02640 }
02641
02642 static int rpc_group_list(int argc, const char **argv)
02643 {
02644 return run_rpc_command(NULL, PI_SAMR, 0,
02645 rpc_group_list_internals,
02646 argc, argv);
02647 }
02648
02649 static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
02650 TALLOC_CTX *mem_ctx,
02651 const char *domain_name,
02652 const DOM_SID *domain_sid,
02653 POLICY_HND *domain_pol,
02654 uint32 rid)
02655 {
02656 NTSTATUS result;
02657 POLICY_HND group_pol;
02658 uint32 num_members, *group_rids, *group_attrs;
02659 uint32 num_names;
02660 char **names;
02661 uint32 *name_types;
02662 int i;
02663
02664 fstring sid_str;
02665 sid_to_string(sid_str, domain_sid);
02666
02667 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
02668 MAXIMUM_ALLOWED_ACCESS,
02669 rid, &group_pol);
02670
02671 if (!NT_STATUS_IS_OK(result))
02672 return result;
02673
02674 result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
02675 &num_members, &group_rids,
02676 &group_attrs);
02677
02678 if (!NT_STATUS_IS_OK(result))
02679 return result;
02680
02681 while (num_members > 0) {
02682 int this_time = 512;
02683
02684 if (num_members < this_time)
02685 this_time = num_members;
02686
02687 result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
02688 this_time, group_rids,
02689 &num_names, &names, &name_types);
02690
02691 if (!NT_STATUS_IS_OK(result))
02692 return result;
02693
02694
02695
02696
02697 for (i = 0; i < this_time; i++) {
02698
02699 if (opt_long_list_entries) {
02700 printf("%s-%d %s\\%s %d\n", sid_str,
02701 group_rids[i], domain_name, names[i],
02702 SID_NAME_USER);
02703 } else {
02704 printf("%s\\%s\n", domain_name, names[i]);
02705 }
02706 }
02707
02708 num_members -= this_time;
02709 group_rids += 512;
02710 }
02711
02712 return NT_STATUS_OK;
02713 }
02714
02715 static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
02716 TALLOC_CTX *mem_ctx,
02717 POLICY_HND *domain_pol,
02718 uint32 rid)
02719 {
02720 NTSTATUS result;
02721 struct rpc_pipe_client *lsa_pipe;
02722 POLICY_HND alias_pol, lsa_pol;
02723 uint32 num_members;
02724 DOM_SID *alias_sids;
02725 char **domains;
02726 char **names;
02727 enum lsa_SidType *types;
02728 int i;
02729
02730 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
02731 MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
02732
02733 if (!NT_STATUS_IS_OK(result))
02734 return result;
02735
02736 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
02737 &num_members, &alias_sids);
02738
02739 if (!NT_STATUS_IS_OK(result)) {
02740 d_fprintf(stderr, "Couldn't list alias members\n");
02741 return result;
02742 }
02743
02744 if (num_members == 0) {
02745 return NT_STATUS_OK;
02746 }
02747
02748 lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
02749 if (!lsa_pipe) {
02750 d_fprintf(stderr, "Couldn't open LSA pipe. Error was %s\n",
02751 nt_errstr(result) );
02752 return result;
02753 }
02754
02755 result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
02756 SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
02757
02758 if (!NT_STATUS_IS_OK(result)) {
02759 d_fprintf(stderr, "Couldn't open LSA policy handle\n");
02760 cli_rpc_pipe_close(lsa_pipe);
02761 return result;
02762 }
02763
02764 result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
02765 alias_sids,
02766 &domains, &names, &types);
02767
02768 if (!NT_STATUS_IS_OK(result) &&
02769 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
02770 d_fprintf(stderr, "Couldn't lookup SIDs\n");
02771 cli_rpc_pipe_close(lsa_pipe);
02772 return result;
02773 }
02774
02775 for (i = 0; i < num_members; i++) {
02776 fstring sid_str;
02777 sid_to_string(sid_str, &alias_sids[i]);
02778
02779 if (opt_long_list_entries) {
02780 printf("%s %s\\%s %d\n", sid_str,
02781 domains[i] ? domains[i] : "*unknown*",
02782 names[i] ? names[i] : "*unknown*", types[i]);
02783 } else {
02784 if (domains[i])
02785 printf("%s\\%s\n", domains[i], names[i]);
02786 else
02787 printf("%s\n", sid_str);
02788 }
02789 }
02790
02791 cli_rpc_pipe_close(lsa_pipe);
02792 return NT_STATUS_OK;
02793 }
02794
02795 static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
02796 const char *domain_name,
02797 struct cli_state *cli,
02798 struct rpc_pipe_client *pipe_hnd,
02799 TALLOC_CTX *mem_ctx,
02800 int argc,
02801 const char **argv)
02802 {
02803 NTSTATUS result;
02804 POLICY_HND connect_pol, domain_pol;
02805 uint32 num_rids, *rids, *rid_types;
02806
02807
02808
02809 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02810 &connect_pol);
02811
02812 if (!NT_STATUS_IS_OK(result))
02813 return result;
02814
02815
02816
02817 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02818 MAXIMUM_ALLOWED_ACCESS,
02819 domain_sid, &domain_pol);
02820
02821 if (!NT_STATUS_IS_OK(result))
02822 return result;
02823
02824 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
02825 1, argv, &num_rids, &rids, &rid_types);
02826
02827 if (!NT_STATUS_IS_OK(result)) {
02828
02829
02830
02831 DOM_SID sid_Builtin;
02832
02833 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
02834
02835 string_to_sid(&sid_Builtin, "S-1-5-32");
02836
02837 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02838 MAXIMUM_ALLOWED_ACCESS,
02839 &sid_Builtin, &domain_pol);
02840
02841 if (!NT_STATUS_IS_OK(result)) {
02842 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
02843 return result;
02844 }
02845
02846 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
02847 1, argv, &num_rids,
02848 &rids, &rid_types);
02849
02850 if (!NT_STATUS_IS_OK(result)) {
02851 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
02852 return result;
02853 }
02854 }
02855
02856 if (num_rids != 1) {
02857 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
02858 return result;
02859 }
02860
02861 if (rid_types[0] == SID_NAME_DOM_GRP) {
02862 return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
02863 domain_sid, &domain_pol,
02864 rids[0]);
02865 }
02866
02867 if (rid_types[0] == SID_NAME_ALIAS) {
02868 return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
02869 rids[0]);
02870 }
02871
02872 return NT_STATUS_NO_SUCH_GROUP;
02873 }
02874
02875 static int rpc_group_members(int argc, const char **argv)
02876 {
02877 if (argc != 1) {
02878 return rpc_group_usage(argc, argv);
02879 }
02880
02881 return run_rpc_command(NULL, PI_SAMR, 0,
02882 rpc_group_members_internals,
02883 argc, argv);
02884 }
02885
02886 static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
02887 const char *domain_name,
02888 struct cli_state *cli,
02889 struct rpc_pipe_client *pipe_hnd,
02890 TALLOC_CTX *mem_ctx,
02891 int argc,
02892 const char **argv)
02893 {
02894 NTSTATUS result;
02895 POLICY_HND connect_pol, domain_pol, group_pol;
02896 uint32 num_rids, *rids, *rid_types;
02897 GROUP_INFO_CTR ctr;
02898
02899 if (argc != 2) {
02900 d_printf("Usage: 'net rpc group rename group newname'\n");
02901 return NT_STATUS_UNSUCCESSFUL;
02902 }
02903
02904
02905
02906 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
02907 &connect_pol);
02908
02909 if (!NT_STATUS_IS_OK(result))
02910 return result;
02911
02912
02913
02914 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
02915 MAXIMUM_ALLOWED_ACCESS,
02916 domain_sid, &domain_pol);
02917
02918 if (!NT_STATUS_IS_OK(result))
02919 return result;
02920
02921 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
02922 1, argv, &num_rids, &rids, &rid_types);
02923
02924 if (num_rids != 1) {
02925 d_fprintf(stderr, "Couldn't find group %s\n", argv[0]);
02926 return result;
02927 }
02928
02929 if (rid_types[0] != SID_NAME_DOM_GRP) {
02930 d_fprintf(stderr, "Can only rename domain groups\n");
02931 return NT_STATUS_UNSUCCESSFUL;
02932 }
02933
02934 result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
02935 MAXIMUM_ALLOWED_ACCESS,
02936 rids[0], &group_pol);
02937
02938 if (!NT_STATUS_IS_OK(result))
02939 return result;
02940
02941 ZERO_STRUCT(ctr);
02942
02943 ctr.switch_value1 = 2;
02944 init_samr_group_info2(&ctr.group.info2, argv[1]);
02945
02946 result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
02947
02948 if (!NT_STATUS_IS_OK(result))
02949 return result;
02950
02951 return NT_STATUS_NO_SUCH_GROUP;
02952 }
02953
02954 static int rpc_group_rename(int argc, const char **argv)
02955 {
02956 if (argc != 2) {
02957 return rpc_group_usage(argc, argv);
02958 }
02959
02960 return run_rpc_command(NULL, PI_SAMR, 0,
02961 rpc_group_rename_internals,
02962 argc, argv);
02963 }
02964
02965
02966
02967
02968
02969
02970
02971
02972 int net_rpc_group(int argc, const char **argv)
02973 {
02974 struct functable func[] = {
02975 {"add", rpc_group_add},
02976 {"delete", rpc_group_delete},
02977 {"addmem", rpc_group_addmem},
02978 {"delmem", rpc_group_delmem},
02979 {"list", rpc_group_list},
02980 {"members", rpc_group_members},
02981 {"rename", rpc_group_rename},
02982 {NULL, NULL}
02983 };
02984
02985 if (argc == 0) {
02986 return run_rpc_command(NULL, PI_SAMR, 0,
02987 rpc_group_list_internals,
02988 argc, argv);
02989 }
02990
02991 return net_run_function(argc, argv, func, rpc_group_usage);
02992 }
02993
02994
02995
02996 static int rpc_share_usage(int argc, const char **argv)
02997 {
02998 return net_help_share(argc, argv);
02999 }
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016 static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
03017 const char *domain_name,
03018 struct cli_state *cli,
03019 struct rpc_pipe_client *pipe_hnd,
03020 TALLOC_CTX *mem_ctx,int argc,
03021 const char **argv)
03022 {
03023 WERROR result;
03024 char *sharename;
03025 char *path;
03026 uint32 type = STYPE_DISKTREE;
03027 uint32 num_users=0, perms=0;
03028 char *password=NULL;
03029 uint32 level = 2;
03030
03031 if ((sharename = talloc_strdup(mem_ctx, argv[0])) == NULL) {
03032 return NT_STATUS_NO_MEMORY;
03033 }
03034
03035 path = strchr(sharename, '=');
03036 if (!path)
03037 return NT_STATUS_UNSUCCESSFUL;
03038 *path++ = '\0';
03039
03040 result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
03041 opt_comment, perms, opt_maxusers,
03042 num_users, path, password,
03043 level, NULL);
03044 return werror_to_ntstatus(result);
03045 }
03046
03047 static int rpc_share_add(int argc, const char **argv)
03048 {
03049 if ((argc < 1) || !strchr(argv[0], '=')) {
03050 DEBUG(1,("Sharename or path not specified on add\n"));
03051 return rpc_share_usage(argc, argv);
03052 }
03053 return run_rpc_command(NULL, PI_SRVSVC, 0,
03054 rpc_share_add_internals,
03055 argc, argv);
03056 }
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073 static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
03074 const char *domain_name,
03075 struct cli_state *cli,
03076 struct rpc_pipe_client *pipe_hnd,
03077 TALLOC_CTX *mem_ctx,
03078 int argc,
03079 const char **argv)
03080 {
03081 WERROR result;
03082
03083 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
03084 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
03085 }
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097 static int rpc_share_delete(int argc, const char **argv)
03098 {
03099 if (argc < 1) {
03100 DEBUG(1,("Sharename not specified on delete\n"));
03101 return rpc_share_usage(argc, argv);
03102 }
03103 return run_rpc_command(NULL, PI_SRVSVC, 0,
03104 rpc_share_del_internals,
03105 argc, argv);
03106 }
03107
03108
03109
03110
03111
03112
03113
03114 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
03115 {
03116 fstring netname = "", remark = "";
03117
03118 rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
03119 rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
03120
03121 if (opt_long_list_entries) {
03122 d_printf("%-12s %-8.8s %-50s\n",
03123 netname, share_type[info1->info_1.type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)], remark);
03124 } else {
03125 d_printf("%s\n", netname);
03126 }
03127
03128 }
03129
03130 static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
03131 TALLOC_CTX *mem_ctx,
03132 uint32 level,
03133 int argc,
03134 const char **argv,
03135 SRV_SHARE_INFO_CTR *ctr)
03136 {
03137 WERROR result;
03138 SRV_SHARE_INFO info;
03139
03140
03141 if (argc == 0) {
03142
03143 ENUM_HND hnd;
03144 uint32 preferred_len = 0xffffffff;
03145
03146 init_enum_hnd(&hnd, 0);
03147
03148 return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
03149 preferred_len, &hnd);
03150 }
03151
03152
03153 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
03154
03155 if (!W_ERROR_IS_OK(result))
03156 goto done;
03157
03158
03159 ZERO_STRUCTP(ctr);
03160
03161 ctr->info_level = ctr->switch_value = level;
03162 ctr->ptr_share_info = ctr->ptr_entries = 1;
03163 ctr->num_entries = ctr->num_entries2 = 1;
03164
03165 switch (level) {
03166 case 1:
03167 {
03168 char *s;
03169 SRV_SHARE_INFO_1 *info1;
03170
03171 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, 1);
03172 if (ctr->share.info1 == NULL) {
03173 result = WERR_NOMEM;
03174 goto done;
03175 }
03176 info1 = ctr->share.info1;
03177
03178 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
03179
03180
03181
03182 memcpy(&info1->info_1, &info.share.info1.info_1, sizeof(SH_INFO_1));
03183
03184
03185
03186 s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_netname);
03187 if (s)
03188 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
03189
03190 s = unistr2_tdup(mem_ctx, &info.share.info1.info_1_str.uni_remark);
03191 if (s)
03192 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
03193 }
03194 case 2:
03195 {
03196 char *s;
03197 SRV_SHARE_INFO_2 *info2;
03198
03199 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, 1);
03200 if (ctr->share.info2 == NULL) {
03201 result = WERR_NOMEM;
03202 goto done;
03203 }
03204 info2 = ctr->share.info2;
03205
03206 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
03207
03208
03209
03210 memcpy(&info2->info_2, &info.share.info2.info_2, sizeof(SH_INFO_2));
03211
03212
03213
03214 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_netname);
03215 if (s)
03216 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
03217
03218 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_remark);
03219 if (s)
03220 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
03221
03222 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_path);
03223 if (s)
03224 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
03225
03226 s = unistr2_tdup(mem_ctx, &info.share.info2.info_2_str.uni_passwd);
03227 if (s)
03228 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
03229 }
03230 case 502:
03231 {
03232 char *s;
03233 SRV_SHARE_INFO_502 *info502;
03234
03235 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, 1);
03236 if (ctr->share.info502 == NULL) {
03237 result = WERR_NOMEM;
03238 goto done;
03239 }
03240 info502 = ctr->share.info502;
03241
03242 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
03243
03244
03245
03246 memcpy(&info502->info_502, &info.share.info502.info_502, sizeof(SH_INFO_502));
03247
03248
03249
03250 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_netname);
03251 if (s)
03252 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
03253
03254 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_remark);
03255 if (s)
03256 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
03257
03258 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_path);
03259 if (s)
03260 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
03261
03262 s = unistr2_tdup(mem_ctx, &info.share.info502.info_502_str.uni_passwd);
03263 if (s)
03264 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
03265
03266 info502->info_502_str.sd = dup_sec_desc(mem_ctx, info.share.info502.info_502_str.sd);
03267
03268 }
03269
03270 }
03271
03272 done:
03273 return result;
03274 }
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292 static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
03293 const char *domain_name,
03294 struct cli_state *cli,
03295 struct rpc_pipe_client *pipe_hnd,
03296 TALLOC_CTX *mem_ctx,
03297 int argc,
03298 const char **argv)
03299 {
03300 SRV_SHARE_INFO_CTR ctr;
03301 WERROR result;
03302 uint32 i, level = 1;
03303
03304 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
03305 if (!W_ERROR_IS_OK(result))
03306 goto done;
03307
03308
03309
03310 if (opt_long_list_entries) {
03311 d_printf(
03312 "\nEnumerating shared resources (exports) on remote server:\n\n"\
03313 "\nShare name Type Description\n"\
03314 "---------- ---- -----------\n");
03315 }
03316 for (i = 0; i < ctr.num_entries; i++)
03317 display_share_info_1(&ctr.share.info1[i]);
03318 done:
03319 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
03320 }
03321
03322
03323
03324
03325
03326
03327
03328 static int rpc_share_list(int argc, const char **argv)
03329 {
03330 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_list_internals, argc, argv);
03331 }
03332
03333 static BOOL check_share_availability(struct cli_state *cli, const char *netname)
03334 {
03335 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
03336 d_printf("skipping [%s]: not a file share.\n", netname);
03337 return False;
03338 }
03339
03340 if (!cli_tdis(cli))
03341 return False;
03342
03343 return True;
03344 }
03345
03346 static BOOL check_share_sanity(struct cli_state *cli, fstring netname, uint32 type)
03347 {
03348
03349 if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
03350 printf("share [%s] is not a diskshare (type: %x)\n", netname, type);
03351 return False;
03352 }
03353
03354
03355
03356 if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
03357 strequal(netname,"global"))
03358 return False;
03359
03360 if (opt_exclude && in_list(netname, opt_exclude, False)) {
03361 printf("excluding [%s]\n", netname);
03362 return False;
03363 }
03364
03365 return check_share_availability(cli, netname);
03366 }
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384 static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
03385 const char *domain_name,
03386 struct cli_state *cli,
03387 struct rpc_pipe_client *pipe_hnd,
03388 TALLOC_CTX *mem_ctx,
03389 int argc,
03390 const char **argv)
03391 {
03392 WERROR result;
03393 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
03394 SRV_SHARE_INFO_CTR ctr_src;
03395 uint32 type = STYPE_DISKTREE;
03396 char *password = NULL;
03397 uint32 i;
03398 struct rpc_pipe_client *srvsvc_pipe = NULL;
03399 struct cli_state *cli_dst = NULL;
03400 uint32 level = 502;
03401
03402 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
03403 if (!W_ERROR_IS_OK(result))
03404 goto done;
03405
03406
03407 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
03408 if (!NT_STATUS_IS_OK(nt_status))
03409 return nt_status;
03410
03411
03412 for (i = 0; i < ctr_src.num_entries; i++) {
03413
03414 fstring netname = "", remark = "", path = "";
03415
03416 nt_status = NT_STATUS_UNSUCCESSFUL;
03417
03418 rpcstr_pull_unistr2_fstring(
03419 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
03420 rpcstr_pull_unistr2_fstring(
03421 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
03422 rpcstr_pull_unistr2_fstring(
03423 path, &ctr_src.share.info502[i].info_502_str.uni_path);
03424
03425 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
03426 continue;
03427
03428
03429
03430 printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
03431 netname, path, remark);
03432
03433 result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
03434 ctr_src.share.info502[i].info_502.perms,
03435 ctr_src.share.info502[i].info_502.max_uses,
03436 ctr_src.share.info502[i].info_502.num_uses,
03437 path, password, level,
03438 NULL);
03439
03440 if (W_ERROR_V(result) == W_ERROR_V(WERR_ALREADY_EXISTS)) {
03441 printf(" [%s] does already exist\n", netname);
03442 continue;
03443 }
03444
03445 if (!W_ERROR_IS_OK(result)) {
03446 printf("cannot add share: %s\n", dos_errstr(result));
03447 goto done;
03448 }
03449
03450 }
03451
03452 nt_status = NT_STATUS_OK;
03453
03454 done:
03455 if (cli_dst) {
03456 cli_shutdown(cli_dst);
03457 }
03458
03459 return nt_status;
03460
03461 }
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472 static int rpc_share_migrate_shares(int argc, const char **argv)
03473 {
03474
03475 if (!opt_host) {
03476 printf("no server to migrate\n");
03477 return -1;
03478 }
03479
03480 return run_rpc_command(NULL, PI_SRVSVC, 0,
03481 rpc_share_migrate_shares_internals,
03482 argc, argv);
03483 }
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493 static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
03494 {
03495 static NTSTATUS nt_status;
03496 static struct copy_clistate *local_state;
03497 static fstring filename, new_mask;
03498 fstring dir;
03499 char *old_dir;
03500
03501 local_state = (struct copy_clistate *)state;
03502 nt_status = NT_STATUS_UNSUCCESSFUL;
03503
03504 if (strequal(f->name, ".") || strequal(f->name, ".."))
03505 return;
03506
03507 DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
03508
03509
03510 if (f->mode & aDIR) {
03511
03512 DEBUG(3,("got dir: %s\n", f->name));
03513
03514 fstrcpy(dir, local_state->cwd);
03515 fstrcat(dir, "\\");
03516 fstrcat(dir, f->name);
03517
03518 switch (net_mode_share)
03519 {
03520 case NET_MODE_SHARE_MIGRATE:
03521
03522 nt_status = net_copy_file(local_state->mem_ctx,
03523 local_state->cli_share_src,
03524 local_state->cli_share_dst,
03525 dir, dir,
03526 opt_acls? True : False,
03527 opt_attrs? True : False,
03528 opt_timestamps? True : False,
03529 False);
03530 break;
03531 default:
03532 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
03533 return;
03534 }
03535
03536 if (!NT_STATUS_IS_OK(nt_status))
03537 printf("could not handle dir %s: %s\n",
03538 dir, nt_errstr(nt_status));
03539
03540
03541 fstrcpy(new_mask, dir);
03542 fstrcat(new_mask, "\\*");
03543
03544 old_dir = local_state->cwd;
03545 local_state->cwd = dir;
03546 if (!sync_files(local_state, new_mask))
03547 printf("could not handle files\n");
03548 local_state->cwd = old_dir;
03549
03550 return;
03551 }
03552
03553
03554
03555 fstrcpy(filename, local_state->cwd);
03556 fstrcat(filename, "\\");
03557 fstrcat(filename, f->name);
03558
03559 DEBUG(3,("got file: %s\n", filename));
03560
03561 switch (net_mode_share)
03562 {
03563 case NET_MODE_SHARE_MIGRATE:
03564 nt_status = net_copy_file(local_state->mem_ctx,
03565 local_state->cli_share_src,
03566 local_state->cli_share_dst,
03567 filename, filename,
03568 opt_acls? True : False,
03569 opt_attrs? True : False,
03570 opt_timestamps? True: False,
03571 True);
03572 break;
03573 default:
03574 d_fprintf(stderr, "Unsupported file mode %d\n", net_mode_share);
03575 return;
03576 }
03577
03578 if (!NT_STATUS_IS_OK(nt_status))
03579 printf("could not handle file %s: %s\n",
03580 filename, nt_errstr(nt_status));
03581
03582 }
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593 BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
03594 {
03595 struct cli_state *targetcli;
03596 pstring targetpath;
03597
03598 DEBUG(3,("calling cli_list with mask: %s\n", mask));
03599
03600 if ( !cli_resolve_path( "", cp_clistate->cli_share_src, mask, &targetcli, targetpath ) ) {
03601 d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
03602 mask, cli_errstr(cp_clistate->cli_share_src));
03603 return False;
03604 }
03605
03606 if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
03607 d_fprintf(stderr, "listing %s failed with error: %s\n",
03608 mask, cli_errstr(targetcli));
03609 return False;
03610 }
03611
03612 return True;
03613 }
03614
03615
03616
03617
03618
03619
03620
03621 BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
03622 const char *sharename)
03623 {
03624 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
03625
03626 switch (net_mode_share) {
03627 case NET_MODE_SHARE_MIGRATE:
03628 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
03629 nt_status = net_copy_fileattr(cp_clistate->mem_ctx,
03630 cp_clistate->cli_share_src,
03631 cp_clistate->cli_share_dst,
03632 "\\", "\\",
03633 opt_acls? True : False,
03634 opt_attrs? True : False,
03635 opt_timestamps? True: False,
03636 False);
03637 break;
03638 default:
03639 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
03640 break;
03641 }
03642
03643 if (!NT_STATUS_IS_OK(nt_status)) {
03644 printf("Could handle directory attributes for top level directory of share %s. Error %s\n",
03645 sharename, nt_errstr(nt_status));
03646 return False;
03647 }
03648
03649 return True;
03650 }
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668 static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
03669 const char *domain_name,
03670 struct cli_state *cli,
03671 struct rpc_pipe_client *pipe_hnd,
03672 TALLOC_CTX *mem_ctx,
03673 int argc,
03674 const char **argv)
03675 {
03676 WERROR result;
03677 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
03678 SRV_SHARE_INFO_CTR ctr_src;
03679 uint32 i;
03680 uint32 level = 502;
03681 struct copy_clistate cp_clistate;
03682 BOOL got_src_share = False;
03683 BOOL got_dst_share = False;
03684 pstring mask = "\\*";
03685 char *dst = NULL;
03686
03687 dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
03688
03689 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
03690
03691 if (!W_ERROR_IS_OK(result))
03692 goto done;
03693
03694 for (i = 0; i < ctr_src.num_entries; i++) {
03695
03696 fstring netname = "";
03697
03698 rpcstr_pull_unistr2_fstring(
03699 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
03700
03701 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
03702 continue;
03703
03704
03705 if (strequal(netname, "print$") || netname[1] == '$') {
03706 d_printf("skipping [%s]: builtin/hidden share\n", netname);
03707 continue;
03708 }
03709
03710 switch (net_mode_share)
03711 {
03712 case NET_MODE_SHARE_MIGRATE:
03713 printf("syncing");
03714 break;
03715 default:
03716 d_fprintf(stderr, "Unsupported mode %d\n", net_mode_share);
03717 break;
03718 }
03719 printf(" [%s] files and directories %s ACLs, %s DOS Attributes %s\n",
03720 netname,
03721 opt_acls ? "including" : "without",
03722 opt_attrs ? "including" : "without",
03723 opt_timestamps ? "(preserving timestamps)" : "");
03724
03725 cp_clistate.mem_ctx = mem_ctx;
03726 cp_clistate.cli_share_src = NULL;
03727 cp_clistate.cli_share_dst = NULL;
03728 cp_clistate.cwd = NULL;
03729 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
03730
03731
03732 nt_status = connect_to_service(&cp_clistate.cli_share_src,
03733 &cli->dest_ip, cli->desthost,
03734 netname, "A:");
03735 if (!NT_STATUS_IS_OK(nt_status))
03736 goto done;
03737
03738 got_src_share = True;
03739
03740 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
03741
03742 nt_status = connect_to_service(&cp_clistate.cli_share_dst,
03743 NULL, dst, netname, "A:");
03744 if (!NT_STATUS_IS_OK(nt_status))
03745 goto done;
03746
03747 got_dst_share = True;
03748 }
03749
03750 if (!copy_top_level_perms(&cp_clistate, netname)) {
03751 d_fprintf(stderr, "Could not handle the top level directory permissions for the share: %s\n", netname);
03752 nt_status = NT_STATUS_UNSUCCESSFUL;
03753 goto done;
03754 }
03755
03756 if (!sync_files(&cp_clistate, mask)) {
03757 d_fprintf(stderr, "could not handle files for share: %s\n", netname);
03758 nt_status = NT_STATUS_UNSUCCESSFUL;
03759 goto done;
03760 }
03761 }
03762
03763 nt_status = NT_STATUS_OK;
03764
03765 done:
03766
03767 if (got_src_share)
03768 cli_shutdown(cp_clistate.cli_share_src);
03769
03770 if (got_dst_share)
03771 cli_shutdown(cp_clistate.cli_share_dst);
03772
03773 return nt_status;
03774
03775 }
03776
03777 static int rpc_share_migrate_files(int argc, const char **argv)
03778 {
03779
03780 if (!opt_host) {
03781 printf("no server to migrate\n");
03782 return -1;
03783 }
03784
03785 return run_rpc_command(NULL, PI_SRVSVC, 0,
03786 rpc_share_migrate_files_internals,
03787 argc, argv);
03788 }
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806 static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
03807 const char *domain_name,
03808 struct cli_state *cli,
03809 struct rpc_pipe_client *pipe_hnd,
03810 TALLOC_CTX *mem_ctx,
03811 int argc,
03812 const char **argv)
03813 {
03814 WERROR result;
03815 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
03816 SRV_SHARE_INFO_CTR ctr_src;
03817 SRV_SHARE_INFO info;
03818 uint32 i;
03819 struct rpc_pipe_client *srvsvc_pipe = NULL;
03820 struct cli_state *cli_dst = NULL;
03821 uint32 level = 502;
03822
03823 result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
03824
03825 if (!W_ERROR_IS_OK(result))
03826 goto done;
03827
03828
03829 nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
03830 if (!NT_STATUS_IS_OK(nt_status))
03831 return nt_status;
03832
03833
03834 for (i = 0; i < ctr_src.num_entries; i++) {
03835
03836 fstring netname = "", remark = "", path = "";
03837
03838 nt_status = NT_STATUS_UNSUCCESSFUL;
03839
03840 rpcstr_pull_unistr2_fstring(
03841 netname, &ctr_src.share.info502[i].info_502_str.uni_netname);
03842 rpcstr_pull_unistr2_fstring(
03843 remark, &ctr_src.share.info502[i].info_502_str.uni_remark);
03844 rpcstr_pull_unistr2_fstring(
03845 path, &ctr_src.share.info502[i].info_502_str.uni_path);
03846
03847 if (!check_share_sanity(cli, netname, ctr_src.share.info502[i].info_502.type))
03848 continue;
03849
03850 printf("migrating: [%s], path: %s, comment: %s, including share-ACLs\n",
03851 netname, path, remark);
03852
03853 if (opt_verbose)
03854 display_sec_desc(ctr_src.share.info502[i].info_502_str.sd);
03855
03856
03857 ZERO_STRUCT(info);
03858
03859 info.switch_value = level;
03860 info.ptr_share_ctr = 1;
03861
03862
03863 info.share.info502 = ctr_src.share.info502[i];
03864
03865
03866 result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
03867
03868 if (!W_ERROR_IS_OK(result)) {
03869 printf("cannot set share-acl: %s\n", dos_errstr(result));
03870 goto done;
03871 }
03872
03873 }
03874
03875 nt_status = NT_STATUS_OK;
03876
03877 done:
03878 if (cli_dst) {
03879 cli_shutdown(cli_dst);
03880 }
03881
03882 return nt_status;
03883
03884 }
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895 static int rpc_share_migrate_security(int argc, const char **argv)
03896 {
03897
03898 if (!opt_host) {
03899 printf("no server to migrate\n");
03900 return -1;
03901 }
03902
03903 return run_rpc_command(NULL, PI_SRVSVC, 0,
03904 rpc_share_migrate_security_internals,
03905 argc, argv);
03906 }
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919 static int rpc_share_migrate_all(int argc, const char **argv)
03920 {
03921 int ret;
03922
03923 if (!opt_host) {
03924 printf("no server to migrate\n");
03925 return -1;
03926 }
03927
03928
03929
03930
03931 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_shares_internals, argc, argv);
03932 if (ret)
03933 return ret;
03934
03935 ret = run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_files_internals, argc, argv);
03936 if (ret)
03937 return ret;
03938
03939 return run_rpc_command(NULL, PI_SRVSVC, 0, rpc_share_migrate_security_internals, argc, argv);
03940 }
03941
03942
03943
03944
03945
03946
03947
03948
03949 static int rpc_share_migrate(int argc, const char **argv)
03950 {
03951
03952 struct functable func[] = {
03953 {"all", rpc_share_migrate_all},
03954 {"files", rpc_share_migrate_files},
03955 {"help", rpc_share_usage},
03956 {"security", rpc_share_migrate_security},
03957 {"shares", rpc_share_migrate_shares},
03958 {NULL, NULL}
03959 };
03960
03961 net_mode_share = NET_MODE_SHARE_MIGRATE;
03962
03963 return net_run_function(argc, argv, func, rpc_share_usage);
03964 }
03965
03966 struct full_alias {
03967 DOM_SID sid;
03968 uint32 num_members;
03969 DOM_SID *members;
03970 };
03971
03972 static int num_server_aliases;
03973 static struct full_alias *server_aliases;
03974
03975
03976
03977
03978 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
03979 {
03980 if (server_aliases == NULL)
03981 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
03982
03983 server_aliases[num_server_aliases] = *alias;
03984 num_server_aliases += 1;
03985 }
03986
03987
03988
03989
03990
03991
03992 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
03993 TALLOC_CTX *mem_ctx,
03994 POLICY_HND *connect_pol,
03995 const DOM_SID *domain_sid)
03996 {
03997 uint32 start_idx, max_entries, num_entries, i;
03998 struct acct_info *groups;
03999 NTSTATUS result;
04000 POLICY_HND domain_pol;
04001
04002
04003
04004 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
04005 MAXIMUM_ALLOWED_ACCESS,
04006 domain_sid, &domain_pol);
04007 if (!NT_STATUS_IS_OK(result))
04008 return result;
04009
04010 start_idx = 0;
04011 max_entries = 250;
04012
04013 do {
04014 result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
04015 &start_idx, max_entries,
04016 &groups, &num_entries);
04017
04018 for (i = 0; i < num_entries; i++) {
04019
04020 POLICY_HND alias_pol;
04021 struct full_alias alias;
04022 DOM_SID *members;
04023 int j;
04024
04025 result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
04026 MAXIMUM_ALLOWED_ACCESS,
04027 groups[i].rid,
04028 &alias_pol);
04029 if (!NT_STATUS_IS_OK(result))
04030 goto done;
04031
04032 result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
04033 &alias_pol,
04034 &alias.num_members,
04035 &members);
04036 if (!NT_STATUS_IS_OK(result))
04037 goto done;
04038
04039 result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
04040 if (!NT_STATUS_IS_OK(result))
04041 goto done;
04042
04043 alias.members = NULL;
04044
04045 if (alias.num_members > 0) {
04046 alias.members = SMB_MALLOC_ARRAY(DOM_SID, alias.num_members);
04047
04048 for (j = 0; j < alias.num_members; j++)
04049 sid_copy(&alias.members[j],
04050 &members[j]);
04051 }
04052
04053 sid_copy(&alias.sid, domain_sid);
04054 sid_append_rid(&alias.sid, groups[i].rid);
04055
04056 push_alias(mem_ctx, &alias);
04057 }
04058 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
04059
04060 result = NT_STATUS_OK;
04061
04062 done:
04063 rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
04064
04065 return result;
04066 }
04067
04068
04069
04070
04071
04072 static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
04073 const char *domain_name,
04074 struct cli_state *cli,
04075 struct rpc_pipe_client *pipe_hnd,
04076 TALLOC_CTX *mem_ctx,
04077 int argc,
04078 const char **argv)
04079 {
04080 int i;
04081 NTSTATUS result;
04082 POLICY_HND lsa_pol;
04083
04084 result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
04085 SEC_RIGHTS_MAXIMUM_ALLOWED,
04086 &lsa_pol);
04087 if (!NT_STATUS_IS_OK(result))
04088 return result;
04089
04090 for (i=0; i<num_server_aliases; i++) {
04091 char **names;
04092 char **domains;
04093 uint32 *types;
04094 int j;
04095
04096 struct full_alias *alias = &server_aliases[i];
04097
04098 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
04099 &alias->sid,
04100 &domains, &names, &types);
04101 if (!NT_STATUS_IS_OK(result))
04102 continue;
04103
04104 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
04105
04106 if (alias->num_members == 0) {
04107 DEBUG(1, ("\n"));
04108 continue;
04109 }
04110
04111 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
04112 alias->num_members,
04113 alias->members,
04114 &domains, &names, &types);
04115
04116 if (!NT_STATUS_IS_OK(result) &&
04117 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
04118 continue;
04119
04120 for (j=0; j<alias->num_members; j++)
04121 DEBUG(1, ("%s\\%s (%d); ",
04122 domains[j] ? domains[j] : "*unknown*",
04123 names[j] ? names[j] : "*unknown*",types[j]));
04124 DEBUG(1, ("\n"));
04125 }
04126
04127 rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
04128
04129 return NT_STATUS_OK;
04130 }
04131
04132
04133
04134
04135
04136
04137 static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
04138 const char *domain_name,
04139 struct cli_state *cli,
04140 struct rpc_pipe_client *pipe_hnd,
04141 TALLOC_CTX *mem_ctx,
04142 int argc,
04143 const char **argv)
04144 {
04145 NTSTATUS result;
04146 POLICY_HND connect_pol;
04147
04148 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
04149 &connect_pol);
04150
04151 if (!NT_STATUS_IS_OK(result))
04152 goto done;
04153
04154 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
04155 &global_sid_Builtin);
04156
04157 if (!NT_STATUS_IS_OK(result))
04158 goto done;
04159
04160 result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
04161 domain_sid);
04162
04163 rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
04164 done:
04165 return result;
04166 }
04167
04168 static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
04169 {
04170 token->num_sids = 4;
04171
04172 token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4);
04173
04174 token->user_sids[0] = *user_sid;
04175 sid_copy(&token->user_sids[1], &global_sid_World);
04176 sid_copy(&token->user_sids[2], &global_sid_Network);
04177 sid_copy(&token->user_sids[3], &global_sid_Authenticated_Users);
04178 }
04179
04180 static void free_user_token(NT_USER_TOKEN *token)
04181 {
04182 SAFE_FREE(token->user_sids);
04183 }
04184
04185 static BOOL is_sid_in_token(NT_USER_TOKEN *token, DOM_SID *sid)
04186 {
04187 int i;
04188
04189 for (i=0; i<token->num_sids; i++) {
04190 if (sid_compare(sid, &token->user_sids[i]) == 0)
04191 return True;
04192 }
04193 return False;
04194 }
04195
04196 static void add_sid_to_token(NT_USER_TOKEN *token, DOM_SID *sid)
04197 {
04198 if (is_sid_in_token(token, sid))
04199 return;
04200
04201 token->user_sids = SMB_REALLOC_ARRAY(token->user_sids, DOM_SID, token->num_sids+1);
04202 if (!token->user_sids) {
04203 return;
04204 }
04205
04206 sid_copy(&token->user_sids[token->num_sids], sid);
04207
04208 token->num_sids += 1;
04209 }
04210
04211 struct user_token {
04212 fstring name;
04213 NT_USER_TOKEN token;
04214 };
04215
04216 static void dump_user_token(struct user_token *token)
04217 {
04218 int i;
04219
04220 d_printf("%s\n", token->name);
04221
04222 for (i=0; i<token->token.num_sids; i++) {
04223 d_printf(" %s\n", sid_string_static(&token->token.user_sids[i]));
04224 }
04225 }
04226
04227 static BOOL is_alias_member(DOM_SID *sid, struct full_alias *alias)
04228 {
04229 int i;
04230
04231 for (i=0; i<alias->num_members; i++) {
04232 if (sid_compare(sid, &alias->members[i]) == 0)
04233 return True;
04234 }
04235
04236 return False;
04237 }
04238
04239 static void collect_sid_memberships(NT_USER_TOKEN *token, DOM_SID sid)
04240 {
04241 int i;
04242
04243 for (i=0; i<num_server_aliases; i++) {
04244 if (is_alias_member(&sid, &server_aliases[i]))
04245 add_sid_to_token(token, &server_aliases[i].sid);
04246 }
04247 }
04248
04249
04250
04251
04252
04253
04254
04255
04256 static void collect_alias_memberships(NT_USER_TOKEN *token)
04257 {
04258 int num_global_sids = token->num_sids;
04259 int i;
04260
04261 for (i=0; i<num_global_sids; i++) {
04262 collect_sid_memberships(token, token->user_sids[i]);
04263 }
04264 }
04265
04266 static BOOL get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
04267 {
04268 struct winbindd_request request;
04269 struct winbindd_response response;
04270 fstring full_name;
04271 NSS_STATUS result;
04272
04273 DOM_SID user_sid;
04274
04275 int i;
04276
04277 fstr_sprintf(full_name, "%s%c%s",
04278 domain, *lp_winbind_separator(), user);
04279
04280
04281
04282 ZERO_STRUCT(request);
04283 ZERO_STRUCT(response);
04284
04285 fstrcpy(request.data.name.dom_name, domain);
04286 fstrcpy(request.data.name.name, user);
04287
04288 result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response);
04289
04290 if (result != NSS_STATUS_SUCCESS) {
04291 DEBUG(1, ("winbind could not find %s\n", full_name));
04292 return False;
04293 }
04294
04295 if (response.data.sid.type != SID_NAME_USER) {
04296 DEBUG(1, ("%s is not a user\n", full_name));
04297 return False;
04298 }
04299
04300 string_to_sid(&user_sid, response.data.sid.sid);
04301
04302 init_user_token(token, &user_sid);
04303
04304
04305
04306 ZERO_STRUCT(response);
04307
04308 fstrcpy(request.data.username, full_name);
04309
04310 result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
04311
04312 if (result != NSS_STATUS_SUCCESS) {
04313 DEBUG(1, ("winbind could not get groups of %s\n", full_name));
04314 return False;
04315 }
04316
04317 for (i = 0; i < response.data.num_entries; i++) {
04318 gid_t gid = ((gid_t *)response.extra_data.data)[i];
04319 DOM_SID sid;
04320
04321 struct winbindd_request sidrequest;
04322 struct winbindd_response sidresponse;
04323
04324 ZERO_STRUCT(sidrequest);
04325 ZERO_STRUCT(sidresponse);
04326
04327 sidrequest.data.gid = gid;
04328
04329 result = winbindd_request_response(WINBINDD_GID_TO_SID,
04330 &sidrequest, &sidresponse);
04331
04332 if (result != NSS_STATUS_SUCCESS) {
04333 DEBUG(1, ("winbind could not find SID of gid %d\n",
04334 gid));
04335 return False;
04336 }
04337
04338 DEBUG(3, (" %s\n", sidresponse.data.sid.sid));
04339
04340 string_to_sid(&sid, sidresponse.data.sid.sid);
04341 add_sid_to_token(token, &sid);
04342 }
04343
04344 SAFE_FREE(response.extra_data.data);
04345
04346 return True;
04347 }
04348
04349
04350
04351
04352
04353 static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens)
04354 {
04355 struct winbindd_request request;
04356 struct winbindd_response response;
04357 const char *extra_data;
04358 fstring name;
04359 int i;
04360 struct user_token *result;
04361
04362 if (lp_winbind_use_default_domain() &&
04363 (opt_target_workgroup == NULL)) {
04364 d_fprintf(stderr, "winbind use default domain = yes set, "
04365 "please specify a workgroup\n");
04366 return False;
04367 }
04368
04369
04370
04371 ZERO_STRUCT(request);
04372 ZERO_STRUCT(response);
04373
04374 if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
04375 NSS_STATUS_SUCCESS)
04376 return False;
04377
04378
04379
04380 if (!response.extra_data.data)
04381 return False;
04382
04383 extra_data = (const char *)response.extra_data.data;
04384 *num_tokens = 0;
04385
04386 while(next_token(&extra_data, name, ",", sizeof(fstring))) {
04387 *num_tokens += 1;
04388 }
04389
04390 result = SMB_MALLOC_ARRAY(struct user_token, *num_tokens);
04391
04392 if (result == NULL) {
04393 DEBUG(1, ("Could not malloc sid array\n"));
04394 return False;
04395 }
04396
04397 extra_data = (const char *)response.extra_data.data;
04398 i=0;
04399
04400 while(next_token(&extra_data, name, ",", sizeof(fstring))) {
04401
04402 fstring domain, user;
04403 char *p;
04404
04405 fstrcpy(result[i].name, name);
04406
04407 p = strchr(name, *lp_winbind_separator());
04408
04409 DEBUG(3, ("%s\n", name));
04410
04411 if (p == NULL) {
04412 fstrcpy(domain, opt_target_workgroup);
04413 fstrcpy(user, name);
04414 } else {
04415 *p++ = '\0';
04416 fstrcpy(domain, name);
04417 strupper_m(domain);
04418 fstrcpy(user, p);
04419 }
04420
04421 get_user_sids(domain, user, &(result[i].token));
04422 i+=1;
04423 }
04424
04425 SAFE_FREE(response.extra_data.data);
04426
04427 *user_tokens = result;
04428
04429 return True;
04430 }
04431
04432 static BOOL get_user_tokens_from_file(FILE *f,
04433 int *num_tokens,
04434 struct user_token **tokens)
04435 {
04436 struct user_token *token = NULL;
04437
04438 while (!feof(f)) {
04439 fstring line;
04440
04441 if (fgets(line, sizeof(line)-1, f) == NULL) {
04442 return True;
04443 }
04444
04445 if (line[strlen(line)-1] == '\n')
04446 line[strlen(line)-1] = '\0';
04447
04448 if (line[0] == ' ') {
04449
04450
04451 DOM_SID sid;
04452 string_to_sid(&sid, &line[1]);
04453
04454 if (token == NULL) {
04455 DEBUG(0, ("File does not begin with username"));
04456 return False;
04457 }
04458
04459 add_sid_to_token(&token->token, &sid);
04460 continue;
04461 }
04462
04463
04464
04465 *num_tokens += 1;
04466 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
04467 if (*tokens == NULL) {
04468 DEBUG(0, ("Could not realloc tokens\n"));
04469 return False;
04470 }
04471
04472 token = &((*tokens)[*num_tokens-1]);
04473
04474 fstrcpy(token->name, line);
04475 token->token.num_sids = 0;
04476 token->token.user_sids = NULL;
04477 continue;
04478 }
04479
04480 return False;
04481 }
04482
04483
04484
04485
04486
04487
04488 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
04489 TALLOC_CTX *mem_ctx,
04490 const char *netname,
04491 int num_tokens,
04492 struct user_token *tokens)
04493 {
04494 int fnum;
04495 SEC_DESC *share_sd = NULL;
04496 SEC_DESC *root_sd = NULL;
04497 struct cli_state *cli = pipe_hnd->cli;
04498 int i;
04499 SRV_SHARE_INFO info;
04500 WERROR result;
04501 uint16 cnum;
04502
04503 result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
04504 502, &info);
04505
04506 if (!W_ERROR_IS_OK(result)) {
04507 DEBUG(1, ("Coult not query secdesc for share %s\n",
04508 netname));
04509 return;
04510 }
04511
04512 share_sd = info.share.info502.info_502_str.sd;
04513 if (share_sd == NULL) {
04514 DEBUG(1, ("Got no secdesc for share %s\n",
04515 netname));
04516 }
04517
04518 cnum = cli->cnum;
04519
04520 if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
04521 return;
04522 }
04523
04524 fnum = cli_nt_create(cli, "\\", READ_CONTROL_ACCESS);
04525
04526 if (fnum != -1) {
04527 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
04528 }
04529
04530 for (i=0; i<num_tokens; i++) {
04531 uint32 acc_granted;
04532 NTSTATUS status;
04533
04534 if (share_sd != NULL) {
04535 if (!se_access_check(share_sd, &tokens[i].token,
04536 1, &acc_granted, &status)) {
04537 DEBUG(1, ("Could not check share_sd for "
04538 "user %s\n",
04539 tokens[i].name));
04540 continue;
04541 }
04542
04543 if (!NT_STATUS_IS_OK(status))
04544 continue;
04545 }
04546
04547 if (root_sd == NULL) {
04548 d_printf(" %s\n", tokens[i].name);
04549 continue;
04550 }
04551
04552 if (!se_access_check(root_sd, &tokens[i].token,
04553 1, &acc_granted, &status)) {
04554 DEBUG(1, ("Could not check root_sd for user %s\n",
04555 tokens[i].name));
04556 continue;
04557 }
04558
04559 if (!NT_STATUS_IS_OK(status))
04560 continue;
04561
04562 d_printf(" %s\n", tokens[i].name);
04563 }
04564
04565 if (fnum != -1)
04566 cli_close(cli, fnum);
04567 cli_tdis(cli);
04568 cli->cnum = cnum;
04569
04570 return;
04571 }
04572
04573 struct share_list {
04574 int num_shares;
04575 char **shares;
04576 };
04577
04578 static void collect_share(const char *name, uint32 m,
04579 const char *comment, void *state)
04580 {
04581 struct share_list *share_list = (struct share_list *)state;
04582
04583 if (m != STYPE_DISKTREE)
04584 return;
04585
04586 share_list->num_shares += 1;
04587 share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
04588 if (!share_list->shares) {
04589 share_list->num_shares = 0;
04590 return;
04591 }
04592 share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
04593 }
04594
04595 static void rpc_share_userlist_usage(void)
04596 {
04597 return;
04598 }
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616 static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
04617 const char *domain_name,
04618 struct cli_state *cli,
04619 struct rpc_pipe_client *pipe_hnd,
04620 TALLOC_CTX *mem_ctx,
04621 int argc,
04622 const char **argv)
04623 {
04624 int ret;
04625 BOOL r;
04626 ENUM_HND hnd;
04627 uint32 i;
04628 FILE *f;
04629
04630 struct user_token *tokens = NULL;
04631 int num_tokens = 0;
04632
04633 struct share_list share_list;
04634
04635 if (argc > 1) {
04636 rpc_share_userlist_usage();
04637 return NT_STATUS_UNSUCCESSFUL;
04638 }
04639
04640 if (argc == 0) {
04641 f = stdin;
04642 } else {
04643 f = fopen(argv[0], "r");
04644 }
04645
04646 if (f == NULL) {
04647 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
04648 return NT_STATUS_UNSUCCESSFUL;
04649 }
04650
04651 r = get_user_tokens_from_file(f, &num_tokens, &tokens);
04652
04653 if (f != stdin)
04654 fclose(f);
04655
04656 if (!r) {
04657 DEBUG(0, ("Could not read users from file\n"));
04658 return NT_STATUS_UNSUCCESSFUL;
04659 }
04660
04661 for (i=0; i<num_tokens; i++)
04662 collect_alias_memberships(&tokens[i].token);
04663
04664 init_enum_hnd(&hnd, 0);
04665
04666 share_list.num_shares = 0;
04667 share_list.shares = NULL;
04668
04669 ret = cli_RNetShareEnum(cli, collect_share, &share_list);
04670
04671 if (ret == -1) {
04672 DEBUG(0, ("Error returning browse list: %s\n",
04673 cli_errstr(cli)));
04674 goto done;
04675 }
04676
04677 for (i = 0; i < share_list.num_shares; i++) {
04678 char *netname = share_list.shares[i];
04679
04680 if (netname[strlen(netname)-1] == '$')
04681 continue;
04682
04683 d_printf("%s\n", netname);
04684
04685 show_userlist(pipe_hnd, mem_ctx, netname,
04686 num_tokens, tokens);
04687 }
04688 done:
04689 for (i=0; i<num_tokens; i++) {
04690 free_user_token(&tokens[i].token);
04691 }
04692 SAFE_FREE(tokens);
04693 SAFE_FREE(share_list.shares);
04694
04695 return NT_STATUS_OK;
04696 }
04697
04698 static int rpc_share_allowedusers(int argc, const char **argv)
04699 {
04700 int result;
04701
04702 result = run_rpc_command(NULL, PI_SAMR, 0,
04703 rpc_aliaslist_internals,
04704 argc, argv);
04705 if (result != 0)
04706 return result;
04707
04708 result = run_rpc_command(NULL, PI_LSARPC, 0,
04709 rpc_aliaslist_dump,
04710 argc, argv);
04711 if (result != 0)
04712 return result;
04713
04714 return run_rpc_command(NULL, PI_SRVSVC, 0,
04715 rpc_share_allowedusers_internals,
04716 argc, argv);
04717 }
04718
04719 int net_usersidlist(int argc, const char **argv)
04720 {
04721 int num_tokens = 0;
04722 struct user_token *tokens = NULL;
04723 int i;
04724
04725 if (argc != 0) {
04726 net_usersidlist_usage(argc, argv);
04727 return 0;
04728 }
04729
04730 if (!get_user_tokens(&num_tokens, &tokens)) {
04731 DEBUG(0, ("Could not get the user/sid list\n"));
04732 return 0;
04733 }
04734
04735 for (i=0; i<num_tokens; i++) {
04736 dump_user_token(&tokens[i]);
04737 free_user_token(&tokens[i].token);
04738 }
04739
04740 SAFE_FREE(tokens);
04741 return 1;
04742 }
04743
04744 int net_usersidlist_usage(int argc, const char **argv)
04745 {
04746 d_printf("net usersidlist\n"
04747 "\tprints out a list of all users the running winbind knows\n"
04748 "\tabout, together with all their SIDs. This is used as\n"
04749 "\tinput to the 'net rpc share allowedusers' command.\n\n");
04750
04751 net_common_flags_usage(argc, argv);
04752 return -1;
04753 }
04754
04755
04756
04757
04758
04759
04760
04761
04762 int net_rpc_share(int argc, const char **argv)
04763 {
04764 struct functable func[] = {
04765 {"add", rpc_share_add},
04766 {"delete", rpc_share_delete},
04767 {"allowedusers", rpc_share_allowedusers},
04768 {"migrate", rpc_share_migrate},
04769 {"list", rpc_share_list},
04770 {NULL, NULL}
04771 };
04772
04773 if (argc == 0)
04774 return run_rpc_command(NULL, PI_SRVSVC, 0,
04775 rpc_share_list_internals,
04776 argc, argv);
04777
04778 return net_run_function(argc, argv, func, rpc_share_usage);
04779 }
04780
04781 static NTSTATUS rpc_sh_share_list(TALLOC_CTX *mem_ctx,
04782 struct rpc_sh_ctx *ctx,
04783 struct rpc_pipe_client *pipe_hnd,
04784 int argc, const char **argv)
04785 {
04786 return rpc_share_list_internals(ctx->domain_sid, ctx->domain_name,
04787 ctx->cli, pipe_hnd, mem_ctx,
04788 argc, argv);
04789 }
04790
04791 static NTSTATUS rpc_sh_share_add(TALLOC_CTX *mem_ctx,
04792 struct rpc_sh_ctx *ctx,
04793 struct rpc_pipe_client *pipe_hnd,
04794 int argc, const char **argv)
04795 {
04796 WERROR result;
04797
04798 if ((argc < 2) || (argc > 3)) {
04799 d_fprintf(stderr, "usage: %s <share> <path> [comment]\n",
04800 ctx->whoami);
04801 return NT_STATUS_INVALID_PARAMETER;
04802 }
04803
04804 result = rpccli_srvsvc_net_share_add(
04805 pipe_hnd, mem_ctx, argv[0], STYPE_DISKTREE,
04806 (argc == 3) ? argv[2] : "",
04807 0, 0, 0, argv[1], NULL, 2, NULL);
04808
04809 return werror_to_ntstatus(result);
04810 }
04811
04812 static NTSTATUS rpc_sh_share_delete(TALLOC_CTX *mem_ctx,
04813 struct rpc_sh_ctx *ctx,
04814 struct rpc_pipe_client *pipe_hnd,
04815 int argc, const char **argv)
04816 {
04817 WERROR result;
04818
04819 if (argc != 1) {
04820 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
04821 return NT_STATUS_INVALID_PARAMETER;
04822 }
04823
04824 result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
04825 return werror_to_ntstatus(result);
04826 }
04827
04828 static NTSTATUS rpc_sh_share_info(TALLOC_CTX *mem_ctx,
04829 struct rpc_sh_ctx *ctx,
04830 struct rpc_pipe_client *pipe_hnd,
04831 int argc, const char **argv)
04832 {
04833 SRV_SHARE_INFO info;
04834 SRV_SHARE_INFO_2 *info2 = &info.share.info2;
04835 WERROR result;
04836
04837 if (argc != 1) {
04838 d_fprintf(stderr, "usage: %s <share>\n", ctx->whoami);
04839 return NT_STATUS_INVALID_PARAMETER;
04840 }
04841
04842 result = rpccli_srvsvc_net_share_get_info(
04843 pipe_hnd, mem_ctx, argv[0], 2, &info);
04844 if (!W_ERROR_IS_OK(result)) {
04845 goto done;
04846 }
04847
04848 d_printf("Name: %s\n",
04849 rpcstr_pull_unistr2_talloc(mem_ctx,
04850 &info2->info_2_str.uni_netname));
04851 d_printf("Comment: %s\n",
04852 rpcstr_pull_unistr2_talloc(mem_ctx,
04853 &info2->info_2_str.uni_remark));
04854
04855 d_printf("Path: %s\n",
04856 rpcstr_pull_unistr2_talloc(mem_ctx,
04857 &info2->info_2_str.uni_path));
04858 d_printf("Password: %s\n",
04859 rpcstr_pull_unistr2_talloc(mem_ctx,
04860 &info2->info_2_str.uni_passwd));
04861
04862 done:
04863 return werror_to_ntstatus(result);
04864 }
04865
04866 struct rpc_sh_cmd *net_rpc_share_cmds(TALLOC_CTX *mem_ctx,
04867 struct rpc_sh_ctx *ctx)
04868 {
04869 static struct rpc_sh_cmd cmds[] = {
04870
04871 { "list", NULL, PI_SRVSVC, rpc_sh_share_list,
04872 "List available shares" },
04873
04874 { "add", NULL, PI_SRVSVC, rpc_sh_share_add,
04875 "Add a share" },
04876
04877 { "delete", NULL, PI_SRVSVC, rpc_sh_share_delete,
04878 "Delete a share" },
04879
04880 { "info", NULL, PI_SRVSVC, rpc_sh_share_info,
04881 "Get information about a share" },
04882
04883 { NULL, NULL, 0, NULL, NULL }
04884 };
04885
04886 return cmds;
04887 }
04888
04889
04890
04891 static int rpc_file_usage(int argc, const char **argv)
04892 {
04893 return net_help_file(argc, argv);
04894 }
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911 static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
04912 const char *domain_name,
04913 struct cli_state *cli,
04914 struct rpc_pipe_client *pipe_hnd,
04915 TALLOC_CTX *mem_ctx,
04916 int argc,
04917 const char **argv)
04918 {
04919 WERROR result;
04920 result = rpccli_srvsvc_net_file_close(pipe_hnd, mem_ctx, atoi(argv[0]));
04921 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
04922 }
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933 static int rpc_file_close(int argc, const char **argv)
04934 {
04935 if (argc < 1) {
04936 DEBUG(1, ("No fileid given on close\n"));
04937 return(rpc_file_usage(argc, argv));
04938 }
04939
04940 return run_rpc_command(NULL, PI_SRVSVC, 0,
04941 rpc_file_close_internals,
04942 argc, argv);
04943 }
04944
04945
04946
04947
04948
04949
04950
04951
04952 static void display_file_info_3( FILE_INFO_3 *info3 )
04953 {
04954 fstring user = "", path = "";
04955
04956 rpcstr_pull_unistr2_fstring(user, info3->user);
04957 rpcstr_pull_unistr2_fstring(path, info3->path);
04958
04959 d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
04960 info3->id, user, info3->perms, info3->num_locks, path);
04961 }
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979 static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
04980 const char *domain_name,
04981 struct cli_state *cli,
04982 struct rpc_pipe_client *pipe_hnd,
04983 TALLOC_CTX *mem_ctx,
04984 int argc,
04985 const char **argv)
04986 {
04987 SRV_FILE_INFO_CTR ctr;
04988 WERROR result;
04989 ENUM_HND hnd;
04990 uint32 preferred_len = 0xffffffff, i;
04991 const char *username=NULL;
04992
04993 init_enum_hnd(&hnd, 0);
04994
04995
04996 if (argc > 0)
04997 username = smb_xstrdup(argv[0]);
04998
04999 result = rpccli_srvsvc_net_file_enum(pipe_hnd,
05000 mem_ctx, 3, username, &ctr, preferred_len, &hnd);
05001
05002 if (!W_ERROR_IS_OK(result))
05003 goto done;
05004
05005
05006
05007 d_printf(
05008 "\nEnumerating open files on remote server:\n\n"\
05009 "\nFileId Opened by Perms Locks Path"\
05010 "\n------ --------- ----- ----- ---- \n");
05011 for (i = 0; i < ctr.num_entries; i++)
05012 display_file_info_3(&ctr.file.info3[i]);
05013 done:
05014 return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
05015 }
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027 static int rpc_file_user(int argc, const char **argv)
05028 {
05029 if (argc < 1) {
05030 DEBUG(1, ("No username given\n"));
05031 return(rpc_file_usage(argc, argv));
05032 }
05033
05034 return run_rpc_command(NULL, PI_SRVSVC, 0,
05035 rpc_file_list_internals,
05036 argc, argv);
05037 }
05038
05039
05040
05041
05042
05043
05044
05045
05046 int net_rpc_file(int argc, const char **argv)
05047 {
05048 struct functable func[] = {
05049 {"close", rpc_file_close},
05050 {"user", rpc_file_user},
05051 #if 0
05052 {"info", rpc_file_info},
05053 #endif
05054 {NULL, NULL}
05055 };
05056
05057 if (argc == 0)
05058 return run_rpc_command(NULL, PI_SRVSVC, 0,
05059 rpc_file_list_internals,
05060 argc, argv);
05061
05062 return net_run_function(argc, argv, func, rpc_file_usage);
05063 }
05064
05065
05066
05067
05068
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
05082 const char *domain_name,
05083 struct cli_state *cli,
05084 struct rpc_pipe_client *pipe_hnd,
05085 TALLOC_CTX *mem_ctx,
05086 int argc,
05087 const char **argv)
05088 {
05089 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
05090
05091 result = rpccli_shutdown_abort(pipe_hnd, mem_ctx);
05092
05093 if (NT_STATUS_IS_OK(result)) {
05094 d_printf("\nShutdown successfully aborted\n");
05095 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
05096 } else
05097 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
05098
05099 return result;
05100 }
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
05119 const char *domain_name,
05120 struct cli_state *cli,
05121 struct rpc_pipe_client *pipe_hnd,
05122 TALLOC_CTX *mem_ctx,
05123 int argc,
05124 const char **argv)
05125 {
05126 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
05127
05128 result = werror_to_ntstatus(rpccli_reg_abort_shutdown(pipe_hnd, mem_ctx));
05129
05130 if (NT_STATUS_IS_OK(result)) {
05131 d_printf("\nShutdown successfully aborted\n");
05132 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
05133 } else
05134 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
05135
05136 return result;
05137 }
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149 static int rpc_shutdown_abort(int argc, const char **argv)
05150 {
05151 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
05152 rpc_shutdown_abort_internals,
05153 argc, argv);
05154
05155 if (rc == 0)
05156 return rc;
05157
05158 DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
05159
05160 return run_rpc_command(NULL, PI_WINREG, 0,
05161 rpc_reg_shutdown_abort_internals,
05162 argc, argv);
05163 }
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181 static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
05182 const char *domain_name,
05183 struct cli_state *cli,
05184 struct rpc_pipe_client *pipe_hnd,
05185 TALLOC_CTX *mem_ctx,
05186 int argc,
05187 const char **argv)
05188 {
05189 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
05190 const char *msg = "This machine will be shutdown shortly";
05191 uint32 timeout = 20;
05192
05193 if (opt_comment) {
05194 msg = opt_comment;
05195 }
05196 if (opt_timeout) {
05197 timeout = opt_timeout;
05198 }
05199
05200
05201 result = rpccli_shutdown_init(pipe_hnd, mem_ctx, msg, timeout, opt_reboot,
05202 opt_force);
05203
05204 if (NT_STATUS_IS_OK(result)) {
05205 d_printf("\nShutdown of remote machine succeeded\n");
05206 DEBUG(5,("Shutdown of remote machine succeeded\n"));
05207 } else {
05208 DEBUG(1,("Shutdown of remote machine failed!\n"));
05209 }
05210 return result;
05211 }
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227
05228
05229 static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
05230 const char *domain_name,
05231 struct cli_state *cli,
05232 struct rpc_pipe_client *pipe_hnd,
05233 TALLOC_CTX *mem_ctx,
05234 int argc,
05235 const char **argv)
05236 {
05237 WERROR result;
05238 const char *msg = "This machine will be shutdown shortly";
05239 uint32 timeout = 20;
05240 #if 0
05241 poptContext pc;
05242 int rc;
05243
05244 struct poptOption long_options[] = {
05245 {"message", 'm', POPT_ARG_STRING, &msg},
05246 {"timeout", 't', POPT_ARG_INT, &timeout},
05247 {"reboot", 'r', POPT_ARG_NONE, &reboot},
05248 {"force", 'f', POPT_ARG_NONE, &force},
05249 { 0, 0, 0, 0}
05250 };
05251
05252 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
05253 POPT_CONTEXT_KEEP_FIRST);
05254
05255 rc = poptGetNextOpt(pc);
05256
05257 if (rc < -1) {
05258
05259 DEBUG(0, ("%s: %s\n",
05260 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
05261 poptStrerror(rc)));
05262 return NT_STATUS_INVALID_PARAMETER;
05263 }
05264 #endif
05265 if (opt_comment) {
05266 msg = opt_comment;
05267 }
05268 if (opt_timeout) {
05269 timeout = opt_timeout;
05270 }
05271
05272
05273 result = rpccli_reg_shutdown(pipe_hnd, mem_ctx, msg, timeout, opt_reboot, opt_force);
05274
05275 if (W_ERROR_IS_OK(result)) {
05276 d_printf("\nShutdown of remote machine succeeded\n");
05277 } else {
05278 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
05279 if (W_ERROR_EQUAL(result,WERR_MACHINE_LOCKED))
05280 d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
05281 else
05282 d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(result));
05283 }
05284
05285 return werror_to_ntstatus(result);
05286 }
05287
05288
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298 static int rpc_shutdown(int argc, const char **argv)
05299 {
05300 int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
05301 rpc_init_shutdown_internals,
05302 argc, argv);
05303
05304 if (rc) {
05305 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
05306 rc = run_rpc_command(NULL, PI_WINREG, 0,
05307 rpc_reg_shutdown_internals, argc, argv);
05308 }
05309
05310 return rc;
05311 }
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327
05328
05329
05330
05331
05332
05333 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
05334 const char *domain_name,
05335 struct cli_state *cli,
05336 struct rpc_pipe_client *pipe_hnd,
05337 TALLOC_CTX *mem_ctx,
05338 int argc,
05339 const char **argv)
05340 {
05341 POLICY_HND connect_pol, domain_pol, user_pol;
05342 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
05343 char *acct_name;
05344 uint32 acb_info;
05345 uint32 user_rid;
05346 uint32 acct_flags=0;
05347
05348 if (argc != 2) {
05349 d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
05350 return NT_STATUS_INVALID_PARAMETER;
05351 }
05352
05353
05354
05355
05356
05357 if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
05358 return NT_STATUS_NO_MEMORY;
05359 }
05360
05361 strupper_m(acct_name);
05362
05363
05364 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
05365 &connect_pol);
05366 if (!NT_STATUS_IS_OK(result)) {
05367 goto done;
05368 }
05369
05370
05371 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
05372 MAXIMUM_ALLOWED_ACCESS,
05373 domain_sid, &domain_pol);
05374 if (!NT_STATUS_IS_OK(result)) {
05375 goto done;
05376 }
05377
05378
05379 acb_info = ACB_NORMAL;
05380 acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
05381 SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
05382 SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
05383 SAMR_USER_SETATTR;
05384
05385 result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
05386 acct_name, acb_info, acct_flags,
05387 &user_pol, &user_rid);
05388 if (!NT_STATUS_IS_OK(result)) {
05389 goto done;
05390 }
05391
05392 {
05393 SAM_USERINFO_CTR ctr;
05394 SAM_USER_INFO_23 p23;
05395 NTTIME notime;
05396 char nostr[] = "";
05397 LOGON_HRS hrs;
05398 uchar pwbuf[516];
05399
05400 encode_pw_buffer(pwbuf, argv[1], STR_UNICODE);
05401
05402 ZERO_STRUCT(ctr);
05403 ZERO_STRUCT(p23);
05404 ZERO_STRUCT(notime);
05405 hrs.max_len = 1260;
05406 hrs.offset = 0;
05407 hrs.len = 21;
05408 memset(hrs.hours, 0xFF, sizeof(hrs.hours));
05409 acb_info = ACB_DOMTRUST;
05410
05411 init_sam_user_info23A(&p23, ¬ime, ¬ime, ¬ime,
05412 ¬ime, ¬ime, ¬ime,
05413 nostr, nostr, nostr, nostr, nostr,
05414 nostr, nostr, nostr, nostr, nostr,
05415 0, 0, acb_info, ACCT_FLAGS, 168, &hrs,
05416 0, 0, (char *)pwbuf);
05417 ctr.switch_value = 23;
05418 ctr.info.id23 = &p23;
05419 p23.passmustchange = 0;
05420
05421 result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
05422 &cli->user_session_key, &ctr);
05423
05424 if (!NT_STATUS_IS_OK(result)) {
05425 DEBUG(0,("Could not set trust account password: %s\n",
05426 nt_errstr(result)));
05427 goto done;
05428 }
05429 }
05430
05431 done:
05432 SAFE_FREE(acct_name);
05433 return result;
05434 }
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445 static int rpc_trustdom_add(int argc, const char **argv)
05446 {
05447 if (argc > 0) {
05448 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
05449 argc, argv);
05450 } else {
05451 d_printf("Usage: net rpc trustdom add <domain> <trust password>\n");
05452 return -1;
05453 }
05454 }
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472 static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
05473 const char *domain_name,
05474 struct cli_state *cli,
05475 struct rpc_pipe_client *pipe_hnd,
05476 TALLOC_CTX *mem_ctx,
05477 int argc,
05478 const char **argv)
05479 {
05480 POLICY_HND connect_pol, domain_pol, user_pol;
05481 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
05482 char *acct_name;
05483 const char **names;
05484 DOM_SID trust_acct_sid;
05485 uint32 *user_rids, num_rids, *name_types;
05486 uint32 flags = 0x000003e8;
05487
05488 if (argc != 1) {
05489 d_printf("Usage: net rpc trustdom del <domain_name>\n");
05490 return NT_STATUS_INVALID_PARAMETER;
05491 }
05492
05493
05494
05495
05496 acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
05497
05498 if (acct_name == NULL)
05499 return NT_STATUS_NO_MEMORY;
05500
05501 strupper_m(acct_name);
05502
05503 if ((names = TALLOC_ARRAY(mem_ctx, const char *, 1)) == NULL) {
05504 return NT_STATUS_NO_MEMORY;
05505 }
05506 names[0] = acct_name;
05507
05508
05509
05510 result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
05511 &connect_pol);
05512 if (!NT_STATUS_IS_OK(result)) {
05513 goto done;
05514 }
05515
05516
05517 result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
05518 MAXIMUM_ALLOWED_ACCESS,
05519 domain_sid, &domain_pol);
05520 if (!NT_STATUS_IS_OK(result)) {
05521 goto done;
05522 }
05523
05524 result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
05525 names, &num_rids,
05526 &user_rids, &name_types);
05527
05528 if (!NT_STATUS_IS_OK(result)) {
05529 goto done;
05530 }
05531
05532 result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
05533 MAXIMUM_ALLOWED_ACCESS,
05534 user_rids[0], &user_pol);
05535
05536 if (!NT_STATUS_IS_OK(result)) {
05537 goto done;
05538 }
05539
05540
05541 sid_copy(&trust_acct_sid, domain_sid);
05542 if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
05543 goto done;
05544 }
05545
05546
05547
05548 result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
05549 &trust_acct_sid);
05550
05551 if (!NT_STATUS_IS_OK(result)) {
05552 goto done;
05553 }
05554
05555
05556
05557 result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
05558
05559 if (!NT_STATUS_IS_OK(result)) {
05560 goto done;
05561 }
05562
05563 if (!NT_STATUS_IS_OK(result)) {
05564 DEBUG(0,("Could not set trust account password: %s\n",
05565 nt_errstr(result)));
05566 goto done;
05567 }
05568
05569 done:
05570 return result;
05571 }
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582 static int rpc_trustdom_del(int argc, const char **argv)
05583 {
05584 if (argc > 0) {
05585 return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
05586 argc, argv);
05587 } else {
05588 d_printf("Usage: net rpc trustdom del <domain>\n");
05589 return -1;
05590 }
05591 }
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604 static int rpc_trustdom_establish(int argc, const char **argv)
05605 {
05606 struct cli_state *cli = NULL;
05607 struct in_addr server_ip;
05608 struct rpc_pipe_client *pipe_hnd = NULL;
05609 POLICY_HND connect_hnd;
05610 TALLOC_CTX *mem_ctx;
05611 NTSTATUS nt_status;
05612 DOM_SID *domain_sid;
05613
05614 char* domain_name;
05615 char* domain_name_pol;
05616 char* acct_name;
05617 fstring pdc_name;
05618
05619
05620
05621
05622
05623 if (argc != 1) {
05624 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
05625 return -1;
05626 }
05627
05628 domain_name = smb_xstrdup(argv[0]);
05629 strupper_m(domain_name);
05630
05631
05632 asprintf(&acct_name, "%s$", lp_workgroup());
05633 strupper_m(acct_name);
05634
05635
05636
05637
05638
05639 if (opt_workgroup) {
05640 opt_workgroup = smb_xstrdup(domain_name);
05641 };
05642
05643 opt_user_name = acct_name;
05644
05645
05646 if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
05647 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
05648 return -1;
05649 }
05650
05651
05652 nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
05653 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
05654
05655
05656 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
05657 nt_errstr(nt_status)));
05658 return -1;
05659 }
05660
05661
05662
05663 saf_store( domain_name, pdc_name );
05664
05665
05666
05667
05668
05669 nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
05670
05671 if (NT_STATUS_IS_ERR(nt_status)) {
05672 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
05673 domain_name, nt_errstr(nt_status)));
05674 return -1;
05675 }
05676
05677
05678
05679
05680
05681 if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
05682 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
05683 for domain %s\n", domain_name));
05684 cli_shutdown(cli);
05685 return -1;
05686 }
05687
05688 if (!(mem_ctx = talloc_init("establishing trust relationship to "
05689 "domain %s", domain_name))) {
05690 DEBUG(0, ("talloc_init() failed\n"));
05691 cli_shutdown(cli);
05692 return -1;
05693 }
05694
05695
05696
05697
05698
05699 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
05700 if (!pipe_hnd) {
05701 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
05702 cli_shutdown(cli);
05703 talloc_destroy(mem_ctx);
05704 return -1;
05705 }
05706
05707 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
05708 &connect_hnd);
05709 if (NT_STATUS_IS_ERR(nt_status)) {
05710 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
05711 nt_errstr(nt_status)));
05712 cli_shutdown(cli);
05713 talloc_destroy(mem_ctx);
05714 return -1;
05715 }
05716
05717
05718
05719 nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
05720 5 ,
05721 &domain_name_pol, &domain_sid);
05722 if (NT_STATUS_IS_ERR(nt_status)) {
05723 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
05724 nt_errstr(nt_status)));
05725 cli_shutdown(cli);
05726 talloc_destroy(mem_ctx);
05727 return -1;
05728 }
05729
05730
05731
05732
05733
05734
05735
05736
05737 if (!secrets_store_trusted_domain_password(domain_name,
05738 opt_password,
05739 domain_sid)) {
05740 DEBUG(0, ("Storing password for trusted domain failed.\n"));
05741 cli_shutdown(cli);
05742 talloc_destroy(mem_ctx);
05743 return -1;
05744 }
05745
05746
05747
05748
05749
05750 nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
05751 if (NT_STATUS_IS_ERR(nt_status)) {
05752 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
05753 nt_errstr(nt_status)));
05754 cli_shutdown(cli);
05755 talloc_destroy(mem_ctx);
05756 return -1;
05757 }
05758
05759 cli_shutdown(cli);
05760
05761 talloc_destroy(mem_ctx);
05762
05763 d_printf("Trust to domain %s established\n", domain_name);
05764 return 0;
05765 }
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776 static int rpc_trustdom_revoke(int argc, const char **argv)
05777 {
05778 char* domain_name;
05779
05780 if (argc < 1) return -1;
05781
05782
05783 domain_name = smb_xstrdup(argv[0]);
05784 strupper_m(domain_name);
05785
05786
05787 if (!trusted_domain_password_delete(domain_name)) {
05788 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
05789 domain_name));
05790 return -1;
05791 };
05792
05793 return 0;
05794 }
05795
05796
05797
05798
05799
05800
05801
05802
05803
05804
05805 static int rpc_trustdom_usage(int argc, const char **argv)
05806 {
05807 d_printf(" net rpc trustdom add \t\t add trusting domain's account\n");
05808 d_printf(" net rpc trustdom del \t\t delete trusting domain's account\n");
05809 d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
05810 d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
05811 d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
05812 d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
05813 return -1;
05814 }
05815
05816
05817 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
05818 const char *domain_name,
05819 struct cli_state *cli,
05820 struct rpc_pipe_client *pipe_hnd,
05821 TALLOC_CTX *mem_ctx,
05822 int argc,
05823 const char **argv)
05824 {
05825 fstring str_sid;
05826 sid_to_string(str_sid, domain_sid);
05827 d_printf("%s\n", str_sid);
05828 return NT_STATUS_OK;
05829 }
05830
05831 static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
05832 {
05833 fstring ascii_sid, padding;
05834 int pad_len, col_len = 20;
05835
05836
05837 sid_to_string(ascii_sid, dom_sid);
05838
05839
05840 pad_len = col_len - strlen(trusted_dom_name);
05841 padding[pad_len] = 0;
05842 do padding[--pad_len] = ' '; while (pad_len);
05843
05844 d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
05845 }
05846
05847 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
05848 TALLOC_CTX *mem_ctx,
05849 POLICY_HND *pol,
05850 DOM_SID dom_sid,
05851 const char *trusted_dom_name)
05852 {
05853 NTSTATUS nt_status;
05854 LSA_TRUSTED_DOMAIN_INFO *info;
05855 char *cleartextpwd = NULL;
05856 DATA_BLOB data;
05857
05858 nt_status = rpccli_lsa_query_trusted_domain_info_by_sid(pipe_hnd, mem_ctx, pol, 4, &dom_sid, &info);
05859
05860 if (NT_STATUS_IS_ERR(nt_status)) {
05861 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
05862 nt_errstr(nt_status)));
05863 goto done;
05864 }
05865
05866 data = data_blob(NULL, info->password.password.length);
05867
05868 memcpy(data.data, info->password.password.data, info->password.password.length);
05869 data.length = info->password.password.length;
05870
05871 cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password, &data);
05872
05873 if (cleartextpwd == NULL) {
05874 DEBUG(0,("retrieved NULL password\n"));
05875 nt_status = NT_STATUS_UNSUCCESSFUL;
05876 goto done;
05877 }
05878
05879 if (!secrets_store_trusted_domain_password(trusted_dom_name,
05880 cleartextpwd,
05881 &dom_sid)) {
05882 DEBUG(0, ("Storing password for trusted domain failed.\n"));
05883 nt_status = NT_STATUS_UNSUCCESSFUL;
05884 goto done;
05885 }
05886
05887 #ifdef DEBUG_PASSWORD
05888 DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], password: [%s]\n",
05889 trusted_dom_name, sid_string_static(&dom_sid), cleartextpwd));
05890 #endif
05891
05892 done:
05893 SAFE_FREE(cleartextpwd);
05894 data_blob_free(&data);
05895
05896 return nt_status;
05897 }
05898
05899 static int rpc_trustdom_vampire(int argc, const char **argv)
05900 {
05901
05902 TALLOC_CTX* mem_ctx;
05903 struct cli_state *cli = NULL;
05904 struct rpc_pipe_client *pipe_hnd = NULL;
05905 NTSTATUS nt_status;
05906 const char *domain_name = NULL;
05907 DOM_SID *queried_dom_sid;
05908 POLICY_HND connect_hnd;
05909
05910
05911 unsigned int num_domains, enum_ctx = 0;
05912 int i;
05913 DOM_SID *domain_sids;
05914 char **trusted_dom_names;
05915 fstring pdc_name;
05916 char *dummy;
05917
05918
05919
05920
05921
05922 mem_ctx = talloc_init("trust relationships vampire");
05923
05924
05925
05926
05927
05928
05929 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
05930 domain_name = opt_workgroup;
05931 opt_target_workgroup = opt_workgroup;
05932 } else {
05933 fstrcpy(pdc_name, global_myname());
05934 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
05935 opt_target_workgroup = domain_name;
05936 };
05937
05938
05939 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
05940 DEBUG(0, ("Couldn't connect to domain controller\n"));
05941 talloc_destroy(mem_ctx);
05942 return -1;
05943 };
05944
05945 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
05946 if (!pipe_hnd) {
05947 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
05948 nt_errstr(nt_status) ));
05949 cli_shutdown(cli);
05950 talloc_destroy(mem_ctx);
05951 return -1;
05952 };
05953
05954 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
05955 &connect_hnd);
05956 if (NT_STATUS_IS_ERR(nt_status)) {
05957 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
05958 nt_errstr(nt_status)));
05959 cli_shutdown(cli);
05960 talloc_destroy(mem_ctx);
05961 return -1;
05962 };
05963
05964
05965 nt_status = rpccli_lsa_query_info_policy(
05966 pipe_hnd, mem_ctx, &connect_hnd, 5 ,
05967 &dummy, &queried_dom_sid);
05968
05969 if (NT_STATUS_IS_ERR(nt_status)) {
05970 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
05971 nt_errstr(nt_status)));
05972 cli_shutdown(cli);
05973 talloc_destroy(mem_ctx);
05974 return -1;
05975 }
05976
05977
05978
05979
05980
05981
05982 d_printf("Vampire trusted domains:\n\n");
05983
05984 do {
05985 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
05986 &num_domains,
05987 &trusted_dom_names, &domain_sids);
05988
05989 if (NT_STATUS_IS_ERR(nt_status)) {
05990 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
05991 nt_errstr(nt_status)));
05992 cli_shutdown(cli);
05993 talloc_destroy(mem_ctx);
05994 return -1;
05995 };
05996
05997 for (i = 0; i < num_domains; i++) {
05998
05999 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
06000
06001 nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
06002 domain_sids[i], trusted_dom_names[i]);
06003 if (!NT_STATUS_IS_OK(nt_status)) {
06004 cli_shutdown(cli);
06005 talloc_destroy(mem_ctx);
06006 return -1;
06007 }
06008 };
06009
06010
06011
06012
06013
06014 if (!num_domains) d_printf("none\n");
06015
06016 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
06017
06018
06019 nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
06020 if (NT_STATUS_IS_ERR(nt_status)) {
06021 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
06022 nt_errstr(nt_status)));
06023 cli_shutdown(cli);
06024 talloc_destroy(mem_ctx);
06025 return -1;
06026 };
06027
06028
06029 cli_shutdown(cli);
06030
06031 talloc_destroy(mem_ctx);
06032 return 0;
06033 }
06034
06035 static int rpc_trustdom_list(int argc, const char **argv)
06036 {
06037
06038 TALLOC_CTX* mem_ctx;
06039 struct cli_state *cli = NULL, *remote_cli = NULL;
06040 struct rpc_pipe_client *pipe_hnd = NULL;
06041 NTSTATUS nt_status;
06042 const char *domain_name = NULL;
06043 DOM_SID *queried_dom_sid;
06044 fstring padding;
06045 int ascii_dom_name_len;
06046 POLICY_HND connect_hnd;
06047
06048
06049 unsigned int num_domains, enum_ctx = 0;
06050 int i, pad_len, col_len = 20;
06051 DOM_SID *domain_sids;
06052 char **trusted_dom_names;
06053 fstring pdc_name;
06054 char *dummy;
06055
06056
06057 POLICY_HND domain_hnd;
06058 char **trusting_dom_names;
06059 uint32 *trusting_dom_rids;
06060
06061
06062
06063
06064
06065 mem_ctx = talloc_init("trust relationships listing");
06066
06067
06068
06069
06070
06071
06072 if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
06073 domain_name = opt_workgroup;
06074 opt_target_workgroup = opt_workgroup;
06075 } else {
06076 fstrcpy(pdc_name, global_myname());
06077 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
06078 opt_target_workgroup = domain_name;
06079 };
06080
06081
06082 if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
06083 DEBUG(0, ("Couldn't connect to domain controller\n"));
06084 talloc_destroy(mem_ctx);
06085 return -1;
06086 };
06087
06088 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
06089 if (!pipe_hnd) {
06090 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
06091 nt_errstr(nt_status) ));
06092 cli_shutdown(cli);
06093 talloc_destroy(mem_ctx);
06094 return -1;
06095 };
06096
06097 nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
06098 &connect_hnd);
06099 if (NT_STATUS_IS_ERR(nt_status)) {
06100 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
06101 nt_errstr(nt_status)));
06102 cli_shutdown(cli);
06103 talloc_destroy(mem_ctx);
06104 return -1;
06105 };
06106
06107
06108 nt_status = rpccli_lsa_query_info_policy(
06109 pipe_hnd, mem_ctx, &connect_hnd, 5 ,
06110 &dummy, &queried_dom_sid);
06111
06112 if (NT_STATUS_IS_ERR(nt_status)) {
06113 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
06114 nt_errstr(nt_status)));
06115 cli_shutdown(cli);
06116 talloc_destroy(mem_ctx);
06117 return -1;
06118 }
06119
06120
06121
06122
06123
06124
06125 d_printf("Trusted domains list:\n\n");
06126
06127 do {
06128 nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
06129 &num_domains,
06130 &trusted_dom_names, &domain_sids);
06131
06132 if (NT_STATUS_IS_ERR(nt_status)) {
06133 DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
06134 nt_errstr(nt_status)));
06135 cli_shutdown(cli);
06136 talloc_destroy(mem_ctx);
06137 return -1;
06138 };
06139
06140 for (i = 0; i < num_domains; i++) {
06141 print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
06142 };
06143
06144
06145
06146
06147
06148 if (!num_domains) d_printf("none\n");
06149
06150 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
06151
06152
06153 nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
06154 if (NT_STATUS_IS_ERR(nt_status)) {
06155 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
06156 nt_errstr(nt_status)));
06157 cli_shutdown(cli);
06158 talloc_destroy(mem_ctx);
06159 return -1;
06160 };
06161
06162 cli_rpc_pipe_close(pipe_hnd);
06163
06164
06165
06166
06167
06168 d_printf("\nTrusting domains list:\n\n");
06169
06170
06171
06172
06173 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
06174 if (!pipe_hnd) {
06175 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
06176 cli_shutdown(cli);
06177 talloc_destroy(mem_ctx);
06178 return -1;
06179 };
06180
06181
06182 nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
06183 &connect_hnd);
06184 if (!NT_STATUS_IS_OK(nt_status)) {
06185 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
06186 nt_errstr(nt_status)));
06187 cli_shutdown(cli);
06188 talloc_destroy(mem_ctx);
06189 return -1;
06190 };
06191
06192
06193
06194 nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
06195 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
06196 queried_dom_sid, &domain_hnd);
06197 if (!NT_STATUS_IS_OK(nt_status)) {
06198 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
06199 nt_errstr(nt_status)));
06200 cli_shutdown(cli);
06201 talloc_destroy(mem_ctx);
06202 return -1;
06203 };
06204
06205
06206
06207
06208
06209 enum_ctx = 0;
06210 do {
06211
06212 nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
06213 &enum_ctx, ACB_DOMTRUST, 0xffff,
06214 &trusting_dom_names, &trusting_dom_rids,
06215 &num_domains);
06216 if (NT_STATUS_IS_ERR(nt_status)) {
06217 DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
06218 nt_errstr(nt_status)));
06219 cli_shutdown(cli);
06220 talloc_destroy(mem_ctx);
06221 return -1;
06222 };
06223
06224 for (i = 0; i < num_domains; i++) {
06225
06226
06227
06228
06229
06230
06231
06232
06233 ascii_dom_name_len = strlen(trusting_dom_names[i]);
06234 if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
06235 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
06236
06237
06238 pad_len = col_len - strlen(trusting_dom_names[i]);
06239 padding[pad_len] = 0;
06240 do padding[--pad_len] = ' '; while (pad_len);
06241
06242
06243 strupper_m(trusting_dom_names[i]);
06244 opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
06245 opt_target_workgroup = opt_workgroup;
06246
06247 d_printf("%s%s", trusting_dom_names[i], padding);
06248
06249
06250 remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
06251 if (remote_cli) {
06252
06253 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
06254 d_fprintf(stderr, "couldn't get domain's sid\n");
06255
06256 cli_shutdown(remote_cli);
06257
06258 } else {
06259 d_fprintf(stderr, "domain controller is not responding\n");
06260 };
06261 };
06262
06263 if (!num_domains) d_printf("none\n");
06264
06265 } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
06266
06267
06268 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
06269 if (!NT_STATUS_IS_OK(nt_status)) {
06270 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
06271 };
06272
06273 nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
06274 if (!NT_STATUS_IS_OK(nt_status)) {
06275 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
06276 };
06277
06278
06279 cli_shutdown(cli);
06280
06281 talloc_destroy(mem_ctx);
06282 return 0;
06283 }
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294 static int rpc_trustdom(int argc, const char **argv)
06295 {
06296 struct functable func[] = {
06297 {"add", rpc_trustdom_add},
06298 {"del", rpc_trustdom_del},
06299 {"establish", rpc_trustdom_establish},
06300 {"revoke", rpc_trustdom_revoke},
06301 {"help", rpc_trustdom_usage},
06302 {"list", rpc_trustdom_list},
06303 {"vampire", rpc_trustdom_vampire},
06304 {NULL, NULL}
06305 };
06306
06307 if (argc == 0) {
06308 rpc_trustdom_usage(argc, argv);
06309 return -1;
06310 }
06311
06312 return (net_run_function(argc, argv, func, rpc_user_usage));
06313 }
06314
06315
06316
06317
06318
06319
06320
06321 BOOL net_rpc_check(unsigned flags)
06322 {
06323 struct cli_state *cli;
06324 BOOL ret = False;
06325 struct in_addr server_ip;
06326 char *server_name = NULL;
06327 NTSTATUS status;
06328
06329
06330 if (!net_find_server(NULL, flags, &server_ip, &server_name))
06331 return False;
06332
06333 if ((cli = cli_initialise()) == NULL) {
06334 return False;
06335 }
06336
06337 status = cli_connect(cli, server_name, &server_ip);
06338 if (!NT_STATUS_IS_OK(status))
06339 goto done;
06340 if (!attempt_netbios_session_request(&cli, global_myname(),
06341 server_name, &server_ip))
06342 goto done;
06343 if (!cli_negprot(cli))
06344 goto done;
06345 if (cli->protocol < PROTOCOL_NT1)
06346 goto done;
06347
06348 ret = True;
06349 done:
06350 cli_shutdown(cli);
06351 return ret;
06352 }
06353
06354
06355 static int rpc_samdump(int argc, const char **argv) {
06356 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
06357 argc, argv);
06358 }
06359
06360
06361 static int rpc_vampire(int argc, const char **argv) {
06362 return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
06363 argc, argv);
06364 }
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380 static int rpc_printer_migrate_all(int argc, const char **argv)
06381 {
06382 int ret;
06383
06384 if (!opt_host) {
06385 printf("no server to migrate\n");
06386 return -1;
06387 }
06388
06389 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_printers_internals, argc, argv);
06390 if (ret)
06391 return ret;
06392
06393 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_drivers_internals, argc, argv);
06394 if (ret)
06395 return ret;
06396
06397 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_forms_internals, argc, argv);
06398 if (ret)
06399 return ret;
06400
06401 ret = run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_settings_internals, argc, argv);
06402 if (ret)
06403 return ret;
06404
06405 return run_rpc_command(NULL, PI_SPOOLSS, 0, rpc_printer_migrate_security_internals, argc, argv);
06406
06407 }
06408
06409
06410
06411
06412
06413
06414
06415
06416
06417
06418 static int rpc_printer_migrate_drivers(int argc, const char **argv)
06419 {
06420 if (!opt_host) {
06421 printf("no server to migrate\n");
06422 return -1;
06423 }
06424
06425 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06426 rpc_printer_migrate_drivers_internals,
06427 argc, argv);
06428 }
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438
06439 static int rpc_printer_migrate_forms(int argc, const char **argv)
06440 {
06441 if (!opt_host) {
06442 printf("no server to migrate\n");
06443 return -1;
06444 }
06445
06446 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06447 rpc_printer_migrate_forms_internals,
06448 argc, argv);
06449 }
06450
06451
06452
06453
06454
06455
06456
06457
06458
06459
06460 static int rpc_printer_migrate_printers(int argc, const char **argv)
06461 {
06462 if (!opt_host) {
06463 printf("no server to migrate\n");
06464 return -1;
06465 }
06466
06467 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06468 rpc_printer_migrate_printers_internals,
06469 argc, argv);
06470 }
06471
06472
06473
06474
06475
06476
06477
06478
06479
06480
06481 static int rpc_printer_migrate_security(int argc, const char **argv)
06482 {
06483 if (!opt_host) {
06484 printf("no server to migrate\n");
06485 return -1;
06486 }
06487
06488 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06489 rpc_printer_migrate_security_internals,
06490 argc, argv);
06491 }
06492
06493
06494
06495
06496
06497
06498
06499
06500
06501
06502 static int rpc_printer_migrate_settings(int argc, const char **argv)
06503 {
06504 if (!opt_host) {
06505 printf("no server to migrate\n");
06506 return -1;
06507 }
06508
06509 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06510 rpc_printer_migrate_settings_internals,
06511 argc, argv);
06512 }
06513
06514
06515
06516
06517
06518
06519
06520
06521 int rpc_printer_migrate(int argc, const char **argv)
06522 {
06523
06524
06525
06526
06527
06528 struct functable func[] = {
06529 {"all", rpc_printer_migrate_all},
06530 {"drivers", rpc_printer_migrate_drivers},
06531 {"forms", rpc_printer_migrate_forms},
06532 {"help", rpc_printer_usage},
06533 {"printers", rpc_printer_migrate_printers},
06534 {"security", rpc_printer_migrate_security},
06535 {"settings", rpc_printer_migrate_settings},
06536 {NULL, NULL}
06537 };
06538
06539 return net_run_function(argc, argv, func, rpc_printer_usage);
06540 }
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552 static int rpc_printer_list(int argc, const char **argv)
06553 {
06554
06555 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06556 rpc_printer_list_internals,
06557 argc, argv);
06558 }
06559
06560
06561
06562
06563
06564
06565
06566
06567
06568
06569 static int rpc_printer_driver_list(int argc, const char **argv)
06570 {
06571
06572 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06573 rpc_printer_driver_list_internals,
06574 argc, argv);
06575 }
06576
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586 static int rpc_printer_publish_publish(int argc, const char **argv)
06587 {
06588
06589 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06590 rpc_printer_publish_publish_internals,
06591 argc, argv);
06592 }
06593
06594
06595
06596
06597
06598
06599
06600
06601
06602
06603 static int rpc_printer_publish_update(int argc, const char **argv)
06604 {
06605
06606 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06607 rpc_printer_publish_update_internals,
06608 argc, argv);
06609 }
06610
06611
06612
06613
06614
06615
06616
06617
06618
06619
06620 static int rpc_printer_publish_unpublish(int argc, const char **argv)
06621 {
06622
06623 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06624 rpc_printer_publish_unpublish_internals,
06625 argc, argv);
06626 }
06627
06628
06629
06630
06631
06632
06633
06634
06635
06636
06637 static int rpc_printer_publish_list(int argc, const char **argv)
06638 {
06639
06640 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06641 rpc_printer_publish_list_internals,
06642 argc, argv);
06643 }
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654
06655 static int rpc_printer_publish(int argc, const char **argv)
06656 {
06657
06658 struct functable func[] = {
06659 {"publish", rpc_printer_publish_publish},
06660 {"update", rpc_printer_publish_update},
06661 {"unpublish", rpc_printer_publish_unpublish},
06662 {"list", rpc_printer_publish_list},
06663 {"help", rpc_printer_usage},
06664 {NULL, NULL}
06665 };
06666
06667 if (argc == 0)
06668 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06669 rpc_printer_publish_list_internals,
06670 argc, argv);
06671
06672 return net_run_function(argc, argv, func, rpc_printer_usage);
06673
06674 }
06675
06676
06677
06678
06679
06680
06681
06682
06683 int rpc_printer_usage(int argc, const char **argv)
06684 {
06685 return net_help_printer(argc, argv);
06686 }
06687
06688
06689
06690
06691
06692
06693
06694 int net_rpc_printer(int argc, const char **argv)
06695 {
06696 struct functable func[] = {
06697 {"list", rpc_printer_list},
06698 {"migrate", rpc_printer_migrate},
06699 {"driver", rpc_printer_driver_list},
06700 {"publish", rpc_printer_publish},
06701 {NULL, NULL}
06702 };
06703
06704 if (argc == 0)
06705 return run_rpc_command(NULL, PI_SPOOLSS, 0,
06706 rpc_printer_list_internals,
06707 argc, argv);
06708
06709 return net_run_function(argc, argv, func, rpc_printer_usage);
06710 }
06711
06712
06713
06714
06715
06716
06717
06718
06719
06720
06721
06722 int net_rpc_usage(int argc, const char **argv)
06723 {
06724 d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
06725 d_printf(" net rpc join \t\t\tto join a domain \n");
06726 d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n");
06727 d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
06728 d_printf(" net rpc user \t\t\tto add, delete and list users\n");
06729 d_printf(" net rpc password <username> [<password>] -Uadmin_username%%admin_pass\n");
06730 d_printf(" net rpc group \t\tto list groups\n");
06731 d_printf(" net rpc share \t\tto add, delete, list and migrate shares\n");
06732 d_printf(" net rpc printer \t\tto list and migrate printers\n");
06733 d_printf(" net rpc file \t\t\tto list open files\n");
06734 d_printf(" net rpc changetrustpw \tto change the trust account password\n");
06735 d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
06736 d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
06737 d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
06738 d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
06739 d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
06740 d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
06741 d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
06742 d_printf(" net rpc registry\t\tto manage registry hives\n");
06743 d_printf(" net rpc service\t\tto start, stop and query services\n");
06744 d_printf(" net rpc audit\t\t\tto modify global auditing settings\n");
06745 d_printf(" net rpc shell\t\t\tto open an interactive shell for remote server/account management\n");
06746 d_printf("\n");
06747 d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n");
06748 d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
06749 d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
06750 d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
06751 d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n");
06752 return -1;
06753 }
06754
06755
06756
06757
06758
06759
06760
06761
06762
06763
06764 int net_rpc_help(int argc, const char **argv)
06765 {
06766 struct functable func[] = {
06767 {"join", rpc_join_usage},
06768 {"user", rpc_user_usage},
06769 {"group", rpc_group_usage},
06770 {"share", rpc_share_usage},
06771
06772 {"trustdom", rpc_trustdom_usage},
06773
06774
06775 {"vampire", rpc_vampire_usage},
06776 {NULL, NULL}
06777 };
06778
06779 if (argc == 0) {
06780 net_rpc_usage(argc, argv);
06781 return -1;
06782 }
06783
06784 return (net_run_function(argc, argv, func, rpc_user_usage));
06785 }
06786
06787
06788
06789
06790
06791
06792
06793
06794 int net_rpc(int argc, const char **argv)
06795 {
06796 struct functable func[] = {
06797 {"audit", net_rpc_audit},
06798 {"info", net_rpc_info},
06799 {"join", net_rpc_join},
06800 {"oldjoin", net_rpc_oldjoin},
06801 {"testjoin", net_rpc_testjoin},
06802 {"user", net_rpc_user},
06803 {"password", rpc_user_password},
06804 {"group", net_rpc_group},
06805 {"share", net_rpc_share},
06806 {"file", net_rpc_file},
06807 {"printer", net_rpc_printer},
06808 {"changetrustpw", net_rpc_changetrustpw},
06809 {"trustdom", rpc_trustdom},
06810 {"abortshutdown", rpc_shutdown_abort},
06811 {"shutdown", rpc_shutdown},
06812 {"samdump", rpc_samdump},
06813 {"vampire", rpc_vampire},
06814 {"getsid", net_rpc_getsid},
06815 {"rights", net_rpc_rights},
06816 {"service", net_rpc_service},
06817 {"registry", net_rpc_registry},
06818 {"shell", net_rpc_shell},
06819 {"help", net_rpc_help},
06820 {NULL, NULL}
06821 };
06822 return net_run_function(argc, argv, func, net_rpc_usage);
06823 }