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