Store the type of 'sec channel' that we establish to the DC. If we are a
[sfrench/samba-autobuild/.git] / source / utils / net_rpc.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    Distributed SMB/CIFS Server Management Utility 
4    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
5    Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20  
21 #include "includes.h"
22 #include "../utils/net.h"
23
24 /**
25  * @file net_rpc.c
26  *
27  * @brief RPC based subcommands for the 'net' utility.
28  *
29  * This file should contain much of the functionality that used to
30  * be found in rpcclient, execpt that the commands should change 
31  * less often, and the fucntionality should be sane (the user is not 
32  * expected to know a rid/sid before they conduct an operation etc.)
33  *
34  * @todo Perhaps eventually these should be split out into a number
35  * of files, as this could get quite big.
36  **/
37
38
39 /* A function of this type is passed to the 'run_rpc_command' wrapper */
40 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
41
42 /**
43  * Many of the RPC functions need the domain sid.  This function gets
44  *  it at the start of every run 
45  *
46  * @param cli A cli_state already connected to the remote machine
47  *
48  * @return The Domain SID of the remote machine.
49  **/
50
51 static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
52 {
53         DOM_SID *domain_sid;
54         POLICY_HND pol;
55         NTSTATUS result = NT_STATUS_OK;
56         uint32 info_class = 5;
57         fstring domain_name;
58         TALLOC_CTX *mem_ctx;
59         
60         if (!(domain_sid = malloc(sizeof(DOM_SID)))){
61                 DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n"));
62                 goto error;
63         }
64             
65         if (!(mem_ctx=talloc_init("net_get_remote_domain_sid")))
66         {
67                 DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n"));
68                 goto error;
69         }
70
71
72         if (!cli_nt_session_open (cli, PI_LSARPC)) {
73                 fprintf(stderr, "could not initialise lsa pipe\n");
74                 goto error;
75         }
76         
77         result = cli_lsa_open_policy(cli, mem_ctx, True, 
78                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
79                                      &pol);
80         if (!NT_STATUS_IS_OK(result)) {
81                 goto error;
82         }
83
84         result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 
85                                            domain_name, domain_sid);
86         if (!NT_STATUS_IS_OK(result)) {
87                 goto error;
88         }
89
90         cli_lsa_close(cli, mem_ctx, &pol);
91         cli_nt_session_close(cli);
92         talloc_destroy(mem_ctx);
93
94         return domain_sid;
95
96  error:
97         fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
98
99         if (!NT_STATUS_IS_OK(result)) {
100                 fprintf(stderr, "error: %s\n", nt_errstr(result));
101         }
102
103         exit(1);
104 }
105
106 /**
107  * Run a single RPC command, from start to finish.
108  *
109  * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
110  * @param conn_flag a NET_FLAG_ combination.  Passed to 
111  *                   net_make_ipc_connection.
112  * @param argc  Standard main() style argc
113  * @param argc  Standard main() style argv.  Initial components are already
114  *              stripped
115  * @return A shell status integer (0 for success)
116  */
117
118 static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
119                            rpc_command_fn fn,
120                            int argc, const char **argv) 
121 {
122         struct cli_state *cli = NULL;
123         TALLOC_CTX *mem_ctx;
124         NTSTATUS nt_status;
125         DOM_SID *domain_sid;
126
127         /* make use of cli_state handed over as an argument, if possible */
128         if (!cli_arg)
129                 cli = net_make_ipc_connection(conn_flags);
130         else
131                 cli = cli_arg;
132
133         if (!cli) {
134                 return -1;
135         }
136
137         domain_sid = net_get_remote_domain_sid(cli);
138
139         /* Create mem_ctx */
140         
141         if (!(mem_ctx = talloc_init("run_rpc_command"))) {
142                 DEBUG(0, ("talloc_init() failed\n"));
143                 cli_shutdown(cli);
144                 return -1;
145         }
146         
147         if (!cli_nt_session_open(cli, pipe_idx)) {
148                 DEBUG(0, ("Could not initialise pipe\n"));
149         }
150         
151         nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
152         
153         if (!NT_STATUS_IS_OK(nt_status)) {
154                 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
155         } else {
156                 DEBUG(5, ("rpc command function succedded\n"));
157         }
158                 
159             
160         if (cli->nt_pipe_fnum)
161                 cli_nt_session_close(cli);
162         
163         /* close the connection only if it was opened here */
164         if (!cli_arg)
165                 cli_shutdown(cli);
166         
167         talloc_destroy(mem_ctx);
168
169         return (!NT_STATUS_IS_OK(nt_status));
170 }
171
172
173 /****************************************************************************/
174
175
176 /** 
177  * Force a change of the trust acccount password.
178  *
179  * All parameters are provided by the run_rpc_command function, except for
180  * argc, argv which are passes through. 
181  *
182  * @param domain_sid The domain sid aquired from the remote server
183  * @param cli A cli_state connected to the server.
184  * @param mem_ctx Talloc context, destoyed on compleation of the function.
185  * @param argc  Standard main() style argc
186  * @param argc  Standard main() style argv.  Initial components are already
187  *              stripped
188  *
189  * @return Normal NTSTATUS return.
190  **/
191
192 static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
193                                        int argc, const char **argv) {
194         
195         return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
196 }
197
198 /** 
199  * Force a change of the trust acccount password.
200  *
201  * @param argc  Standard main() style argc
202  * @param argc  Standard main() style argv.  Initial components are already
203  *              stripped
204  *
205  * @return A shell status integer (0 for success)
206  **/
207
208 int net_rpc_changetrustpw(int argc, const char **argv) 
209 {
210         return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
211                                argc, argv);
212 }
213
214
215 /****************************************************************************/
216
217
218 /** 
219  * Join a domain, the old way.
220  *
221  * This uses 'machinename' as the inital password, and changes it. 
222  *
223  * The password should be created with 'server manager' or equiv first.
224  *
225  * All parameters are provided by the run_rpc_command function, except for
226  * argc, argv which are passes through. 
227  *
228  * @param domain_sid The domain sid aquired from the remote server
229  * @param cli A cli_state connected to the server.
230  * @param mem_ctx Talloc context, destoyed on compleation of the function.
231  * @param argc  Standard main() style argc
232  * @param argc  Standard main() style argv.  Initial components are already
233  *              stripped
234  *
235  * @return Normal NTSTATUS return.
236  **/
237
238 static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, 
239                                             TALLOC_CTX *mem_ctx, 
240                                             int argc, const char **argv) {
241         
242         fstring trust_passwd;
243         unsigned char orig_trust_passwd_hash[16];
244         NTSTATUS result;
245
246         fstrcpy(trust_passwd, global_myname());
247         strlower(trust_passwd);
248
249         /*
250          * Machine names can be 15 characters, but the max length on
251          * a password is 14.  --jerry
252          */
253
254         trust_passwd[14] = '\0';
255
256         E_md4hash(trust_passwd, orig_trust_passwd_hash);
257
258         result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
259                                               orig_trust_passwd_hash,
260                                               SEC_CHAN_WKSTA);
261
262         /* SEC_CHAN_WKSTA specified specifically, as you cannot use this
263            to join a BDC to the domain (MS won't allow it, and is *really*
264            insecure) */
265
266         if (NT_STATUS_IS_OK(result))
267                 printf("Joined domain %s.\n",opt_target_workgroup);
268
269
270         if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
271                 DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
272                 result = NT_STATUS_UNSUCCESSFUL;
273         }
274
275         return result;
276 }
277
278 /** 
279  * Join a domain, the old way.
280  *
281  * @param argc  Standard main() style argc
282  * @param argc  Standard main() style argv.  Initial components are already
283  *              stripped
284  *
285  * @return A shell status integer (0 for success)
286  **/
287
288 static int net_rpc_join_oldstyle(int argc, const char **argv) 
289 {
290         uint32 sec_channel_type;
291         /* check what type of join */
292         if (argc >= 0) {
293                 sec_channel_type = get_sec_channel_type(argv[0]);
294         } else {
295                 sec_channel_type = get_sec_channel_type(NULL);
296         }
297         
298         if (sec_channel_type != SEC_CHAN_WKSTA) 
299                 return 1;
300
301         return run_rpc_command(NULL, PI_NETLOGON, 
302                                NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 
303                                rpc_join_oldstyle_internals,
304                                argc, argv);
305 }
306
307 /** 
308  * Join a domain, the old way.
309  *
310  * @param argc  Standard main() style argc
311  * @param argc  Standard main() style argv.  Initial components are already
312  *              stripped
313  *
314  * @return A shell status integer (0 for success)
315  **/
316
317 static int net_rpc_oldjoin(int argc, const char **argv) 
318 {
319         return run_rpc_command(NULL, PI_NETLOGON, 
320                                NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 
321                                rpc_join_oldstyle_internals,
322                                argc, argv);
323 }
324
325 /** 
326  * Basic usage function for 'net rpc join'
327  * @param argc  Standard main() style argc
328  * @param argc  Standard main() style argv.  Initial components are already
329  *              stripped
330  **/
331
332 static int rpc_join_usage(int argc, const char **argv) 
333 {       
334         d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
335                  "\t to join a domain with admin username & password\n"\
336                  "\t\t password will be prompted if needed and none is specified\n"\
337                  "\t <type> can be (default MEMBER)\n"\
338                  "\t\t BDC - Join as a BDC\n"\
339                  "\t\t PDC - Join as a PDC\n"\
340                  "\t\t MEMBER - Join as a MEMBER server\n");
341
342         net_common_flags_usage(argc, argv);
343         return -1;
344 }
345
346 /** 
347  * 'net rpc join' entrypoint.
348  * @param argc  Standard main() style argc
349  * @param argc  Standard main() style argv.  Initial components are already
350  *              stripped
351  *
352  * Main 'net_rpc_join()' (where the admain username/password is used) is 
353  * in net_rpc_join.c
354  * Assume if a -U is specified, it's the new style, otherwise it's the
355  * old style.  If 'oldstyle' is specfied explicity, do it and don't prompt.
356  **/
357
358 int net_rpc_join(int argc, const char **argv) 
359 {
360         if ((net_rpc_join_oldstyle(argc, argv) == 0))
361                 return 0;
362         
363         return net_rpc_join_newstyle(argc, argv);
364 }
365
366
367
368 /** 
369  * display info about a rpc domain
370  *
371  * All parameters are provided by the run_rpc_command function, except for
372  * argc, argv which are passed through. 
373  *
374  * @param domain_sid The domain sid acquired from the remote server
375  * @param cli A cli_state connected to the server.
376  * @param mem_ctx Talloc context, destoyed on completion of the function.
377  * @param argc  Standard main() style argc
378  * @param argv  Standard main() style argv.  Initial components are already
379  *              stripped
380  *
381  * @return Normal NTSTATUS return.
382  **/
383
384 static NTSTATUS 
385 rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
386                    TALLOC_CTX *mem_ctx, int argc, const char **argv)
387 {
388         POLICY_HND connect_pol, domain_pol;
389         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
390         SAM_UNK_CTR ctr;
391         fstring sid_str;
392
393         sid_to_string(sid_str, domain_sid);
394
395         /* Get sam policy handle */     
396         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
397                                   &connect_pol);
398         if (!NT_STATUS_IS_OK(result)) {
399                 goto done;
400         }
401         
402         /* Get domain policy handle */
403         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
404                                       MAXIMUM_ALLOWED_ACCESS,
405                                       domain_sid, &domain_pol);
406         if (!NT_STATUS_IS_OK(result)) {
407                 goto done;
408         }
409
410         ZERO_STRUCT(ctr);
411         result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
412                                          2, &ctr);
413         if (NT_STATUS_IS_OK(result)) {
414                 TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
415                 d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
416                 d_printf("Domain SID: %s\n", sid_str);
417                 d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
418                 d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
419                 d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
420                 d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
421                 talloc_destroy(ctx);
422         }
423
424  done:
425         return result;
426 }
427
428
429 /** 
430  * 'net rpc info' entrypoint.
431  * @param argc  Standard main() style argc
432  * @param argc  Standard main() style argv.  Initial components are already
433  *              stripped
434  **/
435 int net_rpc_info(int argc, const char **argv) 
436 {
437         return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 
438                                rpc_info_internals,
439                                argc, argv);
440 }
441
442
443 /** 
444  * Fetch domain SID into the local secrets.tdb
445  *
446  * All parameters are provided by the run_rpc_command function, except for
447  * argc, argv which are passes through. 
448  *
449  * @param domain_sid The domain sid acquired from the remote server
450  * @param cli A cli_state connected to the server.
451  * @param mem_ctx Talloc context, destoyed on completion of the function.
452  * @param argc  Standard main() style argc
453  * @param argv  Standard main() style argv.  Initial components are already
454  *              stripped
455  *
456  * @return Normal NTSTATUS return.
457  **/
458
459 static NTSTATUS 
460 rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli,
461                    TALLOC_CTX *mem_ctx, int argc, const char **argv)
462 {
463         fstring sid_str;
464
465         sid_to_string(sid_str, domain_sid);
466         d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
467                  sid_str, lp_workgroup());
468
469         if (!secrets_store_domain_sid(global_myname(), domain_sid)) {
470                 DEBUG(0,("Can't store domain SID\n"));
471                 return NT_STATUS_UNSUCCESSFUL;
472         }
473
474         return NT_STATUS_OK;
475 }
476
477
478 /** 
479  * 'net rpc getsid' entrypoint.
480  * @param argc  Standard main() style argc
481  * @param argc  Standard main() style argv.  Initial components are already
482  *              stripped
483  **/
484 int net_rpc_getsid(int argc, const char **argv) 
485 {
486         return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 
487                                rpc_getsid_internals,
488                                argc, argv);
489 }
490
491
492 /****************************************************************************/
493
494 /**
495  * Basic usage function for 'net rpc user'
496  * @param argc  Standard main() style argc.
497  * @param argv  Standard main() style argv.  Initial components are already
498  *              stripped.
499  **/
500
501 static int rpc_user_usage(int argc, const char **argv)
502 {
503         return net_help_user(argc, argv);
504 }
505
506 /** 
507  * Add a new user to a remote RPC server
508  *
509  * All parameters are provided by the run_rpc_command function, except for
510  * argc, argv which are passes through. 
511  *
512  * @param domain_sid The domain sid acquired from the remote server
513  * @param cli A cli_state connected to the server.
514  * @param mem_ctx Talloc context, destoyed on completion of the function.
515  * @param argc  Standard main() style argc
516  * @param argv  Standard main() style argv.  Initial components are already
517  *              stripped
518  *
519  * @return Normal NTSTATUS return.
520  **/
521
522 static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
523                                        int argc, const char **argv) {
524         
525         POLICY_HND connect_pol, domain_pol, user_pol;
526         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
527         const char *acct_name;
528         uint16 acb_info;
529         uint32 unknown, user_rid;
530
531         if (argc != 1) {
532                 d_printf("User must be specified\n");
533                 rpc_user_usage(argc, argv);
534                 return NT_STATUS_OK;
535         }
536
537         acct_name = argv[0];
538
539         /* Get sam policy handle */
540         
541         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
542                                   &connect_pol);
543         if (!NT_STATUS_IS_OK(result)) {
544                 goto done;
545         }
546         
547         /* Get domain policy handle */
548         
549         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
550                                       MAXIMUM_ALLOWED_ACCESS,
551                                       domain_sid, &domain_pol);
552         if (!NT_STATUS_IS_OK(result)) {
553                 goto done;
554         }
555
556         /* Create domain user */
557
558         acb_info = ACB_NORMAL;
559         unknown = 0xe005000b; /* No idea what this is - a permission mask? */
560
561         result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
562                                           acct_name, acb_info, unknown,
563                                           &user_pol, &user_rid);
564         if (!NT_STATUS_IS_OK(result)) {
565                 goto done;
566         }
567
568  done:
569         if (!NT_STATUS_IS_OK(result)) {
570                 d_printf("Failed to add user %s - %s\n", acct_name, 
571                          nt_errstr(result));
572         } else {
573                 d_printf("Added user %s\n", acct_name);
574         }
575         return result;
576 }
577
578 /** 
579  * Add a new user to a remote RPC server
580  *
581  * @param argc  Standard main() style argc
582  * @param argv  Standard main() style argv.  Initial components are already
583  *              stripped
584  *
585  * @return A shell status integer (0 for success)
586  **/
587
588 static int rpc_user_add(int argc, const char **argv) 
589 {
590         return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_add_internals,
591                                argc, argv);
592 }
593
594 /** 
595  * Delete a user from a remote RPC server
596  *
597  * All parameters are provided by the run_rpc_command function, except for
598  * argc, argv which are passes through. 
599  *
600  * @param domain_sid The domain sid acquired from the remote server
601  * @param cli A cli_state connected to the server.
602  * @param mem_ctx Talloc context, destoyed on completion of the function.
603  * @param argc  Standard main() style argc
604  * @param argv  Standard main() style argv.  Initial components are already
605  *              stripped
606  *
607  * @return Normal NTSTATUS return.
608  **/
609
610 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, 
611                                        struct cli_state *cli, 
612                                        TALLOC_CTX *mem_ctx, 
613                                        int argc, const char **argv)
614 {
615         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
616         POLICY_HND connect_pol, domain_pol, user_pol;
617
618         if (argc < 1) {
619                 d_printf("User must be specified\n");
620                 rpc_user_usage(argc, argv);
621                 return NT_STATUS_OK;
622         }
623         /* Get sam policy and domain handles */
624
625         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
626                                   &connect_pol);
627
628         if (!NT_STATUS_IS_OK(result)) {
629                 goto done;
630         }
631
632         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
633                                       MAXIMUM_ALLOWED_ACCESS,
634                                       domain_sid, &domain_pol);
635
636         if (!NT_STATUS_IS_OK(result)) {
637                 goto done;
638         }
639
640         /* Get handle on user */
641
642         {
643                 uint32 *user_rids, num_rids, *name_types;
644                 uint32 flags = 0x000003e8; /* Unknown */
645
646                 result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
647                                                flags, 1, &argv[0],
648                                                &num_rids, &user_rids,
649                                                &name_types);
650
651                 if (!NT_STATUS_IS_OK(result)) {
652                         goto done;
653                 }
654
655                 result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
656                                             MAXIMUM_ALLOWED_ACCESS,
657                                             user_rids[0], &user_pol);
658
659                 if (!NT_STATUS_IS_OK(result)) {
660                         goto done;
661                 }
662         }
663
664         /* Delete user */
665
666         result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
667
668         if (!NT_STATUS_IS_OK(result)) {
669                 goto done;
670         }
671
672         /* Display results */
673
674  done:
675         return result;
676
677 }       
678
679 /** 
680  * Delete a user from a remote RPC server
681  *
682  * @param argc  Standard main() style argc
683  * @param argv  Standard main() style argv.  Initial components are already
684  *              stripped
685  *
686  * @return A shell status integer (0 for success)
687  **/
688
689 static int rpc_user_delete(int argc, const char **argv) 
690 {
691         return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_del_internals,
692                                argc, argv);
693 }
694
695 /** 
696  * List user's groups on a remote RPC server
697  *
698  * All parameters are provided by the run_rpc_command function, except for
699  * argc, argv which are passes through. 
700  *
701  * @param domain_sid The domain sid acquired from the remote server
702  * @param cli A cli_state connected to the server.
703  * @param mem_ctx Talloc context, destoyed on completion of the function.
704  * @param argc  Standard main() style argc
705  * @param argv  Standard main() style argv.  Initial components are already
706  *              stripped
707  *
708  * @return Normal NTSTATUS return.
709  **/
710
711 static NTSTATUS 
712 rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
713                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
714 {
715         POLICY_HND connect_pol, domain_pol, user_pol;
716         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
717         uint32 *rids, num_rids, *name_types, num_names;
718         uint32 flags = 0x000003e8; /* Unknown */
719         int i;
720         char **names;
721         DOM_GID *user_gids;
722
723         if (argc < 1) {
724                 d_printf("User must be specified\n");
725                 rpc_user_usage(argc, argv);
726                 return NT_STATUS_OK;
727         }
728         /* Get sam policy handle */
729         
730         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
731                                   &connect_pol);
732         if (!NT_STATUS_IS_OK(result)) goto done;
733         
734         /* Get domain policy handle */
735         
736         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
737                                       MAXIMUM_ALLOWED_ACCESS,
738                                       domain_sid, &domain_pol);
739         if (!NT_STATUS_IS_OK(result)) goto done;
740
741         /* Get handle on user */
742
743         result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
744                                        flags, 1, &argv[0],
745                                        &num_rids, &rids, &name_types);
746
747         if (!NT_STATUS_IS_OK(result)) goto done;
748
749         result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
750                                     MAXIMUM_ALLOWED_ACCESS,
751                                     rids[0], &user_pol);
752         if (!NT_STATUS_IS_OK(result)) goto done;
753
754         result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
755                                            &num_rids, &user_gids);
756
757         /* Look up rids */
758
759         rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
760
761         for (i = 0; i < num_rids; i++)
762                 rids[i] = user_gids[i].g_rid;
763
764         result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
765                                       flags, num_rids, rids,
766                                       &num_names, &names, &name_types);
767
768         if (!NT_STATUS_IS_OK(result)) {
769                 goto done;
770         }
771
772         /* Display results */
773
774         for (i = 0; i < num_names; i++)
775                 printf("%s\n", names[i]);
776
777  done:
778         return result;
779 }
780
781 /** 
782  * List a user's groups from a remote RPC server
783  *
784  * @param argc  Standard main() style argc
785  * @param argv  Standard main() style argv.  Initial components are already
786  *              stripped
787  *
788  * @return A shell status integer (0 for success)
789  **/
790
791 static int rpc_user_info(int argc, const char **argv) 
792 {
793         return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_info_internals,
794                                argc, argv);
795 }
796
797 /** 
798  * List users on a remote RPC server
799  *
800  * All parameters are provided by the run_rpc_command function, except for
801  * argc, argv which are passes through. 
802  *
803  * @param domain_sid The domain sid acquired from the remote server
804  * @param cli A cli_state connected to the server.
805  * @param mem_ctx Talloc context, destoyed on completion of the function.
806  * @param argc  Standard main() style argc
807  * @param argv  Standard main() style argv.  Initial components are already
808  *              stripped
809  *
810  * @return Normal NTSTATUS return.
811  **/
812
813 static NTSTATUS 
814 rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
815                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
816 {
817         POLICY_HND connect_pol, domain_pol;
818         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
819         uint32 start_idx=0, num_entries, i, loop_count = 0;
820         SAM_DISPINFO_CTR ctr;
821         SAM_DISPINFO_1 info1;
822
823         /* Get sam policy handle */
824         
825         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
826                                   &connect_pol);
827         if (!NT_STATUS_IS_OK(result)) {
828                 goto done;
829         }
830         
831         /* Get domain policy handle */
832         
833         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
834                                       MAXIMUM_ALLOWED_ACCESS,
835                                       domain_sid, &domain_pol);
836         if (!NT_STATUS_IS_OK(result)) {
837                 goto done;
838         }
839
840         /* Query domain users */
841         ZERO_STRUCT(ctr);
842         ZERO_STRUCT(info1);
843         ctr.sam.info1 = &info1;
844         if (opt_long_list_entries)
845                 d_printf("\nUser name             Comment"\
846                          "\n-----------------------------\n");
847         do {
848                 fstring user, desc;
849                 uint32 max_entries, max_size;
850
851                 get_query_dispinfo_params(
852                         loop_count, &max_entries, &max_size);
853
854                 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
855                                                  &start_idx, 1, &num_entries,
856                                                  max_entries, max_size, &ctr);
857                 loop_count++;
858
859                 for (i = 0; i < num_entries; i++) {
860                         unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
861                         if (opt_long_list_entries) 
862                                 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
863                         
864                         if (opt_long_list_entries)
865                                 printf("%-21.21s %-50.50s\n", user, desc);
866                         else
867                                 printf("%s\n", user);
868                 }
869         } while (!NT_STATUS_IS_OK(result));
870
871  done:
872         return result;
873 }
874
875 /** 
876  * 'net rpc user' entrypoint.
877  * @param argc  Standard main() style argc
878  * @param argc  Standard main() style argv.  Initial components are already
879  *              stripped
880  **/
881
882 int net_rpc_user(int argc, const char **argv) 
883 {
884         struct functable func[] = {
885                 {"add", rpc_user_add},
886                 {"info", rpc_user_info},
887                 {"delete", rpc_user_delete},
888                 {NULL, NULL}
889         };
890         
891         if (argc == 0) {
892                 if (opt_long_list_entries) {
893                 } else {
894                 }
895                         return run_rpc_command(NULL,PI_SAMR, 0, 
896                                                rpc_user_list_internals,
897                                                argc, argv);
898         }
899
900         return net_run_function(argc, argv, func, rpc_user_usage);
901 }
902
903
904 /****************************************************************************/
905
906 /**
907  * Basic usage function for 'net rpc group'
908  * @param argc  Standard main() style argc.
909  * @param argv  Standard main() style argv.  Initial components are already
910  *              stripped.
911  **/
912
913 static int rpc_group_usage(int argc, const char **argv)
914 {
915         return net_help_group(argc, argv);
916 }
917
918 /** 
919  * List groups on a remote RPC server
920  *
921  * All parameters are provided by the run_rpc_command function, except for
922  * argc, argv which are passes through. 
923  *
924  * @param domain_sid The domain sid acquired from the remote server
925  * @param cli A cli_state connected to the server.
926  * @param mem_ctx Talloc context, destoyed on completion of the function.
927  * @param argc  Standard main() style argc
928  * @param argv  Standard main() style argv.  Initial components are already
929  *              stripped
930  *
931  * @return Normal NTSTATUS return.
932  **/
933
934 static NTSTATUS 
935 rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
936                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
937 {
938         POLICY_HND connect_pol, domain_pol;
939         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
940         uint32 start_idx=0, max_entries=250, num_entries, i;
941         struct acct_info *groups;
942         DOM_SID global_sid_Builtin;
943
944         string_to_sid(&global_sid_Builtin, "S-1-5-32");
945
946         /* Get sam policy handle */
947         
948         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
949                                   &connect_pol);
950         if (!NT_STATUS_IS_OK(result)) {
951                 goto done;
952         }
953         
954         /* Get domain policy handle */
955         
956         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
957                                       MAXIMUM_ALLOWED_ACCESS,
958                                       domain_sid, &domain_pol);
959         if (!NT_STATUS_IS_OK(result)) {
960                 goto done;
961         }
962
963         /* Query domain groups */
964         if (opt_long_list_entries)
965                 d_printf("\nGroup name            Comment"\
966                          "\n-----------------------------\n");
967         do {
968                 result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
969                                                   &start_idx, max_entries,
970                                                   &groups, &num_entries);
971                                                  
972                 for (i = 0; i < num_entries; i++) {
973                         if (opt_long_list_entries)
974                                 printf("%-21.21s %-50.50s\n", 
975                                        groups[i].acct_name,
976                                        groups[i].acct_desc);
977                         else
978                                 printf("%-21.21s\n", groups[i].acct_name);
979                 }
980         } while (!NT_STATUS_IS_OK(result));
981         /* query domain aliases */
982         do {
983                 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
984                                                   &start_idx, max_entries,
985                                                   &groups, &num_entries);
986                                                  
987                 for (i = 0; i < num_entries; i++) {
988                         if (opt_long_list_entries)
989                                 printf("%-21.21s %-50.50s\n", 
990                                        groups[i].acct_name,
991                                        groups[i].acct_desc);
992                         else
993                                 printf("%-21.21s\n", groups[i].acct_name);
994                 }
995         } while (!NT_STATUS_IS_OK(result));
996         cli_samr_close(cli, mem_ctx, &domain_pol);
997         /* Get builtin policy handle */
998         
999         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1000                                       MAXIMUM_ALLOWED_ACCESS,
1001                                       &global_sid_Builtin, &domain_pol);
1002         if (!NT_STATUS_IS_OK(result)) {
1003                 goto done;
1004         }
1005         /* query builtin aliases */
1006         do {
1007                 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
1008                                                   &start_idx, max_entries,
1009                                                   &groups, &num_entries);
1010                                                  
1011                 for (i = 0; i < num_entries; i++) {
1012                         if (opt_long_list_entries)
1013                                 printf("%-21.21s %-50.50s\n", 
1014                                        groups[i].acct_name,
1015                                        groups[i].acct_desc);
1016                         else
1017                                 printf("%s\n", groups[i].acct_name);
1018                 }
1019         } while (!NT_STATUS_IS_OK(result));
1020
1021  done:
1022         return result;
1023 }
1024
1025 /** 
1026  * 'net rpc group' entrypoint.
1027  * @param argc  Standard main() style argc
1028  * @param argc  Standard main() style argv.  Initial components are already
1029  *              stripped
1030  **/
1031
1032 int net_rpc_group(int argc, const char **argv) 
1033 {
1034         struct functable func[] = {
1035 #if 0
1036                 {"add", rpc_group_add},
1037                 {"delete", rpc_group_delete},
1038 #endif
1039                 {NULL, NULL}
1040         };
1041         
1042         if (argc == 0) {
1043                 if (opt_long_list_entries) {
1044                 } else {
1045                 }
1046                 return run_rpc_command(NULL, PI_SAMR, 0, 
1047                                        rpc_group_list_internals,
1048                                        argc, argv);
1049         }
1050
1051         return net_run_function(argc, argv, func, rpc_group_usage);
1052 }
1053
1054 /****************************************************************************/
1055
1056 static int rpc_share_usage(int argc, const char **argv)
1057 {
1058         return net_help_share(argc, argv);
1059 }
1060
1061 /** 
1062  * Add a share on a remote RPC server
1063  *
1064  * All parameters are provided by the run_rpc_command function, except for
1065  * argc, argv which are passes through. 
1066  *
1067  * @param domain_sid The domain sid acquired from the remote server
1068  * @param cli A cli_state connected to the server.
1069  * @param mem_ctx Talloc context, destoyed on completion of the function.
1070  * @param argc  Standard main() style argc
1071  * @param argv  Standard main() style argv.  Initial components are already
1072  *              stripped
1073  *
1074  * @return Normal NTSTATUS return.
1075  **/
1076 static NTSTATUS 
1077 rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1078                         TALLOC_CTX *mem_ctx,int argc, const char **argv)
1079 {
1080         WERROR result;
1081         char *sharename=talloc_strdup(mem_ctx, argv[0]);
1082         char *path;
1083         uint32 type=0; /* only allow disk shares to be added */
1084         uint32 num_users=0, perms=0;
1085         char *password=NULL; /* don't allow a share password */
1086
1087         path = strchr(sharename, '=');
1088         if (!path)
1089                 return NT_STATUS_UNSUCCESSFUL;
1090         *path++ = '\0';
1091
1092         result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
1093                                           opt_comment, perms, opt_maxusers,
1094                                           num_users, path, password);
1095         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1096 }
1097
1098 static int rpc_share_add(int argc, const char **argv)
1099 {
1100         if ((argc < 1) || !strchr(argv[0], '=')) {
1101                 DEBUG(1,("Sharename or path not specified on add\n"));
1102                 return rpc_share_usage(argc, argv);
1103         }
1104         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1105                                rpc_share_add_internals,
1106                                argc, argv);
1107 }
1108
1109 /** 
1110  * Delete a share on a remote RPC server
1111  *
1112  * All parameters are provided by the run_rpc_command function, except for
1113  * argc, argv which are passes through. 
1114  *
1115  * @param domain_sid The domain sid acquired from the remote server
1116  * @param cli A cli_state connected to the server.
1117  * @param mem_ctx Talloc context, destoyed on completion of the function.
1118  * @param argc  Standard main() style argc
1119  * @param argv  Standard main() style argv.  Initial components are already
1120  *              stripped
1121  *
1122  * @return Normal NTSTATUS return.
1123  **/
1124 static NTSTATUS 
1125 rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1126                         TALLOC_CTX *mem_ctx,int argc, const char **argv)
1127 {
1128         WERROR result;
1129
1130         result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
1131         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1132 }
1133
1134 /** 
1135  * Delete a share on a remote RPC server
1136  *
1137  * @param domain_sid The domain sid acquired from the remote server
1138  * @param argc  Standard main() style argc
1139  * @param argv  Standard main() style argv.  Initial components are already
1140  *              stripped
1141  *
1142  * @return A shell status integer (0 for success)
1143  **/
1144 static int rpc_share_delete(int argc, const char **argv)
1145 {
1146         if (argc < 1) {
1147                 DEBUG(1,("Sharename not specified on delete\n"));
1148                 return rpc_share_usage(argc, argv);
1149         }
1150         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1151                                rpc_share_del_internals,
1152                                argc, argv);
1153 }
1154
1155 /**
1156  * Formatted print of share info
1157  *
1158  * @param info1  pointer to SRV_SHARE_INFO_1 to format
1159  **/
1160  
1161 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
1162 {
1163         fstring netname = "", remark = "";
1164
1165         rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
1166         rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
1167
1168         if (opt_long_list_entries) {
1169                 d_printf("%-12.12s %-8.8s %-50.50s\n",
1170                          netname, share_type[info1->info_1.type], remark);
1171         } else {
1172                 d_printf("%-12.12s\n", netname);
1173         }
1174
1175 }
1176
1177 /** 
1178  * List shares on a remote RPC server
1179  *
1180  * All parameters are provided by the run_rpc_command function, except for
1181  * argc, argv which are passes through. 
1182  *
1183  * @param domain_sid The domain sid acquired from the remote server
1184  * @param cli A cli_state connected to the server.
1185  * @param mem_ctx Talloc context, destoyed on completion of the function.
1186  * @param argc  Standard main() style argc
1187  * @param argv  Standard main() style argv.  Initial components are already
1188  *              stripped
1189  *
1190  * @return Normal NTSTATUS return.
1191  **/
1192
1193 static NTSTATUS 
1194 rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1195                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
1196 {
1197         SRV_SHARE_INFO_CTR ctr;
1198         WERROR result;
1199         ENUM_HND hnd;
1200         uint32 preferred_len = 0xffffffff, i;
1201
1202         init_enum_hnd(&hnd, 0);
1203
1204         result = cli_srvsvc_net_share_enum(
1205                 cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
1206
1207         if (!W_ERROR_IS_OK(result))
1208                 goto done;
1209
1210         /* Display results */
1211
1212         if (opt_long_list_entries) {
1213                 d_printf(
1214         "\nEnumerating shared resources (exports) on remote server:\n\n"\
1215         "\nShare name   Type     Description\n"\
1216         "----------   ----     -----------\n");
1217         }
1218         for (i = 0; i < ctr.num_entries; i++)
1219                 display_share_info_1(&ctr.share.info1[i]);
1220  done:
1221         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1222 }
1223
1224 /** 
1225  * 'net rpc share' entrypoint.
1226  * @param argc  Standard main() style argc
1227  * @param argv  Standard main() style argv.  Initial components are already
1228  *              stripped
1229  **/
1230
1231 int net_rpc_share(int argc, const char **argv) 
1232 {
1233         struct functable func[] = {
1234                 {"add", rpc_share_add},
1235                 {"delete", rpc_share_delete},
1236                 {NULL, NULL}
1237         };
1238
1239         if (argc == 0)
1240                 return run_rpc_command(NULL, PI_SRVSVC, 0, 
1241                                        rpc_share_list_internals,
1242                                        argc, argv);
1243
1244         return net_run_function(argc, argv, func, rpc_share_usage);
1245 }
1246
1247 /****************************************************************************/
1248
1249 static int rpc_file_usage(int argc, const char **argv)
1250 {
1251         return net_help_file(argc, argv);
1252 }
1253
1254 /** 
1255  * Close a file on a remote RPC server
1256  *
1257  * All parameters are provided by the run_rpc_command function, except for
1258  * argc, argv which are passes through. 
1259  *
1260  * @param domain_sid The domain sid acquired from the remote server
1261  * @param cli A cli_state connected to the server.
1262  * @param mem_ctx Talloc context, destoyed on completion of the function.
1263  * @param argc  Standard main() style argc
1264  * @param argv  Standard main() style argv.  Initial components are already
1265  *              stripped
1266  *
1267  * @return Normal NTSTATUS return.
1268  **/
1269 static NTSTATUS 
1270 rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1271                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
1272 {
1273         WERROR result;
1274         result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
1275         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1276 }
1277
1278 /** 
1279  * Close a file on a remote RPC server
1280  *
1281  * @param argc  Standard main() style argc
1282  * @param argv  Standard main() style argv.  Initial components are already
1283  *              stripped
1284  *
1285  * @return A shell status integer (0 for success)
1286  **/
1287 static int rpc_file_close(int argc, const char **argv)
1288 {
1289         if (argc < 1) {
1290                 DEBUG(1, ("No fileid given on close\n"));
1291                 return(rpc_file_usage(argc, argv));
1292         }
1293
1294         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1295                                rpc_file_close_internals,
1296                                argc, argv);
1297 }
1298
1299 /** 
1300  * Formatted print of open file info 
1301  *
1302  * @param info3  FILE_INFO_3 contents
1303  * @param str3   strings for FILE_INFO_3
1304  **/
1305
1306 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
1307 {
1308         fstring user = "", path = "";
1309
1310         rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
1311         rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
1312
1313         d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
1314                  info3->id, user, info3->perms, info3->num_locks, path);
1315 }
1316
1317 /** 
1318  * List open files on a remote RPC server
1319  *
1320  * All parameters are provided by the run_rpc_command function, except for
1321  * argc, argv which are passes through. 
1322  *
1323  * @param domain_sid The domain sid acquired from the remote server
1324  * @param cli A cli_state connected to the server.
1325  * @param mem_ctx Talloc context, destoyed on completion of the function.
1326  * @param argc  Standard main() style argc
1327  * @param argv  Standard main() style argv.  Initial components are already
1328  *              stripped
1329  *
1330  * @return Normal NTSTATUS return.
1331  **/
1332
1333 static NTSTATUS 
1334 rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1335                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
1336 {
1337         SRV_FILE_INFO_CTR ctr;
1338         WERROR result;
1339         ENUM_HND hnd;
1340         uint32 preferred_len = 0xffffffff, i;
1341         const char *username=NULL;
1342
1343         init_enum_hnd(&hnd, 0);
1344
1345         /* if argc > 0, must be user command */
1346         if (argc > 0)
1347                 username = smb_xstrdup(argv[0]);
1348                 
1349         result = cli_srvsvc_net_file_enum(
1350                 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
1351
1352         if (!W_ERROR_IS_OK(result))
1353                 goto done;
1354
1355         /* Display results */
1356
1357         d_printf(
1358                  "\nEnumerating open files on remote server:\n\n"\
1359                  "\nFileId  Opened by            Perms  Locks  Path"\
1360                  "\n------  ---------            -----  -----  ---- \n");
1361         for (i = 0; i < ctr.num_entries; i++)
1362                 display_file_info_3(&ctr.file.info3[i].info_3, 
1363                                     &ctr.file.info3[i].info_3_str);
1364  done:
1365         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1366 }
1367
1368
1369 /** 
1370  * List files for a user on a remote RPC server
1371  *
1372  * @param argc  Standard main() style argc
1373  * @param argv  Standard main() style argv.  Initial components are already
1374  *              stripped
1375  *
1376  * @return A shell status integer (0 for success)
1377  **/
1378 static int rpc_file_user(int argc, const char **argv)
1379 {
1380         if (argc < 1) {
1381                 DEBUG(1, ("No username given\n"));
1382                 return(rpc_file_usage(argc, argv));
1383         }
1384
1385         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1386                                rpc_file_list_internals,
1387                                argc, argv);
1388 }
1389
1390
1391 /** 
1392  * 'net rpc file' entrypoint.
1393  * @param argc  Standard main() style argc
1394  * @param argv  Standard main() style argv.  Initial components are already
1395  *              stripped
1396  **/
1397
1398 int net_rpc_file(int argc, const char **argv) 
1399 {
1400         struct functable func[] = {
1401                 {"close", rpc_file_close},
1402                 {"user", rpc_file_user},
1403 #if 0
1404                 {"info", rpc_file_info},
1405 #endif
1406                 {NULL, NULL}
1407         };
1408
1409         if (argc == 0)
1410                 return run_rpc_command(NULL, PI_SRVSVC, 0, 
1411                                        rpc_file_list_internals,
1412                                        argc, argv);
1413
1414         return net_run_function(argc, argv, func, rpc_file_usage);
1415 }
1416
1417 /****************************************************************************/
1418
1419
1420
1421 /** 
1422  * ABORT the shutdown of a remote RPC Server
1423  *
1424  * All parameters are provided by the run_rpc_command function, except for
1425  * argc, argv which are passed through. 
1426  *
1427  * @param domain_sid The domain sid aquired from the remote server
1428  * @param cli A cli_state connected to the server.
1429  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1430  * @param argc  Standard main() style argc
1431  * @param argv  Standard main() style argv.  Initial components are already
1432  *              stripped
1433  *
1434  * @return Normal NTSTATUS return.
1435  **/
1436
1437 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1438                                              int argc, const char **argv) 
1439 {
1440         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1441         
1442         result = cli_reg_abort_shutdown(cli, mem_ctx);
1443         
1444         if (NT_STATUS_IS_OK(result))
1445                 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1446         else
1447                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1448         
1449         return result;
1450 }
1451
1452
1453 /** 
1454  * ABORT the Shut down of a remote RPC server
1455  *
1456  * @param argc  Standard main() style argc
1457  * @param argv  Standard main() style argv.  Initial components are already
1458  *              stripped
1459  *
1460  * @return A shell status integer (0 for success)
1461  **/
1462
1463 static int rpc_shutdown_abort(int argc, const char **argv) 
1464 {
1465         return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_abort_internals,
1466                                argc, argv);
1467 }
1468
1469 /** 
1470  * Shut down a remote RPC Server
1471  *
1472  * All parameters are provided by the run_rpc_command function, except for
1473  * argc, argv which are passes through. 
1474  *
1475  * @param domain_sid The domain sid aquired from the remote server
1476  * @param cli A cli_state connected to the server.
1477  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1478  * @param argc  Standard main() style argc
1479  * @param argc  Standard main() style argv.  Initial components are already
1480  *              stripped
1481  *
1482  * @return Normal NTSTATUS return.
1483  **/
1484
1485 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1486                                        int argc, const char **argv) 
1487 {
1488         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1489         const char *msg = "This machine will be shutdown shortly";
1490         uint32 timeout = 20;
1491 #if 0
1492         poptContext pc;
1493         int rc;
1494
1495         struct poptOption long_options[] = {
1496                 {"message",    'm', POPT_ARG_STRING, &msg},
1497                 {"timeout",    't', POPT_ARG_INT,    &timeout},
1498                 {"reboot",     'r', POPT_ARG_NONE,   &reboot},
1499                 {"force",      'f', POPT_ARG_NONE,   &force},
1500                 { 0, 0, 0, 0}
1501         };
1502
1503         pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
1504                             POPT_CONTEXT_KEEP_FIRST);
1505
1506         rc = poptGetNextOpt(pc);
1507         
1508         if (rc < -1) {
1509                 /* an error occurred during option processing */
1510                 DEBUG(0, ("%s: %s\n",
1511                           poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1512                           poptStrerror(rc)));
1513                 return NT_STATUS_INVALID_PARAMETER;
1514         }
1515 #endif
1516         if (opt_comment) {
1517                 msg = opt_comment;
1518         }
1519         if (opt_timeout) {
1520                 timeout = opt_timeout;
1521         }
1522
1523         /* create an entry */
1524         result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
1525
1526         if (NT_STATUS_IS_OK(result))
1527                 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1528         else
1529                 DEBUG(0,("Shutdown of remote machine failed!\n"));
1530
1531         return result;
1532 }
1533
1534 /** 
1535  * Shut down a remote RPC server
1536  *
1537  * @param argc  Standard main() style argc
1538  * @param argc  Standard main() style argv.  Initial components are already
1539  *              stripped
1540  *
1541  * @return A shell status integer (0 for success)
1542  **/
1543
1544 static int rpc_shutdown(int argc, const char **argv) 
1545 {
1546         return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
1547                                        argc, argv);
1548 }
1549
1550 /***************************************************************************
1551   NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1552   
1553  ***************************************************************************/
1554
1555 /**
1556  * Add interdomain trust account to the RPC server.
1557  * All parameters (except for argc and argv) are passed by run_rpc_command
1558  * function.
1559  *
1560  * @param domain_sid The domain sid acquired from the server
1561  * @param cli A cli_state connected to the server.
1562  * @param mem_ctx Talloc context, destoyed on completion of the function.
1563  * @param argc  Standard main() style argc
1564  * @param argc  Standard main() style argv.  Initial components are already
1565  *              stripped
1566  *
1567  * @return normal NTSTATUS return code
1568  */
1569
1570 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1571                                            int argc, const char **argv) {
1572
1573         POLICY_HND connect_pol, domain_pol, user_pol;
1574         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1575         char *acct_name;
1576         uint16 acb_info;
1577         uint32 unknown, user_rid;
1578
1579         if (argc != 1) {
1580                 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1581                 return NT_STATUS_INVALID_PARAMETER;
1582         }
1583
1584         /* 
1585          * Make valid trusting domain account (ie. uppercased and with '$' appended)
1586          */
1587          
1588         if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1589                 return NT_STATUS_NO_MEMORY;
1590         }
1591
1592         strupper(acct_name);
1593
1594         /* Get samr policy handle */
1595         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1596                                   &connect_pol);
1597         if (!NT_STATUS_IS_OK(result)) {
1598                 goto done;
1599         }
1600         
1601         /* Get domain policy handle */
1602         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1603                                       MAXIMUM_ALLOWED_ACCESS,
1604                                       domain_sid, &domain_pol);
1605         if (!NT_STATUS_IS_OK(result)) {
1606                 goto done;
1607         }
1608
1609         /* Create trusting domain's account */
1610         acb_info = ACB_DOMTRUST;
1611         unknown = 0xe005000b; /* No idea what this is - a permission mask?
1612                                  mimir: yes, most probably it is */
1613
1614         result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1615                                           acct_name, acb_info, unknown,
1616                                           &user_pol, &user_rid);
1617         if (!NT_STATUS_IS_OK(result)) {
1618                 goto done;
1619         }
1620
1621  done:
1622         SAFE_FREE(acct_name);
1623         return result;
1624 }
1625
1626 /**
1627  * Create interdomain trust account for a remote domain.
1628  *
1629  * @param argc standard argc
1630  * @param argv standard argv without initial components
1631  *
1632  * @return Integer status (0 means success)
1633  **/
1634
1635 static int rpc_trustdom_add(int argc, const char **argv)
1636 {
1637         return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
1638                                argc, argv);
1639 }
1640
1641
1642 /**
1643  * Delete interdomain trust account for a remote domain.
1644  *
1645  * @param argc standard argc
1646  * @param argv standard argv without initial components
1647  *
1648  * @return Integer status (0 means success)
1649  **/
1650  
1651 static int rpc_trustdom_del(int argc, const char **argv)
1652 {
1653         d_printf("Sorry, not yet implemented.\n");
1654         return -1;
1655 }
1656
1657  
1658 /**
1659  * Establish trust relationship to a trusting domain.
1660  * Interdomain account must already be created on remote PDC.
1661  *
1662  * @param argc standard argc
1663  * @param argv standard argv without initial components
1664  *
1665  * @return Integer status (0 means success)
1666  **/
1667
1668 static int rpc_trustdom_establish(int argc, const char **argv)
1669 {
1670         struct cli_state *cli;
1671         struct in_addr server_ip;
1672         POLICY_HND connect_hnd;
1673         TALLOC_CTX *mem_ctx;
1674         NTSTATUS nt_status;
1675         DOM_SID domain_sid;
1676         WKS_INFO_100 wks_info;
1677         
1678         char* domain_name;
1679         char* acct_name;
1680         fstring pdc_name;
1681
1682         /*
1683          * Connect to \\server\ipc$ as 'our domain' account with password
1684          */
1685
1686         if (argc != 1) {
1687                 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1688                 return -1;
1689         }
1690
1691         domain_name = smb_xstrdup(argv[0]);
1692         strupper(domain_name);
1693
1694         /* account name used at first is our domain's name with '$' */
1695         asprintf(&acct_name, "%s$", lp_workgroup());
1696         strupper(acct_name);
1697         
1698         /*
1699          * opt_workgroup will be used by connection functions further,
1700          * hence it should be set to remote domain name instead of ours
1701          */
1702         if (opt_workgroup) {
1703                 opt_workgroup = smb_xstrdup(domain_name);
1704         };
1705         
1706         opt_user_name = acct_name;
1707
1708         /* find the domain controller */
1709         if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1710                 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1711                 return -1;
1712         }
1713
1714         /* connect to ipc$ as username/password */
1715         nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1716         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1717
1718                 /* Is it trusting domain account for sure ? */
1719                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1720                         nt_errstr(nt_status)));
1721                 return -1;
1722         }
1723         
1724         /*
1725          * Connect to \\server\ipc$ again (this time anonymously)
1726          */
1727         
1728         nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1729         
1730         if (NT_STATUS_IS_ERR(nt_status)) {
1731                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1732                         domain_name, nt_errstr(nt_status)));
1733         }
1734
1735         /*
1736          * Use NetServerEnum2 to make sure we're talking to a proper server
1737          */
1738          
1739         if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1740                 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1741                          for domain %s\n", domain_name));
1742         }
1743          
1744         /*
1745          * Call WksQueryInfo to check remote server's capabilities
1746          * note: It is now used only to get unicode domain name
1747          */
1748         
1749         if (!cli_nt_session_open(cli, PI_WKSSVC)) {
1750                 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1751                 return -1;
1752         }
1753
1754         if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
1755                         domain_name))) {
1756                 DEBUG(0, ("talloc_init() failed\n"));
1757                 cli_shutdown(cli);
1758                 return -1;
1759         }
1760         
1761         nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1762         
1763         if (NT_STATUS_IS_ERR(nt_status)) {
1764                 DEBUG(0, ("WksQueryInfo call failed.\n"));
1765                 return -1;
1766         }
1767
1768         if (cli->nt_pipe_fnum)
1769                 cli_nt_session_close(cli);
1770
1771
1772         /*
1773          * Call LsaOpenPolicy and LsaQueryInfo
1774          */
1775          
1776         if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
1777                 DEBUG(0, ("talloc_init() failed\n"));
1778                 cli_shutdown(cli);
1779                 return -1;
1780         }
1781
1782         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1783                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1784                 cli_shutdown(cli);
1785                 return -1;
1786         }
1787
1788         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1789                                          &connect_hnd);
1790         if (NT_STATUS_IS_ERR(nt_status)) {
1791                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1792                         nt_errstr(nt_status)));
1793                 return -1;
1794         }
1795
1796         /* Querying info level 5 */
1797         
1798         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1799                                               5 /* info level */, domain_name,
1800                                               &domain_sid);
1801         if (NT_STATUS_IS_ERR(nt_status)) {
1802                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1803                         nt_errstr(nt_status)));
1804                 return -1;
1805         }
1806
1807
1808
1809
1810         /* There should be actually query info level 3 (following nt serv behaviour),
1811            but I still don't know if it's _really_ necessary */
1812                         
1813         /*
1814          * Store the password in secrets db
1815          */
1816
1817         if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1818                                                    wks_info.uni_lan_grp.uni_str_len, opt_password,
1819                                                    domain_sid)) {
1820                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1821                 return -1;
1822         }
1823         
1824         /*
1825          * Close the pipes and clean up
1826          */
1827          
1828         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1829         if (NT_STATUS_IS_ERR(nt_status)) {
1830                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1831                         nt_errstr(nt_status)));
1832                 return -1;
1833         }
1834
1835         if (cli->nt_pipe_fnum)
1836                 cli_nt_session_close(cli);
1837          
1838         talloc_destroy(mem_ctx);
1839          
1840         DEBUG(0, ("Success!\n"));
1841         return 0;
1842 }
1843
1844 /**
1845  * Revoke trust relationship to the remote domain
1846  *
1847  * @param argc standard argc
1848  * @param argv standard argv without initial components
1849  *
1850  * @return Integer status (0 means success)
1851  **/
1852
1853 static int rpc_trustdom_revoke(int argc, const char **argv)
1854 {
1855         char* domain_name;
1856
1857         if (argc < 1) return -1;
1858         
1859         /* generate upper cased domain name */
1860         domain_name = smb_xstrdup(argv[0]);
1861         strupper(domain_name);
1862
1863         /* delete password of the trust */
1864         if (!trusted_domain_password_delete(domain_name)) {
1865                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1866                           domain_name));
1867                 return -1;
1868         };
1869         
1870         return 0;
1871 }
1872
1873 /**
1874  * Usage for 'net rpc trustdom' command
1875  *
1876  * @param argc standard argc
1877  * @param argv standard argv without inital components
1878  *
1879  * @return Integer status returned to shell
1880  **/
1881  
1882 static int rpc_trustdom_usage(int argc, const char **argv)
1883 {
1884         d_printf("  net rpc trustdom add \t\t add trusting domain's account\n");
1885         d_printf("  net rpc trustdom del \t\t delete trusting domain's account\n");
1886         d_printf("  net rpc trustdom establish \t establish relationship to trusted domain\n");
1887         d_printf("  net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1888         d_printf("  net rpc trustdom list \t show current interdomain trust relationships\n");
1889         return -1;
1890 }
1891
1892
1893 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1894                               int argc, const char **argv)
1895 {
1896         fstring str_sid;
1897         sid_to_string(str_sid, domain_sid);
1898         d_printf("%s\n", str_sid);
1899         return NT_STATUS_OK;
1900 };
1901
1902
1903 static int rpc_trustdom_list(int argc, const char **argv)
1904 {
1905         /* common variables */
1906         TALLOC_CTX* mem_ctx;
1907         struct cli_state *cli, *remote_cli;
1908         NTSTATUS nt_status;
1909         const char *domain_name = NULL;
1910         DOM_SID queried_dom_sid;
1911         fstring ascii_sid, padding;
1912         int ascii_dom_name_len;
1913         POLICY_HND connect_hnd;
1914         
1915         /* trusted domains listing variables */
1916         int enum_ctx = 0;
1917         int num_domains, i, pad_len, col_len = 20;
1918         DOM_SID *domain_sids;
1919         char **trusted_dom_names;
1920         fstring pdc_name, dummy;
1921         
1922         /* trusting domains listing variables */
1923         POLICY_HND domain_hnd;
1924         char **trusting_dom_names;
1925         uint32 *trusting_dom_rids;
1926         
1927         /*
1928          * Listing trusted domains (stored in secrets.tdb, if local)
1929          */
1930
1931         mem_ctx = talloc_init("trust relationships listing");
1932
1933         /*
1934          * set domain and pdc name to local samba server (default)
1935          * or to remote one given in command line
1936          */
1937         
1938         if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
1939                 domain_name = opt_workgroup;
1940                 opt_target_workgroup = opt_workgroup;
1941         } else {
1942                 fstrcpy(pdc_name, global_myname());
1943                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1944                 opt_target_workgroup = domain_name;
1945         };
1946
1947         /* open \PIPE\lsarpc and open policy handle */
1948         if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
1949                 DEBUG(0, ("Couldn't connect to domain controller\n"));
1950                 return -1;
1951         };
1952
1953         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1954                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1955                 return -1;
1956         };
1957
1958         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1959                                         &connect_hnd);
1960         if (NT_STATUS_IS_ERR(nt_status)) {
1961                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1962                         nt_errstr(nt_status)));
1963                 return -1;
1964         };
1965         
1966         /* query info level 5 to obtain sid of a domain being queried */
1967         nt_status = cli_lsa_query_info_policy(
1968                 cli, mem_ctx, &connect_hnd, 5 /* info level */, 
1969                 dummy, &queried_dom_sid);
1970
1971         if (NT_STATUS_IS_ERR(nt_status)) {
1972                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1973                         nt_errstr(nt_status)));
1974                 return -1;
1975         }
1976                 
1977         /*
1978          * Keep calling LsaEnumTrustdom over opened pipe until
1979          * the end of enumeration is reached
1980          */
1981          
1982         d_printf("Trusted domains list:\n\n");
1983
1984         do {
1985                 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
1986                                                    &num_domains,
1987                                                    &trusted_dom_names, &domain_sids);
1988                 
1989                 if (NT_STATUS_IS_ERR(nt_status)) {
1990                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
1991                                 nt_errstr(nt_status)));
1992                         return -1;
1993                 };
1994                 
1995                 for (i = 0; i < num_domains; i++) {
1996                         /* convert sid into ascii string */
1997                         sid_to_string(ascii_sid, &(domain_sids[i]));
1998                 
1999                         /* calculate padding space for d_printf to look nicer */
2000                         pad_len = col_len - strlen(trusted_dom_names[i]);
2001                         padding[pad_len] = 0;
2002                         do padding[--pad_len] = ' '; while (pad_len);
2003                         
2004                         d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
2005                 };
2006                 
2007                 /*
2008                  * in case of no trusted domains say something rather
2009                  * than just display blank line
2010                  */
2011                 if (!num_domains) d_printf("none\n");
2012
2013         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2014
2015         /* close this connection before doing next one */
2016         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
2017         if (NT_STATUS_IS_ERR(nt_status)) {
2018                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
2019                         nt_errstr(nt_status)));
2020                 return -1;
2021         };
2022         
2023         cli_nt_session_close(cli);
2024
2025         /*
2026          * Listing trusting domains (stored in passdb backend, if local)
2027          */
2028         
2029         d_printf("\nTrusting domains list:\n\n");
2030
2031         /*
2032          * Open \PIPE\samr and get needed policy handles
2033          */
2034         if (!cli_nt_session_open(cli, PI_SAMR)) {
2035                 DEBUG(0, ("Could not initialise samr pipe\n"));
2036                 return -1;
2037         };
2038         
2039         /* SamrConnect */
2040         nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
2041                                                                  &connect_hnd);
2042         if (!NT_STATUS_IS_OK(nt_status)) {
2043                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
2044                         nt_errstr(nt_status)));
2045                 return -1;
2046         };
2047         
2048         /* SamrOpenDomain - we have to open domain policy handle in order to be
2049            able to enumerate accounts*/
2050         nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
2051                                                                          SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2052                                                                          &queried_dom_sid, &domain_hnd);                                                                         
2053         if (!NT_STATUS_IS_OK(nt_status)) {
2054                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
2055                         nt_errstr(nt_status)));
2056                 return -1;
2057         };
2058         
2059         /*
2060          * perform actual enumeration
2061          */
2062          
2063         enum_ctx = 0;   /* reset enumeration context from last enumeration */
2064         do {
2065                         
2066                 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
2067                                                     &enum_ctx, ACB_DOMTRUST, 0xffff,
2068                                                     &trusting_dom_names, &trusting_dom_rids,
2069                                                     &num_domains);
2070                 if (NT_STATUS_IS_ERR(nt_status)) {
2071                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
2072                                 nt_errstr(nt_status)));
2073                         return -1;
2074                 };
2075                 
2076                 for (i = 0; i < num_domains; i++) {
2077
2078                         /*
2079                          * get each single domain's sid (do we _really_ need this ?):
2080                          *  1) connect to domain's pdc
2081                          *  2) query the pdc for domain's sid
2082                          */
2083
2084                         /* get rid of '$' tail */
2085                         ascii_dom_name_len = strlen(trusting_dom_names[i]);
2086                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
2087                                 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
2088                         
2089                         /* calculate padding space for d_printf to look nicer */
2090                         pad_len = col_len - strlen(trusting_dom_names[i]);
2091                         padding[pad_len] = 0;
2092                         do padding[--pad_len] = ' '; while (pad_len);
2093
2094                         /* set opt_* variables to remote domain */
2095                         strupper(trusting_dom_names[i]);
2096                         opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2097                         opt_target_workgroup = opt_workgroup;
2098                         
2099                         d_printf("%s%s", trusting_dom_names[i], padding);
2100                         
2101                         /* connect to remote domain controller */
2102                         remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2103                         if (remote_cli) {                       
2104                                 /* query for domain's sid */
2105                                 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2106                                         d_printf("couldn't get domain's sid\n");
2107
2108                                 cli_shutdown(remote_cli);
2109                         
2110                         } else {
2111                                 d_printf("domain controller is not responding\n");
2112                         };
2113                 };
2114                 
2115                 if (!num_domains) d_printf("none\n");
2116                 
2117         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2118
2119         /* close opened samr and domain policy handles */
2120         nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2121         if (!NT_STATUS_IS_OK(nt_status)) {
2122                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2123         };
2124         
2125         nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2126         if (!NT_STATUS_IS_OK(nt_status)) {
2127                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2128         };
2129         
2130         /* close samr pipe and connection to IPC$ */
2131         cli_nt_session_close(cli);
2132         cli_shutdown(cli);
2133
2134         talloc_destroy(mem_ctx);         
2135         return 0;
2136 }
2137
2138 /**
2139  * Entrypoint for 'net rpc trustdom' code
2140  *
2141  * @param argc standard argc
2142  * @param argv standard argv without initial components
2143  *
2144  * @return Integer status (0 means success)
2145  */
2146
2147 static int rpc_trustdom(int argc, const char **argv)
2148 {
2149         struct functable func[] = {
2150                 {"add", rpc_trustdom_add},
2151                 {"del", rpc_trustdom_del},
2152                 {"establish", rpc_trustdom_establish},
2153                 {"revoke", rpc_trustdom_revoke},
2154                 {"help", rpc_trustdom_usage},
2155                 {"list", rpc_trustdom_list},
2156                 {NULL, NULL}
2157         };
2158
2159         if (argc == 0) {
2160                 rpc_trustdom_usage(argc, argv);
2161                 return -1;
2162         }
2163
2164         return (net_run_function(argc, argv, func, rpc_user_usage));
2165 }
2166
2167 /**
2168  * Check if a server will take rpc commands
2169  * @param flags Type of server to connect to (PDC, DMB, localhost)
2170  *              if the host is not explicitly specified
2171  * @return  BOOL (true means rpc supported)
2172  */
2173 BOOL net_rpc_check(unsigned flags)
2174 {
2175         struct cli_state cli;
2176         BOOL ret = False;
2177         struct in_addr server_ip;
2178         char *server_name = NULL;
2179
2180         /* flags (i.e. server type) may depend on command */
2181         if (!net_find_server(flags, &server_ip, &server_name))
2182                 return False;
2183
2184         ZERO_STRUCT(cli);
2185         if (cli_initialise(&cli) == False)
2186                 return False;
2187
2188         if (!cli_connect(&cli, server_name, &server_ip))
2189                 goto done;
2190         if (!attempt_netbios_session_request(&cli, global_myname(), 
2191                                              server_name, &server_ip))
2192                 goto done;
2193         if (!cli_negprot(&cli))
2194                 goto done;
2195         if (cli.protocol < PROTOCOL_NT1)
2196                 goto done;
2197
2198         ret = True;
2199  done:
2200         cli_shutdown(&cli);
2201         return ret;
2202 }
2203
2204
2205 /****************************************************************************/
2206
2207
2208 /** 
2209  * Basic usage function for 'net rpc'
2210  * @param argc  Standard main() style argc
2211  * @param argv  Standard main() style argv.  Initial components are already
2212  *              stripped
2213  **/
2214
2215 int net_rpc_usage(int argc, const char **argv) 
2216 {
2217         d_printf("  net rpc info \t\t\tshow basic info about a domain \n");
2218         d_printf("  net rpc join \t\t\tto join a domain \n");
2219         d_printf("  net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n");
2220         d_printf("  net rpc testjoin \t\ttests that a join is valid\n");
2221         d_printf("  net rpc user \t\t\tto add, delete and list users\n");
2222         d_printf("  net rpc group \t\tto list groups\n");
2223         d_printf("  net rpc share \t\tto add, delete, and list shares\n");
2224         d_printf("  net rpc file \t\t\tto list open files\n");
2225         d_printf("  net rpc changetrustpw \tto change the trust account password\n");
2226         d_printf("  net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
2227         d_printf("  net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
2228         d_printf("  net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
2229         d_printf("  net rpc trustdom \t\tto create trusting domain's account\n"
2230                  "\t\t\t\t\tor establish trust\n");
2231         d_printf("  net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2232         d_printf("  net rpc shutdown \t\tto shutdown a remote server\n");
2233         d_printf("\n");
2234         d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2235         d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2236         d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2237         d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2238         d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2239         return -1;
2240 }
2241
2242
2243 /**
2244  * Help function for 'net rpc'.  Calls command specific help if requested
2245  * or displays usage of net rpc
2246  * @param argc  Standard main() style argc
2247  * @param argv  Standard main() style argv.  Initial components are already
2248  *              stripped
2249  **/
2250
2251 int net_rpc_help(int argc, const char **argv)
2252 {
2253         struct functable func[] = {
2254                 {"join", rpc_join_usage},
2255                 {"user", rpc_user_usage},
2256                 {"group", rpc_group_usage},
2257                 {"share", rpc_share_usage},
2258                 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2259                 {"trustdom", rpc_trustdom_usage},
2260                 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2261                 /*{"shutdown", rpc_shutdown_usage}, */
2262                 {NULL, NULL}
2263         };
2264
2265         if (argc == 0) {
2266                 net_rpc_usage(argc, argv);
2267                 return -1;
2268         }
2269
2270         return (net_run_function(argc, argv, func, rpc_user_usage));
2271 }
2272
2273
2274 /** 
2275  * 'net rpc' entrypoint.
2276  * @param argc  Standard main() style argc
2277  * @param argv  Standard main() style argv.  Initial components are already
2278  *              stripped
2279  **/
2280
2281 int net_rpc(int argc, const char **argv)
2282 {
2283         struct functable func[] = {
2284                 {"info", net_rpc_info},
2285                 {"join", net_rpc_join},
2286                 {"oldjoin", net_rpc_oldjoin},
2287                 {"testjoin", net_rpc_testjoin},
2288                 {"user", net_rpc_user},
2289                 {"group", net_rpc_group},
2290                 {"share", net_rpc_share},
2291                 {"file", net_rpc_file},
2292                 {"changetrustpw", net_rpc_changetrustpw},
2293                 {"trustdom", rpc_trustdom},
2294                 {"abortshutdown", rpc_shutdown_abort},
2295                 {"shutdown", rpc_shutdown},
2296                 {"samdump", rpc_samdump},
2297                 {"vampire", rpc_vampire},
2298                 {"getsid", net_rpc_getsid},
2299                 {"help", net_rpc_help},
2300                 {NULL, NULL}
2301         };
2302         return net_run_function(argc, argv, func, net_rpc_usage);
2303 }