fix also net rpc shutdown
[samba.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 #if 0
1448         poptContext pc;
1449         int rc;
1450
1451         struct poptOption long_options[] = {
1452                 {"message",    'm', POPT_ARG_STRING, &msg},
1453                 {"timeout",    't', POPT_ARG_INT,    &timeout},
1454                 {"reboot",     'r', POPT_ARG_NONE,   &reboot},
1455                 {"force",      'f', POPT_ARG_NONE,   &force},
1456                 { 0, 0, 0, 0}
1457         };
1458
1459         pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
1460                             POPT_CONTEXT_KEEP_FIRST);
1461
1462         rc = poptGetNextOpt(pc);
1463         
1464         if (rc < -1) {
1465                 /* an error occurred during option processing */
1466                 DEBUG(0, ("%s: %s\n",
1467                           poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1468                           poptStrerror(rc)));
1469                 return NT_STATUS_INVALID_PARAMETER;
1470         }
1471 #endif
1472         if (opt_comment) {
1473                 msg = opt_comment;
1474         }
1475         if (opt_timeout) {
1476                 timeout = opt_timeout;
1477         }
1478
1479         /* create an entry */
1480         result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
1481
1482         if (NT_STATUS_IS_OK(result))
1483                 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1484         else
1485                 DEBUG(0,("Shutdown of remote machine failed!\n"));
1486
1487         return result;
1488 }
1489
1490 /** 
1491  * Shut down a remote RPC server
1492  *
1493  * @param argc  Standard main() style argc
1494  * @param argc  Standard main() style argv.  Initial components are already
1495  *              stripped
1496  *
1497  * @return A shell status integer (0 for success)
1498  **/
1499
1500 static int rpc_shutdown(int argc, const char **argv) 
1501 {
1502         return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
1503                                        argc, argv);
1504 }
1505
1506 /***************************************************************************
1507   NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1508   
1509  ***************************************************************************/
1510
1511 /**
1512  * Add interdomain trust account to the RPC server.
1513  * All parameters (except for argc and argv) are passed by run_rpc_command
1514  * function.
1515  *
1516  * @param domain_sid The domain sid acquired from the server
1517  * @param cli A cli_state connected to the server.
1518  * @param mem_ctx Talloc context, destoyed on completion of the function.
1519  * @param argc  Standard main() style argc
1520  * @param argc  Standard main() style argv.  Initial components are already
1521  *              stripped
1522  *
1523  * @return normal NTSTATUS return code
1524  */
1525
1526 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1527                                            int argc, const char **argv) {
1528
1529         POLICY_HND connect_pol, domain_pol, user_pol;
1530         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1531         char *acct_name;
1532         uint16 acb_info;
1533         uint32 unknown, user_rid;
1534
1535         if (argc != 1) {
1536                 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1537                 return NT_STATUS_INVALID_PARAMETER;
1538         }
1539
1540         /* 
1541          * Make valid trusting domain account (ie. uppercased and with '$' appended)
1542          */
1543          
1544         if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1545                 return NT_STATUS_NO_MEMORY;
1546         }
1547
1548         strupper(acct_name);
1549
1550         /* Get samr policy handle */
1551         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1552                                   &connect_pol);
1553         if (!NT_STATUS_IS_OK(result)) {
1554                 goto done;
1555         }
1556         
1557         /* Get domain policy handle */
1558         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1559                                       MAXIMUM_ALLOWED_ACCESS,
1560                                       domain_sid, &domain_pol);
1561         if (!NT_STATUS_IS_OK(result)) {
1562                 goto done;
1563         }
1564
1565         /* Create trusting domain's account */
1566         acb_info = ACB_DOMTRUST;
1567         unknown = 0xe005000b; /* No idea what this is - a permission mask?
1568                                  mimir: yes, most probably it is */
1569
1570         result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1571                                           acct_name, acb_info, unknown,
1572                                           &user_pol, &user_rid);
1573         if (!NT_STATUS_IS_OK(result)) {
1574                 goto done;
1575         }
1576
1577  done:
1578         SAFE_FREE(acct_name);
1579         return result;
1580 }
1581
1582 /**
1583  * Create interdomain trust account for a remote domain.
1584  *
1585  * @param argc standard argc
1586  * @param argv standard argv without initial components
1587  *
1588  * @return Integer status (0 means success)
1589  **/
1590
1591 static int rpc_trustdom_add(int argc, const char **argv)
1592 {
1593         return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
1594                                argc, argv);
1595 }
1596
1597
1598 /**
1599  * Delete interdomain trust account for a remote domain.
1600  *
1601  * @param argc standard argc
1602  * @param argv standard argv without initial components
1603  *
1604  * @return Integer status (0 means success)
1605  **/
1606  
1607 static int rpc_trustdom_del(int argc, const char **argv)
1608 {
1609         d_printf("Sorry, not yet implemented.\n");
1610         return -1;
1611 }
1612
1613  
1614 /**
1615  * Establish trust relationship to a trusting domain.
1616  * Interdomain account must already be created on remote PDC.
1617  *
1618  * @param argc standard argc
1619  * @param argv standard argv without initial components
1620  *
1621  * @return Integer status (0 means success)
1622  **/
1623
1624 extern char *opt_user_name;
1625 extern char *opt_password;
1626 extern char *opt_workgroup;
1627
1628 static int rpc_trustdom_establish(int argc, const char **argv)
1629 {
1630         struct cli_state *cli;
1631         struct in_addr server_ip;
1632         POLICY_HND connect_hnd;
1633         TALLOC_CTX *mem_ctx;
1634         NTSTATUS nt_status;
1635         DOM_SID domain_sid;
1636         WKS_INFO_100 wks_info;
1637         
1638         char* domain_name;
1639         char* acct_name;
1640         fstring pdc_name;
1641
1642         /*
1643          * Connect to \\server\ipc$ as 'our domain' account with password
1644          */
1645
1646         if (argc != 1) {
1647                 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1648                 return -1;
1649         }
1650
1651         domain_name = smb_xstrdup(argv[0]);
1652         strupper(domain_name);
1653
1654         /* account name used at first is our domain's name with '$' */
1655         asprintf(&acct_name, "%s$", lp_workgroup());
1656         strupper(acct_name);
1657         
1658         /*
1659          * opt_workgroup will be used by connection functions further,
1660          * hence it should be set to remote domain name instead of ours
1661          */
1662         if (opt_workgroup) {
1663                 SAFE_FREE(opt_workgroup);
1664                 opt_workgroup = smb_xstrdup(domain_name);
1665         };
1666         
1667         opt_user_name = acct_name;
1668
1669         /* find the domain controller */
1670         if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1671                 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1672                 return -1;
1673         }
1674
1675         /* connect to ipc$ as username/password */
1676         nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1677         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1678
1679                 /* Is it trusting domain account for sure ? */
1680                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1681                         nt_errstr(nt_status)));
1682                 return -1;
1683         }
1684         
1685         /*
1686          * Connect to \\server\ipc$ again (this time anonymously)
1687          */
1688         
1689         nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1690         
1691         if (NT_STATUS_IS_ERR(nt_status)) {
1692                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1693                         domain_name, nt_errstr(nt_status)));
1694         }
1695
1696         /*
1697          * Use NetServerEnum2 to make sure we're talking to a proper server
1698          */
1699          
1700         if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1701                 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1702                          for domain %s\n", domain_name));
1703         }
1704          
1705         /*
1706          * Call WksQueryInfo to check remote server's capabilities
1707          * note: It is now used only to get unicode domain name
1708          */
1709         
1710         if (!cli_nt_session_open(cli, PI_WKSSVC)) {
1711                 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1712                 return -1;
1713         }
1714
1715         if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
1716                         domain_name))) {
1717                 DEBUG(0, ("talloc_init() failed\n"));
1718                 cli_shutdown(cli);
1719                 return -1;
1720         }
1721         
1722         nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1723         
1724         if (NT_STATUS_IS_ERR(nt_status)) {
1725                 DEBUG(0, ("WksQueryInfo call failed.\n"));
1726                 return -1;
1727         }
1728
1729         if (cli->nt_pipe_fnum)
1730                 cli_nt_session_close(cli);
1731
1732
1733         /*
1734          * Call LsaOpenPolicy and LsaQueryInfo
1735          */
1736          
1737         if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
1738                 DEBUG(0, ("talloc_init() failed\n"));
1739                 cli_shutdown(cli);
1740                 return -1;
1741         }
1742
1743         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1744                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1745                 cli_shutdown(cli);
1746                 return -1;
1747         }
1748
1749         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1750                                          &connect_hnd);
1751         if (NT_STATUS_IS_ERR(nt_status)) {
1752                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1753                         nt_errstr(nt_status)));
1754                 return -1;
1755         }
1756
1757         /* Querying info level 5 */
1758         
1759         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1760                                               5 /* info level */, domain_name,
1761                                               &domain_sid);
1762         if (NT_STATUS_IS_ERR(nt_status)) {
1763                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1764                         nt_errstr(nt_status)));
1765                 return -1;
1766         }
1767
1768
1769
1770
1771         /* There should be actually query info level 3 (following nt serv behaviour),
1772            but I still don't know if it's _really_ necessary */
1773                         
1774         /*
1775          * Store the password in secrets db
1776          */
1777
1778         if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1779                                                    wks_info.uni_lan_grp.uni_str_len, opt_password,
1780                                                    domain_sid)) {
1781                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1782                 return -1;
1783         }
1784         
1785         /*
1786          * Close the pipes and clean up
1787          */
1788          
1789         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1790         if (NT_STATUS_IS_ERR(nt_status)) {
1791                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1792                         nt_errstr(nt_status)));
1793                 return -1;
1794         }
1795
1796         if (cli->nt_pipe_fnum)
1797                 cli_nt_session_close(cli);
1798          
1799         talloc_destroy(mem_ctx);
1800          
1801         DEBUG(0, ("Success!\n"));
1802         return 0;
1803 }
1804
1805 /**
1806  * Revoke trust relationship to the remote domain
1807  *
1808  * @param argc standard argc
1809  * @param argv standard argv without initial components
1810  *
1811  * @return Integer status (0 means success)
1812  **/
1813
1814 static int rpc_trustdom_revoke(int argc, const char **argv)
1815 {
1816         char* domain_name;
1817
1818         if (argc < 1) return -1;
1819         
1820         /* generate upper cased domain name */
1821         domain_name = smb_xstrdup(argv[0]);
1822         strupper(domain_name);
1823
1824         /* delete password of the trust */
1825         if (!trusted_domain_password_delete(domain_name)) {
1826                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1827                           domain_name));
1828                 return -1;
1829         };
1830         
1831         return 0;
1832 }
1833
1834 /**
1835  * Usage for 'net rpc trustdom' command
1836  *
1837  * @param argc standard argc
1838  * @param argv standard argv without inital components
1839  *
1840  * @return Integer status returned to shell
1841  **/
1842  
1843 static int rpc_trustdom_usage(int argc, const char **argv)
1844 {
1845         d_printf("  net rpc trustdom add \t\t add trusting domain's account\n");
1846         d_printf("  net rpc trustdom del \t\t delete trusting domain's account\n");
1847         d_printf("  net rpc trustdom establish \t establish relationship to trusted domain\n");
1848         d_printf("  net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1849         d_printf("  net rpc trustdom list \t show current interdomain trust relationships\n");
1850         return -1;
1851 }
1852
1853
1854 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1855                               int argc, const char **argv)
1856 {
1857         fstring str_sid;
1858         sid_to_string(str_sid, domain_sid);
1859         d_printf("%s\n", str_sid);
1860         return NT_STATUS_OK;
1861 };
1862
1863
1864 extern char* opt_workgroup;
1865 extern char* opt_target_worgroup;
1866 extern char* opt_host;
1867 extern char* opt_password;
1868
1869 static int rpc_trustdom_list(int argc, const char **argv)
1870 {
1871         /* common variables */
1872         TALLOC_CTX* mem_ctx;
1873         struct cli_state *cli, *remote_cli;
1874         NTSTATUS nt_status;
1875         char *domain_name = NULL;
1876         DOM_SID queried_dom_sid;
1877         fstring ascii_sid, padding;
1878         int ascii_dom_name_len;
1879         POLICY_HND connect_hnd;
1880         
1881         /* trusted domains listing variables */
1882         int enum_ctx = 0;
1883         int num_domains, i, pad_len, col_len = 20;
1884         DOM_SID *domain_sids;
1885         char **trusted_dom_names;
1886         fstring pdc_name;
1887         
1888         /* trusting domains listing variables */
1889         POLICY_HND domain_hnd;
1890         char **trusting_dom_names;
1891         uint32 *trusting_dom_rids;
1892         
1893         /*
1894          * Listing trusted domains (stored in secrets.tdb, if local)
1895          */
1896
1897         mem_ctx = talloc_init("trust relationships listing");
1898
1899         /*
1900          * set domain and pdc name to local samba server (default)
1901          * or to remote one given in command line
1902          */
1903         strupper(opt_workgroup);
1904         if (strcmp(opt_workgroup, lp_workgroup())) {
1905                 domain_name = opt_workgroup;
1906                 if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
1907                 opt_target_workgroup = opt_workgroup;
1908         } else {
1909                 safe_strcpy(pdc_name, global_myname(), FSTRING_LEN);
1910                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1911                 if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
1912                 opt_target_workgroup = domain_name;
1913         };
1914
1915         /* open \PIPE\lsarpc and open policy handle */
1916         if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
1917                 DEBUG(0, ("Couldn't connect to domain controller\n"));
1918                 return -1;
1919         };
1920
1921         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1922                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1923                 return -1;
1924         };
1925
1926         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1927                                         &connect_hnd);
1928         if (NT_STATUS_IS_ERR(nt_status)) {
1929                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1930                         nt_errstr(nt_status)));
1931                 return -1;
1932         };
1933         
1934         /* query info level 5 to obtain sid of a domain being queried */
1935         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1936                                         5 /* info level */, domain_name, &queried_dom_sid);
1937         if (NT_STATUS_IS_ERR(nt_status)) {
1938                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1939                         nt_errstr(nt_status)));
1940                 return -1;
1941         }
1942                 
1943         /*
1944          * Keep calling LsaEnumTrustdom over opened pipe until
1945          * the end of enumeration is reached
1946          */
1947          
1948         d_printf("Trusted domains list:\n\n");
1949
1950         do {
1951                 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
1952                                                    &num_domains,
1953                                                    &trusted_dom_names, &domain_sids);
1954                 
1955                 if (NT_STATUS_IS_ERR(nt_status)) {
1956                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
1957                                 nt_errstr(nt_status)));
1958                         return -1;
1959                 };
1960                 
1961                 for (i = 0; i < num_domains; i++) {
1962                         /* convert sid into ascii string */
1963                         sid_to_string(ascii_sid, &(domain_sids[i]));
1964                 
1965                         /* calculate padding space for d_printf to look nicer */
1966                         pad_len = col_len - strlen(trusted_dom_names[i]);
1967                         padding[pad_len] = 0;
1968                         do padding[--pad_len] = ' '; while (pad_len);
1969                         
1970                         d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
1971                 };
1972                 
1973                 /*
1974                  * in case of no trusted domains say something rather
1975                  * than just display blank line
1976                  */
1977                 if (!num_domains) d_printf("none\n");
1978
1979         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
1980
1981         /* close this connection before doing next one */
1982         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1983         if (NT_STATUS_IS_ERR(nt_status)) {
1984                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
1985                         nt_errstr(nt_status)));
1986                 return -1;
1987         };
1988         
1989         cli_nt_session_close(cli);
1990
1991         /*
1992          * Listing trusting domains (stored in passdb backend, if local)
1993          */
1994         
1995         d_printf("\nTrusting domains list:\n\n");
1996
1997         /*
1998          * Open \PIPE\samr and get needed policy handles
1999          */
2000         if (!cli_nt_session_open(cli, PI_SAMR)) {
2001                 DEBUG(0, ("Could not initialise samr pipe\n"));
2002                 return -1;
2003         };
2004         
2005         /* SamrConnect */
2006         nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
2007                                                                  &connect_hnd);
2008         if (!NT_STATUS_IS_OK(nt_status)) {
2009                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
2010                         nt_errstr(nt_status)));
2011                 return -1;
2012         };
2013         
2014         /* SamrOpenDomain - we have to open domain policy handle in order to be
2015            able to enumerate accounts*/
2016         nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
2017                                                                          SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2018                                                                          &queried_dom_sid, &domain_hnd);                                                                         
2019         if (!NT_STATUS_IS_OK(nt_status)) {
2020                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
2021                         nt_errstr(nt_status)));
2022                 return -1;
2023         };
2024         
2025         /*
2026          * perform actual enumeration
2027          */
2028          
2029         enum_ctx = 0;   /* reset enumeration context from last enumeration */
2030         do {
2031                         
2032                 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
2033                                                     &enum_ctx, ACB_DOMTRUST, 0xffff,
2034                                                     &trusting_dom_names, &trusting_dom_rids,
2035                                                     &num_domains);
2036                 if (NT_STATUS_IS_ERR(nt_status)) {
2037                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
2038                                 nt_errstr(nt_status)));
2039                         return -1;
2040                 };
2041                 
2042                 for (i = 0; i < num_domains; i++) {
2043
2044                         /*
2045                          * get each single domain's sid (do we _really_ need this ?):
2046                          *  1) connect to domain's pdc
2047                          *  2) query the pdc for domain's sid
2048                          */
2049
2050                         /* get rid of '$' tail */
2051                         ascii_dom_name_len = strlen(trusting_dom_names[i]);
2052                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
2053                                 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
2054                         
2055                         /* calculate padding space for d_printf to look nicer */
2056                         pad_len = col_len - strlen(trusting_dom_names[i]);
2057                         padding[pad_len] = 0;
2058                         do padding[--pad_len] = ' '; while (pad_len);
2059
2060                         /* set opt_* variables to remote domain */
2061                         strupper(trusting_dom_names[i]);
2062                         opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2063                         if (opt_target_workgroup) SAFE_FREE(opt_target_workgroup);
2064                         opt_target_workgroup = opt_workgroup;
2065                         
2066                         d_printf("%s%s", trusting_dom_names[i], padding);
2067                         
2068                         /* connect to remote domain controller */
2069                         remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2070                         if (remote_cli) {                       
2071                                 /* query for domain's sid */
2072                                 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2073                                         d_printf("couldn't get domain's sid\n");
2074
2075                                 cli_shutdown(remote_cli);
2076                         
2077                         } else {
2078                                 d_printf("domain controller is not responding\n");
2079                         };
2080                 };
2081                 
2082                 if (!num_domains) d_printf("none\n");
2083                 
2084         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2085
2086         /* close opened samr and domain policy handles */
2087         nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2088         if (!NT_STATUS_IS_OK(nt_status)) {
2089                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2090         };
2091         
2092         nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2093         if (!NT_STATUS_IS_OK(nt_status)) {
2094                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2095         };
2096         
2097         /* close samr pipe and connection to IPC$ */
2098         cli_nt_session_close(cli);
2099         cli_shutdown(cli);
2100
2101         talloc_destroy(mem_ctx);         
2102         return 0;
2103 }
2104
2105 /**
2106  * Entrypoint for 'net rpc trustdom' code
2107  *
2108  * @param argc standard argc
2109  * @param argv standard argv without initial components
2110  *
2111  * @return Integer status (0 means success)
2112  */
2113
2114 static int rpc_trustdom(int argc, const char **argv)
2115 {
2116         struct functable func[] = {
2117                 {"add", rpc_trustdom_add},
2118                 {"del", rpc_trustdom_del},
2119                 {"establish", rpc_trustdom_establish},
2120                 {"revoke", rpc_trustdom_revoke},
2121                 {"help", rpc_trustdom_usage},
2122                 {"list", rpc_trustdom_list},
2123                 {NULL, NULL}
2124         };
2125
2126         if (argc == 0) {
2127                 rpc_trustdom_usage(argc, argv);
2128                 return -1;
2129         }
2130
2131         return (net_run_function(argc, argv, func, rpc_user_usage));
2132 }
2133
2134 /**
2135  * Check if a server will take rpc commands
2136  * @param flags Type of server to connect to (PDC, DMB, localhost)
2137  *              if the host is not explicitly specified
2138  * @return  BOOL (true means rpc supported)
2139  */
2140 BOOL net_rpc_check(unsigned flags)
2141 {
2142         struct cli_state cli;
2143         BOOL ret = False;
2144         struct in_addr server_ip;
2145         char *server_name = NULL;
2146
2147         /* flags (i.e. server type) may depend on command */
2148         if (!net_find_server(flags, &server_ip, &server_name))
2149                 return False;
2150
2151         ZERO_STRUCT(cli);
2152         if (cli_initialise(&cli) == False)
2153                 return False;
2154
2155         if (!cli_connect(&cli, server_name, &server_ip))
2156                 goto done;
2157         if (!attempt_netbios_session_request(&cli, global_myname(), 
2158                                              server_name, &server_ip))
2159                 goto done;
2160         if (!cli_negprot(&cli))
2161                 goto done;
2162         if (cli.protocol < PROTOCOL_NT1)
2163                 goto done;
2164
2165         ret = True;
2166  done:
2167         cli_shutdown(&cli);
2168         return ret;
2169 }
2170
2171
2172 /****************************************************************************/
2173
2174
2175 /** 
2176  * Basic usage function for 'net rpc'
2177  * @param argc  Standard main() style argc
2178  * @param argv  Standard main() style argv.  Initial components are already
2179  *              stripped
2180  **/
2181
2182 int net_rpc_usage(int argc, const char **argv) 
2183 {
2184         d_printf("  net rpc info \t\t\tshow basic info about a domain \n");
2185         d_printf("  net rpc join \t\t\tto join a domain \n");
2186         d_printf("  net rpc testjoin \t\ttests that a join is valid\n");
2187         d_printf("  net rpc user \t\t\tto add, delete and list users\n");
2188         d_printf("  net rpc group \t\tto list groups\n");
2189         d_printf("  net rpc share \t\tto add, delete, and list shares\n");
2190         d_printf("  net rpc file \t\t\tto list open files\n");
2191         d_printf("  net rpc changetrustpw \tto change the trust account password\n");
2192         d_printf("  net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
2193         d_printf("  net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
2194         d_printf("  net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
2195         d_printf("  net rpc trustdom \t\tto create trusting domain's account\n"
2196                  "\t\t\t\t\tor establish trust\n");
2197         d_printf("  net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2198         d_printf("  net rpc shutdown \t\tto shutdown a remote server\n");
2199         d_printf("\n");
2200         d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2201         d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2202         d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2203         d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2204         d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2205         return -1;
2206 }
2207
2208
2209 /**
2210  * Help function for 'net rpc'.  Calls command specific help if requested
2211  * or displays usage of net rpc
2212  * @param argc  Standard main() style argc
2213  * @param argv  Standard main() style argv.  Initial components are already
2214  *              stripped
2215  **/
2216
2217 int net_rpc_help(int argc, const char **argv)
2218 {
2219         struct functable func[] = {
2220                 {"join", rpc_join_usage},
2221                 {"user", rpc_user_usage},
2222                 {"group", rpc_group_usage},
2223                 {"share", rpc_share_usage},
2224                 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2225                 {"trustdom", rpc_trustdom_usage},
2226                 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2227                 /*{"shutdown", rpc_shutdown_usage}, */
2228                 {NULL, NULL}
2229         };
2230
2231         if (argc == 0) {
2232                 net_rpc_usage(argc, argv);
2233                 return -1;
2234         }
2235
2236         return (net_run_function(argc, argv, func, rpc_user_usage));
2237 }
2238
2239
2240 /** 
2241  * 'net rpc' entrypoint.
2242  * @param argc  Standard main() style argc
2243  * @param argv  Standard main() style argv.  Initial components are already
2244  *              stripped
2245  **/
2246
2247 int net_rpc(int argc, const char **argv)
2248 {
2249         struct functable func[] = {
2250                 {"info", net_rpc_info},
2251                 {"join", net_rpc_join},
2252                 {"testjoin", net_rpc_testjoin},
2253                 {"user", net_rpc_user},
2254                 {"group", net_rpc_group},
2255                 {"share", net_rpc_share},
2256                 {"file", net_rpc_file},
2257                 {"changetrustpw", rpc_changetrustpw},
2258                 {"trustdom", rpc_trustdom},
2259                 {"abortshutdown", rpc_shutdown_abort},
2260                 {"shutdown", rpc_shutdown},
2261                 {"samdump", rpc_samdump},
2262                 {"vampire", rpc_vampire},
2263                 {"getsid", net_rpc_getsid},
2264                 {"help", net_rpc_help},
2265                 {NULL, NULL}
2266         };
2267         return net_run_function(argc, argv, func, net_rpc_usage);
2268 }