e0390a1afbb7ed61613fd0d0e2122489250b845c
[kai/samba-autobuild/.git] / source3 / 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         const 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 static int rpc_trustdom_establish(int argc, const char **argv)
1634 {
1635         struct cli_state *cli;
1636         struct in_addr server_ip;
1637         POLICY_HND connect_hnd;
1638         TALLOC_CTX *mem_ctx;
1639         NTSTATUS nt_status;
1640         DOM_SID domain_sid;
1641         WKS_INFO_100 wks_info;
1642         
1643         char* domain_name;
1644         char* acct_name;
1645         fstring pdc_name;
1646
1647         /*
1648          * Connect to \\server\ipc$ as 'our domain' account with password
1649          */
1650
1651         if (argc != 1) {
1652                 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1653                 return -1;
1654         }
1655
1656         domain_name = smb_xstrdup(argv[0]);
1657         strupper(domain_name);
1658
1659         /* account name used at first is our domain's name with '$' */
1660         asprintf(&acct_name, "%s$", lp_workgroup());
1661         strupper(acct_name);
1662         
1663         /*
1664          * opt_workgroup will be used by connection functions further,
1665          * hence it should be set to remote domain name instead of ours
1666          */
1667         if (opt_workgroup) {
1668                 opt_workgroup = smb_xstrdup(domain_name);
1669         };
1670         
1671         opt_user_name = acct_name;
1672
1673         /* find the domain controller */
1674         if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1675                 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1676                 return -1;
1677         }
1678
1679         /* connect to ipc$ as username/password */
1680         nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1681         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1682
1683                 /* Is it trusting domain account for sure ? */
1684                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1685                         nt_errstr(nt_status)));
1686                 return -1;
1687         }
1688         
1689         /*
1690          * Connect to \\server\ipc$ again (this time anonymously)
1691          */
1692         
1693         nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1694         
1695         if (NT_STATUS_IS_ERR(nt_status)) {
1696                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1697                         domain_name, nt_errstr(nt_status)));
1698         }
1699
1700         /*
1701          * Use NetServerEnum2 to make sure we're talking to a proper server
1702          */
1703          
1704         if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1705                 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1706                          for domain %s\n", domain_name));
1707         }
1708          
1709         /*
1710          * Call WksQueryInfo to check remote server's capabilities
1711          * note: It is now used only to get unicode domain name
1712          */
1713         
1714         if (!cli_nt_session_open(cli, PI_WKSSVC)) {
1715                 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1716                 return -1;
1717         }
1718
1719         if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
1720                         domain_name))) {
1721                 DEBUG(0, ("talloc_init() failed\n"));
1722                 cli_shutdown(cli);
1723                 return -1;
1724         }
1725         
1726         nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1727         
1728         if (NT_STATUS_IS_ERR(nt_status)) {
1729                 DEBUG(0, ("WksQueryInfo call failed.\n"));
1730                 return -1;
1731         }
1732
1733         if (cli->nt_pipe_fnum)
1734                 cli_nt_session_close(cli);
1735
1736
1737         /*
1738          * Call LsaOpenPolicy and LsaQueryInfo
1739          */
1740          
1741         if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
1742                 DEBUG(0, ("talloc_init() failed\n"));
1743                 cli_shutdown(cli);
1744                 return -1;
1745         }
1746
1747         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1748                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1749                 cli_shutdown(cli);
1750                 return -1;
1751         }
1752
1753         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1754                                          &connect_hnd);
1755         if (NT_STATUS_IS_ERR(nt_status)) {
1756                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1757                         nt_errstr(nt_status)));
1758                 return -1;
1759         }
1760
1761         /* Querying info level 5 */
1762         
1763         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1764                                               5 /* info level */, domain_name,
1765                                               &domain_sid);
1766         if (NT_STATUS_IS_ERR(nt_status)) {
1767                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1768                         nt_errstr(nt_status)));
1769                 return -1;
1770         }
1771
1772
1773
1774
1775         /* There should be actually query info level 3 (following nt serv behaviour),
1776            but I still don't know if it's _really_ necessary */
1777                         
1778         /*
1779          * Store the password in secrets db
1780          */
1781
1782         if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1783                                                    wks_info.uni_lan_grp.uni_str_len, opt_password,
1784                                                    domain_sid)) {
1785                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1786                 return -1;
1787         }
1788         
1789         /*
1790          * Close the pipes and clean up
1791          */
1792          
1793         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1794         if (NT_STATUS_IS_ERR(nt_status)) {
1795                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1796                         nt_errstr(nt_status)));
1797                 return -1;
1798         }
1799
1800         if (cli->nt_pipe_fnum)
1801                 cli_nt_session_close(cli);
1802          
1803         talloc_destroy(mem_ctx);
1804          
1805         DEBUG(0, ("Success!\n"));
1806         return 0;
1807 }
1808
1809 /**
1810  * Revoke trust relationship to the remote domain
1811  *
1812  * @param argc standard argc
1813  * @param argv standard argv without initial components
1814  *
1815  * @return Integer status (0 means success)
1816  **/
1817
1818 static int rpc_trustdom_revoke(int argc, const char **argv)
1819 {
1820         char* domain_name;
1821
1822         if (argc < 1) return -1;
1823         
1824         /* generate upper cased domain name */
1825         domain_name = smb_xstrdup(argv[0]);
1826         strupper(domain_name);
1827
1828         /* delete password of the trust */
1829         if (!trusted_domain_password_delete(domain_name)) {
1830                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1831                           domain_name));
1832                 return -1;
1833         };
1834         
1835         return 0;
1836 }
1837
1838 /**
1839  * Usage for 'net rpc trustdom' command
1840  *
1841  * @param argc standard argc
1842  * @param argv standard argv without inital components
1843  *
1844  * @return Integer status returned to shell
1845  **/
1846  
1847 static int rpc_trustdom_usage(int argc, const char **argv)
1848 {
1849         d_printf("  net rpc trustdom add \t\t add trusting domain's account\n");
1850         d_printf("  net rpc trustdom del \t\t delete trusting domain's account\n");
1851         d_printf("  net rpc trustdom establish \t establish relationship to trusted domain\n");
1852         d_printf("  net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1853         d_printf("  net rpc trustdom list \t show current interdomain trust relationships\n");
1854         return -1;
1855 }
1856
1857
1858 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1859                               int argc, const char **argv)
1860 {
1861         fstring str_sid;
1862         sid_to_string(str_sid, domain_sid);
1863         d_printf("%s\n", str_sid);
1864         return NT_STATUS_OK;
1865 };
1866
1867
1868 static int rpc_trustdom_list(int argc, const char **argv)
1869 {
1870         /* common variables */
1871         TALLOC_CTX* mem_ctx;
1872         struct cli_state *cli, *remote_cli;
1873         NTSTATUS nt_status;
1874         const char *domain_name = NULL;
1875         DOM_SID queried_dom_sid;
1876         fstring ascii_sid, padding;
1877         int ascii_dom_name_len;
1878         POLICY_HND connect_hnd;
1879         
1880         /* trusted domains listing variables */
1881         int enum_ctx = 0;
1882         int num_domains, i, pad_len, col_len = 20;
1883         DOM_SID *domain_sids;
1884         char **trusted_dom_names;
1885         fstring pdc_name;
1886         
1887         /* trusting domains listing variables */
1888         POLICY_HND domain_hnd;
1889         char **trusting_dom_names;
1890         uint32 *trusting_dom_rids;
1891         
1892         /*
1893          * Listing trusted domains (stored in secrets.tdb, if local)
1894          */
1895
1896         mem_ctx = talloc_init("trust relationships listing");
1897
1898         /*
1899          * set domain and pdc name to local samba server (default)
1900          * or to remote one given in command line
1901          */
1902         
1903         if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
1904                 domain_name = opt_workgroup;
1905                 opt_target_workgroup = opt_workgroup;
1906         } else {
1907                 fstrcpy(pdc_name, global_myname());
1908                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1909                 opt_target_workgroup = domain_name;
1910         };
1911
1912         /* open \PIPE\lsarpc and open policy handle */
1913         if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
1914                 DEBUG(0, ("Couldn't connect to domain controller\n"));
1915                 return -1;
1916         };
1917
1918         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1919                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1920                 return -1;
1921         };
1922
1923         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1924                                         &connect_hnd);
1925         if (NT_STATUS_IS_ERR(nt_status)) {
1926                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1927                         nt_errstr(nt_status)));
1928                 return -1;
1929         };
1930         
1931         /* query info level 5 to obtain sid of a domain being queried */
1932         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1933                                         5 /* info level */, domain_name, &queried_dom_sid);
1934         if (NT_STATUS_IS_ERR(nt_status)) {
1935                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1936                         nt_errstr(nt_status)));
1937                 return -1;
1938         }
1939                 
1940         /*
1941          * Keep calling LsaEnumTrustdom over opened pipe until
1942          * the end of enumeration is reached
1943          */
1944          
1945         d_printf("Trusted domains list:\n\n");
1946
1947         do {
1948                 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
1949                                                    &num_domains,
1950                                                    &trusted_dom_names, &domain_sids);
1951                 
1952                 if (NT_STATUS_IS_ERR(nt_status)) {
1953                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
1954                                 nt_errstr(nt_status)));
1955                         return -1;
1956                 };
1957                 
1958                 for (i = 0; i < num_domains; i++) {
1959                         /* convert sid into ascii string */
1960                         sid_to_string(ascii_sid, &(domain_sids[i]));
1961                 
1962                         /* calculate padding space for d_printf to look nicer */
1963                         pad_len = col_len - strlen(trusted_dom_names[i]);
1964                         padding[pad_len] = 0;
1965                         do padding[--pad_len] = ' '; while (pad_len);
1966                         
1967                         d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
1968                 };
1969                 
1970                 /*
1971                  * in case of no trusted domains say something rather
1972                  * than just display blank line
1973                  */
1974                 if (!num_domains) d_printf("none\n");
1975
1976         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
1977
1978         /* close this connection before doing next one */
1979         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1980         if (NT_STATUS_IS_ERR(nt_status)) {
1981                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
1982                         nt_errstr(nt_status)));
1983                 return -1;
1984         };
1985         
1986         cli_nt_session_close(cli);
1987
1988         /*
1989          * Listing trusting domains (stored in passdb backend, if local)
1990          */
1991         
1992         d_printf("\nTrusting domains list:\n\n");
1993
1994         /*
1995          * Open \PIPE\samr and get needed policy handles
1996          */
1997         if (!cli_nt_session_open(cli, PI_SAMR)) {
1998                 DEBUG(0, ("Could not initialise samr pipe\n"));
1999                 return -1;
2000         };
2001         
2002         /* SamrConnect */
2003         nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
2004                                                                  &connect_hnd);
2005         if (!NT_STATUS_IS_OK(nt_status)) {
2006                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
2007                         nt_errstr(nt_status)));
2008                 return -1;
2009         };
2010         
2011         /* SamrOpenDomain - we have to open domain policy handle in order to be
2012            able to enumerate accounts*/
2013         nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
2014                                                                          SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2015                                                                          &queried_dom_sid, &domain_hnd);                                                                         
2016         if (!NT_STATUS_IS_OK(nt_status)) {
2017                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
2018                         nt_errstr(nt_status)));
2019                 return -1;
2020         };
2021         
2022         /*
2023          * perform actual enumeration
2024          */
2025          
2026         enum_ctx = 0;   /* reset enumeration context from last enumeration */
2027         do {
2028                         
2029                 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
2030                                                     &enum_ctx, ACB_DOMTRUST, 0xffff,
2031                                                     &trusting_dom_names, &trusting_dom_rids,
2032                                                     &num_domains);
2033                 if (NT_STATUS_IS_ERR(nt_status)) {
2034                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
2035                                 nt_errstr(nt_status)));
2036                         return -1;
2037                 };
2038                 
2039                 for (i = 0; i < num_domains; i++) {
2040
2041                         /*
2042                          * get each single domain's sid (do we _really_ need this ?):
2043                          *  1) connect to domain's pdc
2044                          *  2) query the pdc for domain's sid
2045                          */
2046
2047                         /* get rid of '$' tail */
2048                         ascii_dom_name_len = strlen(trusting_dom_names[i]);
2049                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
2050                                 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
2051                         
2052                         /* calculate padding space for d_printf to look nicer */
2053                         pad_len = col_len - strlen(trusting_dom_names[i]);
2054                         padding[pad_len] = 0;
2055                         do padding[--pad_len] = ' '; while (pad_len);
2056
2057                         /* set opt_* variables to remote domain */
2058                         strupper(trusting_dom_names[i]);
2059                         opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2060                         opt_target_workgroup = opt_workgroup;
2061                         
2062                         d_printf("%s%s", trusting_dom_names[i], padding);
2063                         
2064                         /* connect to remote domain controller */
2065                         remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2066                         if (remote_cli) {                       
2067                                 /* query for domain's sid */
2068                                 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2069                                         d_printf("couldn't get domain's sid\n");
2070
2071                                 cli_shutdown(remote_cli);
2072                         
2073                         } else {
2074                                 d_printf("domain controller is not responding\n");
2075                         };
2076                 };
2077                 
2078                 if (!num_domains) d_printf("none\n");
2079                 
2080         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2081
2082         /* close opened samr and domain policy handles */
2083         nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2084         if (!NT_STATUS_IS_OK(nt_status)) {
2085                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2086         };
2087         
2088         nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2089         if (!NT_STATUS_IS_OK(nt_status)) {
2090                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2091         };
2092         
2093         /* close samr pipe and connection to IPC$ */
2094         cli_nt_session_close(cli);
2095         cli_shutdown(cli);
2096
2097         talloc_destroy(mem_ctx);         
2098         return 0;
2099 }
2100
2101 /**
2102  * Entrypoint for 'net rpc trustdom' code
2103  *
2104  * @param argc standard argc
2105  * @param argv standard argv without initial components
2106  *
2107  * @return Integer status (0 means success)
2108  */
2109
2110 static int rpc_trustdom(int argc, const char **argv)
2111 {
2112         struct functable func[] = {
2113                 {"add", rpc_trustdom_add},
2114                 {"del", rpc_trustdom_del},
2115                 {"establish", rpc_trustdom_establish},
2116                 {"revoke", rpc_trustdom_revoke},
2117                 {"help", rpc_trustdom_usage},
2118                 {"list", rpc_trustdom_list},
2119                 {NULL, NULL}
2120         };
2121
2122         if (argc == 0) {
2123                 rpc_trustdom_usage(argc, argv);
2124                 return -1;
2125         }
2126
2127         return (net_run_function(argc, argv, func, rpc_user_usage));
2128 }
2129
2130 /**
2131  * Check if a server will take rpc commands
2132  * @param flags Type of server to connect to (PDC, DMB, localhost)
2133  *              if the host is not explicitly specified
2134  * @return  BOOL (true means rpc supported)
2135  */
2136 BOOL net_rpc_check(unsigned flags)
2137 {
2138         struct cli_state cli;
2139         BOOL ret = False;
2140         struct in_addr server_ip;
2141         char *server_name = NULL;
2142
2143         /* flags (i.e. server type) may depend on command */
2144         if (!net_find_server(flags, &server_ip, &server_name))
2145                 return False;
2146
2147         ZERO_STRUCT(cli);
2148         if (cli_initialise(&cli) == False)
2149                 return False;
2150
2151         if (!cli_connect(&cli, server_name, &server_ip))
2152                 goto done;
2153         if (!attempt_netbios_session_request(&cli, global_myname(), 
2154                                              server_name, &server_ip))
2155                 goto done;
2156         if (!cli_negprot(&cli))
2157                 goto done;
2158         if (cli.protocol < PROTOCOL_NT1)
2159                 goto done;
2160
2161         ret = True;
2162  done:
2163         cli_shutdown(&cli);
2164         return ret;
2165 }
2166
2167
2168 /****************************************************************************/
2169
2170
2171 /** 
2172  * Basic usage function for 'net rpc'
2173  * @param argc  Standard main() style argc
2174  * @param argv  Standard main() style argv.  Initial components are already
2175  *              stripped
2176  **/
2177
2178 int net_rpc_usage(int argc, const char **argv) 
2179 {
2180         d_printf("  net rpc info \t\t\tshow basic info about a domain \n");
2181         d_printf("  net rpc join \t\t\tto join a domain \n");
2182         d_printf("  net rpc testjoin \t\ttests that a join is valid\n");
2183         d_printf("  net rpc user \t\t\tto add, delete and list users\n");
2184         d_printf("  net rpc group \t\tto list groups\n");
2185         d_printf("  net rpc share \t\tto add, delete, and list shares\n");
2186         d_printf("  net rpc file \t\t\tto list open files\n");
2187         d_printf("  net rpc changetrustpw \tto change the trust account password\n");
2188         d_printf("  net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
2189         d_printf("  net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
2190         d_printf("  net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
2191         d_printf("  net rpc trustdom \t\tto create trusting domain's account\n"
2192                  "\t\t\t\t\tor establish trust\n");
2193         d_printf("  net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2194         d_printf("  net rpc shutdown \t\tto shutdown a remote server\n");
2195         d_printf("\n");
2196         d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2197         d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2198         d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2199         d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2200         d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2201         return -1;
2202 }
2203
2204
2205 /**
2206  * Help function for 'net rpc'.  Calls command specific help if requested
2207  * or displays usage of net rpc
2208  * @param argc  Standard main() style argc
2209  * @param argv  Standard main() style argv.  Initial components are already
2210  *              stripped
2211  **/
2212
2213 int net_rpc_help(int argc, const char **argv)
2214 {
2215         struct functable func[] = {
2216                 {"join", rpc_join_usage},
2217                 {"user", rpc_user_usage},
2218                 {"group", rpc_group_usage},
2219                 {"share", rpc_share_usage},
2220                 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2221                 {"trustdom", rpc_trustdom_usage},
2222                 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2223                 /*{"shutdown", rpc_shutdown_usage}, */
2224                 {NULL, NULL}
2225         };
2226
2227         if (argc == 0) {
2228                 net_rpc_usage(argc, argv);
2229                 return -1;
2230         }
2231
2232         return (net_run_function(argc, argv, func, rpc_user_usage));
2233 }
2234
2235
2236 /** 
2237  * 'net rpc' entrypoint.
2238  * @param argc  Standard main() style argc
2239  * @param argv  Standard main() style argv.  Initial components are already
2240  *              stripped
2241  **/
2242
2243 int net_rpc(int argc, const char **argv)
2244 {
2245         struct functable func[] = {
2246                 {"info", net_rpc_info},
2247                 {"join", net_rpc_join},
2248                 {"testjoin", net_rpc_testjoin},
2249                 {"user", net_rpc_user},
2250                 {"group", net_rpc_group},
2251                 {"share", net_rpc_share},
2252                 {"file", net_rpc_file},
2253                 {"changetrustpw", rpc_changetrustpw},
2254                 {"trustdom", rpc_trustdom},
2255                 {"abortshutdown", rpc_shutdown_abort},
2256                 {"shutdown", rpc_shutdown},
2257                 {"samdump", rpc_samdump},
2258                 {"vampire", rpc_vampire},
2259                 {"getsid", net_rpc_getsid},
2260                 {"help", net_rpc_help},
2261                 {NULL, NULL}
2262         };
2263         return net_run_function(argc, argv, func, net_rpc_usage);
2264 }