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