r884: convert samba4 to use [u]int32_t instead of [u]int32
[bbaumbach/samba-autobuild/.git] / source4 / 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_t 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, lp_netbios_name());
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(lp_netbios_name(), 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_t 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_t *user_rids, num_rids, *name_types;
607                 uint32_t 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_t *rids, num_rids, *name_types, num_names;
681         uint32_t 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_t *)talloc(mem_ctx, sizeof(uint32_t) * 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_t start_idx=0, num_entries, i, loop_count = 0;
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                 uint32_t max_entries, max_size;
813
814                 get_query_dispinfo_params(
815                         loop_count, &max_entries, &max_size);
816
817                 result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
818                                                  &start_idx, 1, &num_entries,
819                                                  max_entries, max_size, &ctr);
820                 loop_count++;
821
822                 for (i = 0; i < num_entries; i++) {
823                         unistr2_to_ascii(user, &(&ctr.sam.info1->str[i])->uni_acct_name, sizeof(user)-1);
824                         if (opt_long_list_entries) 
825                                 unistr2_to_ascii(desc, &(&ctr.sam.info1->str[i])->uni_acct_desc, sizeof(desc)-1);
826                         
827                         if (opt_long_list_entries)
828                                 printf("%-21.21s %-50.50s\n", user, desc);
829                         else
830                                 printf("%s\n", user);
831                 }
832         } while (!NT_STATUS_IS_OK(result));
833
834  done:
835         return result;
836 }
837
838 /** 
839  * 'net rpc user' entrypoint.
840  * @param argc  Standard main() style argc
841  * @param argc  Standard main() style argv.  Initial components are already
842  *              stripped
843  **/
844
845 int net_rpc_user(int argc, const char **argv) 
846 {
847         struct functable func[] = {
848                 {"add", rpc_user_add},
849                 {"info", rpc_user_info},
850                 {"delete", rpc_user_delete},
851                 {NULL, NULL}
852         };
853         
854         if (argc == 0) {
855                 if (opt_long_list_entries) {
856                 } else {
857                 }
858                         return run_rpc_command(NULL,PI_SAMR, 0, 
859                                                rpc_user_list_internals,
860                                                argc, argv);
861         }
862
863         return net_run_function(argc, argv, func, rpc_user_usage);
864 }
865
866
867 /****************************************************************************/
868
869 /**
870  * Basic usage function for 'net rpc group'
871  * @param argc  Standard main() style argc.
872  * @param argv  Standard main() style argv.  Initial components are already
873  *              stripped.
874  **/
875
876 static int rpc_group_usage(int argc, const char **argv)
877 {
878         return net_help_group(argc, argv);
879 }
880
881 /** 
882  * List groups on a remote RPC server
883  *
884  * All parameters are provided by the run_rpc_command function, except for
885  * argc, argv which are passes through. 
886  *
887  * @param domain_sid The domain sid acquired from the remote server
888  * @param cli A cli_state connected to the server.
889  * @param mem_ctx Talloc context, destoyed on completion of the function.
890  * @param argc  Standard main() style argc
891  * @param argv  Standard main() style argv.  Initial components are already
892  *              stripped
893  *
894  * @return Normal NTSTATUS return.
895  **/
896
897 static NTSTATUS 
898 rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
899                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
900 {
901         POLICY_HND connect_pol, domain_pol;
902         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
903         uint32_t start_idx=0, max_entries=250, num_entries, i;
904         struct acct_info *groups;
905         DOM_SID global_sid_Builtin;
906
907         string_to_sid(&global_sid_Builtin, "S-1-5-32");
908
909         /* Get sam policy handle */
910         
911         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
912                                   &connect_pol);
913         if (!NT_STATUS_IS_OK(result)) {
914                 goto done;
915         }
916         
917         /* Get domain policy handle */
918         
919         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
920                                       MAXIMUM_ALLOWED_ACCESS,
921                                       domain_sid, &domain_pol);
922         if (!NT_STATUS_IS_OK(result)) {
923                 goto done;
924         }
925
926         /* Query domain groups */
927         if (opt_long_list_entries)
928                 d_printf("\nGroup name            Comment"\
929                          "\n-----------------------------\n");
930         do {
931                 result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
932                                                   &start_idx, max_entries,
933                                                   &groups, &num_entries);
934                                                  
935                 for (i = 0; i < num_entries; i++) {
936                         if (opt_long_list_entries)
937                                 printf("%-21.21s %-50.50s\n", 
938                                        groups[i].acct_name,
939                                        groups[i].acct_desc);
940                         else
941                                 printf("%-21.21s\n", groups[i].acct_name);
942                 }
943         } while (!NT_STATUS_IS_OK(result));
944         /* query domain aliases */
945         do {
946                 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
947                                                   &start_idx, max_entries,
948                                                   &groups, &num_entries);
949                                                  
950                 for (i = 0; i < num_entries; i++) {
951                         if (opt_long_list_entries)
952                                 printf("%-21.21s %-50.50s\n", 
953                                        groups[i].acct_name,
954                                        groups[i].acct_desc);
955                         else
956                                 printf("%-21.21s\n", groups[i].acct_name);
957                 }
958         } while (!NT_STATUS_IS_OK(result));
959         cli_samr_close(cli, mem_ctx, &domain_pol);
960         /* Get builtin policy handle */
961         
962         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
963                                       MAXIMUM_ALLOWED_ACCESS,
964                                       &global_sid_Builtin, &domain_pol);
965         if (!NT_STATUS_IS_OK(result)) {
966                 goto done;
967         }
968         /* query builtin aliases */
969         do {
970                 result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
971                                                   &start_idx, max_entries,
972                                                   &groups, &num_entries);
973                                                  
974                 for (i = 0; i < num_entries; i++) {
975                         if (opt_long_list_entries)
976                                 printf("%-21.21s %-50.50s\n", 
977                                        groups[i].acct_name,
978                                        groups[i].acct_desc);
979                         else
980                                 printf("%s\n", groups[i].acct_name);
981                 }
982         } while (!NT_STATUS_IS_OK(result));
983
984  done:
985         return result;
986 }
987
988 /** 
989  * 'net rpc group' entrypoint.
990  * @param argc  Standard main() style argc
991  * @param argc  Standard main() style argv.  Initial components are already
992  *              stripped
993  **/
994
995 int net_rpc_group(int argc, const char **argv) 
996 {
997         struct functable func[] = {
998 #if 0
999                 {"add", rpc_group_add},
1000                 {"delete", rpc_group_delete},
1001 #endif
1002                 {NULL, NULL}
1003         };
1004         
1005         if (argc == 0) {
1006                 if (opt_long_list_entries) {
1007                 } else {
1008                 }
1009                 return run_rpc_command(NULL, PI_SAMR, 0, 
1010                                        rpc_group_list_internals,
1011                                        argc, argv);
1012         }
1013
1014         return net_run_function(argc, argv, func, rpc_group_usage);
1015 }
1016
1017 /****************************************************************************/
1018
1019 static int rpc_share_usage(int argc, const char **argv)
1020 {
1021         return net_help_share(argc, argv);
1022 }
1023
1024 /** 
1025  * Add a share on a remote RPC server
1026  *
1027  * All parameters are provided by the run_rpc_command function, except for
1028  * argc, argv which are passes through. 
1029  *
1030  * @param domain_sid The domain sid acquired from the remote server
1031  * @param cli A cli_state connected to the server.
1032  * @param mem_ctx Talloc context, destoyed on completion of the function.
1033  * @param argc  Standard main() style argc
1034  * @param argv  Standard main() style argv.  Initial components are already
1035  *              stripped
1036  *
1037  * @return Normal NTSTATUS return.
1038  **/
1039 static NTSTATUS 
1040 rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1041                         TALLOC_CTX *mem_ctx,int argc, const char **argv)
1042 {
1043         WERROR result;
1044         char *sharename=talloc_strdup(mem_ctx, argv[0]);
1045         char *path;
1046         uint32_t type=0; /* only allow disk shares to be added */
1047         uint32_t num_users=0, perms=0;
1048         char *password=NULL; /* don't allow a share password */
1049
1050         path = strchr(sharename, '=');
1051         if (!path)
1052                 return NT_STATUS_UNSUCCESSFUL;
1053         *path++ = '\0';
1054
1055         result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
1056                                           opt_comment, perms, opt_maxusers,
1057                                           num_users, path, password);
1058         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1059 }
1060
1061 static int rpc_share_add(int argc, const char **argv)
1062 {
1063         if ((argc < 1) || !strchr(argv[0], '=')) {
1064                 DEBUG(1,("Sharename or path not specified on add\n"));
1065                 return rpc_share_usage(argc, argv);
1066         }
1067         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1068                                rpc_share_add_internals,
1069                                argc, argv);
1070 }
1071
1072 /** 
1073  * Delete a share on a remote RPC server
1074  *
1075  * All parameters are provided by the run_rpc_command function, except for
1076  * argc, argv which are passes through. 
1077  *
1078  * @param domain_sid The domain sid acquired from the remote server
1079  * @param cli A cli_state connected to the server.
1080  * @param mem_ctx Talloc context, destoyed on completion of the function.
1081  * @param argc  Standard main() style argc
1082  * @param argv  Standard main() style argv.  Initial components are already
1083  *              stripped
1084  *
1085  * @return Normal NTSTATUS return.
1086  **/
1087 static NTSTATUS 
1088 rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1089                         TALLOC_CTX *mem_ctx,int argc, const char **argv)
1090 {
1091         WERROR result;
1092
1093         result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
1094         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1095 }
1096
1097 /** 
1098  * Delete a share on a remote RPC server
1099  *
1100  * @param domain_sid The domain sid acquired from the remote server
1101  * @param argc  Standard main() style argc
1102  * @param argv  Standard main() style argv.  Initial components are already
1103  *              stripped
1104  *
1105  * @return A shell status integer (0 for success)
1106  **/
1107 static int rpc_share_delete(int argc, const char **argv)
1108 {
1109         if (argc < 1) {
1110                 DEBUG(1,("Sharename not specified on delete\n"));
1111                 return rpc_share_usage(argc, argv);
1112         }
1113         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1114                                rpc_share_del_internals,
1115                                argc, argv);
1116 }
1117
1118 /**
1119  * Formatted print of share info
1120  *
1121  * @param info1  pointer to SRV_SHARE_INFO_1 to format
1122  **/
1123  
1124 static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
1125 {
1126         fstring netname = "", remark = "";
1127
1128         rpcstr_pull_unistr2_fstring(netname, &info1->info_1_str.uni_netname);
1129         rpcstr_pull_unistr2_fstring(remark, &info1->info_1_str.uni_remark);
1130
1131         if (opt_long_list_entries) {
1132                 d_printf("%-12.12s %-8.8s %-50.50s\n",
1133                          netname, share_type[info1->info_1.type], remark);
1134         } else {
1135                 d_printf("%-12.12s\n", netname);
1136         }
1137
1138 }
1139
1140 /** 
1141  * List shares on a remote RPC server
1142  *
1143  * All parameters are provided by the run_rpc_command function, except for
1144  * argc, argv which are passes through. 
1145  *
1146  * @param domain_sid The domain sid acquired from the remote server
1147  * @param cli A cli_state connected to the server.
1148  * @param mem_ctx Talloc context, destoyed on completion of the function.
1149  * @param argc  Standard main() style argc
1150  * @param argv  Standard main() style argv.  Initial components are already
1151  *              stripped
1152  *
1153  * @return Normal NTSTATUS return.
1154  **/
1155
1156 static NTSTATUS 
1157 rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1158                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
1159 {
1160         SRV_SHARE_INFO_CTR ctr;
1161         WERROR result;
1162         ENUM_HND hnd;
1163         uint32_t preferred_len = 0xffffffff, i;
1164
1165         init_enum_hnd(&hnd, 0);
1166
1167         result = cli_srvsvc_net_share_enum(
1168                 cli, mem_ctx, 1, &ctr, preferred_len, &hnd);
1169
1170         if (!W_ERROR_IS_OK(result))
1171                 goto done;
1172
1173         /* Display results */
1174
1175         if (opt_long_list_entries) {
1176                 d_printf(
1177         "\nEnumerating shared resources (exports) on remote server:\n\n"\
1178         "\nShare name   Type     Description\n"\
1179         "----------   ----     -----------\n");
1180         }
1181         for (i = 0; i < ctr.num_entries; i++)
1182                 display_share_info_1(&ctr.share.info1[i]);
1183  done:
1184         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1185 }
1186
1187 /** 
1188  * 'net rpc share' entrypoint.
1189  * @param argc  Standard main() style argc
1190  * @param argv  Standard main() style argv.  Initial components are already
1191  *              stripped
1192  **/
1193
1194 int net_rpc_share(int argc, const char **argv) 
1195 {
1196         struct functable func[] = {
1197                 {"add", rpc_share_add},
1198                 {"delete", rpc_share_delete},
1199                 {NULL, NULL}
1200         };
1201
1202         if (argc == 0)
1203                 return run_rpc_command(NULL, PI_SRVSVC, 0, 
1204                                        rpc_share_list_internals,
1205                                        argc, argv);
1206
1207         return net_run_function(argc, argv, func, rpc_share_usage);
1208 }
1209
1210 /****************************************************************************/
1211
1212 static int rpc_file_usage(int argc, const char **argv)
1213 {
1214         return net_help_file(argc, argv);
1215 }
1216
1217 /** 
1218  * Close a file on a remote RPC server
1219  *
1220  * All parameters are provided by the run_rpc_command function, except for
1221  * argc, argv which are passes through. 
1222  *
1223  * @param domain_sid The domain sid acquired from the remote server
1224  * @param cli A cli_state connected to the server.
1225  * @param mem_ctx Talloc context, destoyed on completion of the function.
1226  * @param argc  Standard main() style argc
1227  * @param argv  Standard main() style argv.  Initial components are already
1228  *              stripped
1229  *
1230  * @return Normal NTSTATUS return.
1231  **/
1232 static NTSTATUS 
1233 rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1234                          TALLOC_CTX *mem_ctx, int argc, const char **argv)
1235 {
1236         WERROR result;
1237         result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
1238         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1239 }
1240
1241 /** 
1242  * Close a file on a remote RPC server
1243  *
1244  * @param argc  Standard main() style argc
1245  * @param argv  Standard main() style argv.  Initial components are already
1246  *              stripped
1247  *
1248  * @return A shell status integer (0 for success)
1249  **/
1250 static int rpc_file_close(int argc, const char **argv)
1251 {
1252         if (argc < 1) {
1253                 DEBUG(1, ("No fileid given on close\n"));
1254                 return(rpc_file_usage(argc, argv));
1255         }
1256
1257         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1258                                rpc_file_close_internals,
1259                                argc, argv);
1260 }
1261
1262 /** 
1263  * Formatted print of open file info 
1264  *
1265  * @param info3  FILE_INFO_3 contents
1266  * @param str3   strings for FILE_INFO_3
1267  **/
1268
1269 static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
1270 {
1271         fstring user = "", path = "";
1272
1273         rpcstr_pull_unistr2_fstring(user, &str3->uni_user_name);
1274         rpcstr_pull_unistr2_fstring(path, &str3->uni_path_name);
1275
1276         d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
1277                  info3->id, user, info3->perms, info3->num_locks, path);
1278 }
1279
1280 /** 
1281  * List open files on a remote RPC server
1282  *
1283  * All parameters are provided by the run_rpc_command function, except for
1284  * argc, argv which are passes through. 
1285  *
1286  * @param domain_sid The domain sid acquired from the remote server
1287  * @param cli A cli_state connected to the server.
1288  * @param mem_ctx Talloc context, destoyed on completion of the function.
1289  * @param argc  Standard main() style argc
1290  * @param argv  Standard main() style argv.  Initial components are already
1291  *              stripped
1292  *
1293  * @return Normal NTSTATUS return.
1294  **/
1295
1296 static NTSTATUS 
1297 rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
1298                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
1299 {
1300         SRV_FILE_INFO_CTR ctr;
1301         WERROR result;
1302         ENUM_HND hnd;
1303         uint32_t preferred_len = 0xffffffff, i;
1304         const char *username=NULL;
1305
1306         init_enum_hnd(&hnd, 0);
1307
1308         /* if argc > 0, must be user command */
1309         if (argc > 0)
1310                 username = smb_xstrdup(argv[0]);
1311                 
1312         result = cli_srvsvc_net_file_enum(
1313                 cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
1314
1315         if (!W_ERROR_IS_OK(result))
1316                 goto done;
1317
1318         /* Display results */
1319
1320         d_printf(
1321                  "\nEnumerating open files on remote server:\n\n"\
1322                  "\nFileId  Opened by            Perms  Locks  Path"\
1323                  "\n------  ---------            -----  -----  ---- \n");
1324         for (i = 0; i < ctr.num_entries; i++)
1325                 display_file_info_3(&ctr.file.info3[i].info_3, 
1326                                     &ctr.file.info3[i].info_3_str);
1327  done:
1328         return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1329 }
1330
1331
1332 /** 
1333  * List files for a user on a remote RPC server
1334  *
1335  * @param argc  Standard main() style argc
1336  * @param argv  Standard main() style argv.  Initial components are already
1337  *              stripped
1338  *
1339  * @return A shell status integer (0 for success)
1340  **/
1341 static int rpc_file_user(int argc, const char **argv)
1342 {
1343         if (argc < 1) {
1344                 DEBUG(1, ("No username given\n"));
1345                 return(rpc_file_usage(argc, argv));
1346         }
1347
1348         return run_rpc_command(NULL, PI_SRVSVC, 0, 
1349                                rpc_file_list_internals,
1350                                argc, argv);
1351 }
1352
1353
1354 /** 
1355  * 'net rpc file' entrypoint.
1356  * @param argc  Standard main() style argc
1357  * @param argv  Standard main() style argv.  Initial components are already
1358  *              stripped
1359  **/
1360
1361 int net_rpc_file(int argc, const char **argv) 
1362 {
1363         struct functable func[] = {
1364                 {"close", rpc_file_close},
1365                 {"user", rpc_file_user},
1366 #if 0
1367                 {"info", rpc_file_info},
1368 #endif
1369                 {NULL, NULL}
1370         };
1371
1372         if (argc == 0)
1373                 return run_rpc_command(NULL, PI_SRVSVC, 0, 
1374                                        rpc_file_list_internals,
1375                                        argc, argv);
1376
1377         return net_run_function(argc, argv, func, rpc_file_usage);
1378 }
1379
1380 /****************************************************************************/
1381
1382
1383
1384 /** 
1385  * ABORT the shutdown of a remote RPC Server
1386  *
1387  * All parameters are provided by the run_rpc_command function, except for
1388  * argc, argv which are passed through. 
1389  *
1390  * @param domain_sid The domain sid aquired from the remote server
1391  * @param cli A cli_state connected to the server.
1392  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1393  * @param argc  Standard main() style argc
1394  * @param argv  Standard main() style argv.  Initial components are already
1395  *              stripped
1396  *
1397  * @return Normal NTSTATUS return.
1398  **/
1399
1400 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1401                                              int argc, const char **argv) 
1402 {
1403         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1404         
1405         result = cli_reg_abort_shutdown(cli, mem_ctx);
1406         
1407         if (NT_STATUS_IS_OK(result))
1408                 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
1409         else
1410                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
1411         
1412         return result;
1413 }
1414
1415
1416 /** 
1417  * ABORT the Shut down of a remote RPC server
1418  *
1419  * @param argc  Standard main() style argc
1420  * @param argv  Standard main() style argv.  Initial components are already
1421  *              stripped
1422  *
1423  * @return A shell status integer (0 for success)
1424  **/
1425
1426 static int rpc_shutdown_abort(int argc, const char **argv) 
1427 {
1428         return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_abort_internals,
1429                                argc, argv);
1430 }
1431
1432 /** 
1433  * Shut down a remote RPC Server
1434  *
1435  * All parameters are provided by the run_rpc_command function, except for
1436  * argc, argv which are passes through. 
1437  *
1438  * @param domain_sid The domain sid aquired from the remote server
1439  * @param cli A cli_state connected to the server.
1440  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1441  * @param argc  Standard main() style argc
1442  * @param argc  Standard main() style argv.  Initial components are already
1443  *              stripped
1444  *
1445  * @return Normal NTSTATUS return.
1446  **/
1447
1448 static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1449                                        int argc, const char **argv) 
1450 {
1451         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1452         const char *msg = "This machine will be shutdown shortly";
1453         uint32_t timeout = 20;
1454 #if 0
1455         poptContext pc;
1456         int rc;
1457
1458         struct poptOption long_options[] = {
1459                 {"message",    'm', POPT_ARG_STRING, &msg},
1460                 {"timeout",    't', POPT_ARG_INT,    &timeout},
1461                 {"reboot",     'r', POPT_ARG_NONE,   &reboot},
1462                 {"force",      'f', POPT_ARG_NONE,   &force},
1463                 { 0, 0, 0, 0}
1464         };
1465
1466         pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
1467                             POPT_CONTEXT_KEEP_FIRST);
1468
1469         rc = poptGetNextOpt(pc);
1470         
1471         if (rc < -1) {
1472                 /* an error occurred during option processing */
1473                 DEBUG(0, ("%s: %s\n",
1474                           poptBadOption(pc, POPT_BADOPTION_NOALIAS),
1475                           poptStrerror(rc)));
1476                 return NT_STATUS_INVALID_PARAMETER;
1477         }
1478 #endif
1479         if (opt_comment) {
1480                 msg = opt_comment;
1481         }
1482         if (opt_timeout) {
1483                 timeout = opt_timeout;
1484         }
1485
1486         /* create an entry */
1487         result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
1488
1489         if (NT_STATUS_IS_OK(result))
1490                 DEBUG(5,("Shutdown of remote machine succeeded\n"));
1491         else
1492                 DEBUG(0,("Shutdown of remote machine failed!\n"));
1493
1494         return result;
1495 }
1496
1497 /** 
1498  * Shut down a remote RPC server
1499  *
1500  * @param argc  Standard main() style argc
1501  * @param argc  Standard main() style argv.  Initial components are already
1502  *              stripped
1503  *
1504  * @return A shell status integer (0 for success)
1505  **/
1506
1507 static int rpc_shutdown(int argc, const char **argv) 
1508 {
1509         return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
1510                                        argc, argv);
1511 }
1512
1513 /***************************************************************************
1514   NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
1515   
1516  ***************************************************************************/
1517
1518 /**
1519  * Add interdomain trust account to the RPC server.
1520  * All parameters (except for argc and argv) are passed by run_rpc_command
1521  * function.
1522  *
1523  * @param domain_sid The domain sid acquired from the server
1524  * @param cli A cli_state connected to the server.
1525  * @param mem_ctx Talloc context, destoyed on completion of the function.
1526  * @param argc  Standard main() style argc
1527  * @param argc  Standard main() style argv.  Initial components are already
1528  *              stripped
1529  *
1530  * @return normal NTSTATUS return code
1531  */
1532
1533 static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1534                                            int argc, const char **argv) {
1535
1536         POLICY_HND connect_pol, domain_pol, user_pol;
1537         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1538         char *acct_name;
1539         uint16 acb_info;
1540         uint32_t unknown, user_rid;
1541
1542         if (argc != 1) {
1543                 d_printf("Usage: net rpc trustdom add <domain_name>\n");
1544                 return NT_STATUS_INVALID_PARAMETER;
1545         }
1546
1547         /* 
1548          * Make valid trusting domain account (ie. uppercased and with '$' appended)
1549          */
1550          
1551         if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
1552                 return NT_STATUS_NO_MEMORY;
1553         }
1554
1555         strupper(acct_name);
1556
1557         /* Get samr policy handle */
1558         result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
1559                                   &connect_pol);
1560         if (!NT_STATUS_IS_OK(result)) {
1561                 goto done;
1562         }
1563         
1564         /* Get domain policy handle */
1565         result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
1566                                       MAXIMUM_ALLOWED_ACCESS,
1567                                       domain_sid, &domain_pol);
1568         if (!NT_STATUS_IS_OK(result)) {
1569                 goto done;
1570         }
1571
1572         /* Create trusting domain's account */
1573         acb_info = ACB_DOMTRUST;
1574         unknown = 0xe005000b; /* No idea what this is - a permission mask?
1575                                  mimir: yes, most probably it is */
1576
1577         result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
1578                                           acct_name, acb_info, unknown,
1579                                           &user_pol, &user_rid);
1580         if (!NT_STATUS_IS_OK(result)) {
1581                 goto done;
1582         }
1583
1584  done:
1585         SAFE_FREE(acct_name);
1586         return result;
1587 }
1588
1589 /**
1590  * Create interdomain trust account for a remote domain.
1591  *
1592  * @param argc standard argc
1593  * @param argv standard argv without initial components
1594  *
1595  * @return Integer status (0 means success)
1596  **/
1597
1598 static int rpc_trustdom_add(int argc, const char **argv)
1599 {
1600         return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
1601                                argc, argv);
1602 }
1603
1604
1605 /**
1606  * Delete interdomain trust account for a remote domain.
1607  *
1608  * @param argc standard argc
1609  * @param argv standard argv without initial components
1610  *
1611  * @return Integer status (0 means success)
1612  **/
1613  
1614 static int rpc_trustdom_del(int argc, const char **argv)
1615 {
1616         d_printf("Sorry, not yet implemented.\n");
1617         return -1;
1618 }
1619
1620  
1621 /**
1622  * Establish trust relationship to a trusting domain.
1623  * Interdomain account must already be created on remote PDC.
1624  *
1625  * @param argc standard argc
1626  * @param argv standard argv without initial components
1627  *
1628  * @return Integer status (0 means success)
1629  **/
1630
1631 static int rpc_trustdom_establish(int argc, const char **argv)
1632 {
1633         struct cli_state *cli;
1634         struct in_addr server_ip;
1635         POLICY_HND connect_hnd;
1636         TALLOC_CTX *mem_ctx;
1637         NTSTATUS nt_status;
1638         DOM_SID domain_sid;
1639         WKS_INFO_100 wks_info;
1640         
1641         char* domain_name;
1642         char* acct_name;
1643         fstring pdc_name;
1644
1645         /*
1646          * Connect to \\server\ipc$ as 'our domain' account with password
1647          */
1648
1649         if (argc != 1) {
1650                 d_printf("Usage: net rpc trustdom establish <domain_name>\n");
1651                 return -1;
1652         }
1653
1654         domain_name = smb_xstrdup(argv[0]);
1655         strupper(domain_name);
1656
1657         /* account name used at first is our domain's name with '$' */
1658         asprintf(&acct_name, "%s$", lp_workgroup());
1659         strupper(acct_name);
1660         
1661         /*
1662          * opt_workgroup will be used by connection functions further,
1663          * hence it should be set to remote domain name instead of ours
1664          */
1665         if (opt_workgroup) {
1666                 opt_workgroup = smb_xstrdup(domain_name);
1667         };
1668         
1669         opt_user_name = acct_name;
1670
1671         /* find the domain controller */
1672         if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
1673                 DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
1674                 return -1;
1675         }
1676
1677         /* connect to ipc$ as username/password */
1678         nt_status = connect_to_ipc(&cli, &server_ip, pdc_name);
1679         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
1680
1681                 /* Is it trusting domain account for sure ? */
1682                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
1683                         nt_errstr(nt_status)));
1684                 return -1;
1685         }
1686         
1687         /*
1688          * Connect to \\server\ipc$ again (this time anonymously)
1689          */
1690         
1691         nt_status = connect_to_ipc_anonymous(&cli, &server_ip, (char*)pdc_name);
1692         
1693         if (NT_STATUS_IS_ERR(nt_status)) {
1694                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
1695                         domain_name, nt_errstr(nt_status)));
1696         }
1697
1698         /*
1699          * Use NetServerEnum2 to make sure we're talking to a proper server
1700          */
1701          
1702         if (!cli_get_pdc_name(cli, domain_name, (char*)pdc_name)) {
1703                 DEBUG(0, ("NetServerEnum2 error: Couldn't find primary domain controller\
1704                          for domain %s\n", domain_name));
1705         }
1706          
1707         /*
1708          * Call WksQueryInfo to check remote server's capabilities
1709          * note: It is now used only to get unicode domain name
1710          */
1711         
1712         if (!cli_nt_session_open(cli, PI_WKSSVC)) {
1713                 DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
1714                 return -1;
1715         }
1716
1717         if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
1718                         domain_name))) {
1719                 DEBUG(0, ("talloc_init() failed\n"));
1720                 cli_shutdown(cli);
1721                 return -1;
1722         }
1723         
1724         nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
1725         
1726         if (NT_STATUS_IS_ERR(nt_status)) {
1727                 DEBUG(0, ("WksQueryInfo call failed.\n"));
1728                 return -1;
1729         }
1730
1731         if (cli->nt_pipe_fnum)
1732                 cli_nt_session_close(cli);
1733
1734
1735         /*
1736          * Call LsaOpenPolicy and LsaQueryInfo
1737          */
1738          
1739         if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
1740                 DEBUG(0, ("talloc_init() failed\n"));
1741                 cli_shutdown(cli);
1742                 return -1;
1743         }
1744
1745         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1746                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1747                 cli_shutdown(cli);
1748                 return -1;
1749         }
1750
1751         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1752                                          &connect_hnd);
1753         if (NT_STATUS_IS_ERR(nt_status)) {
1754                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1755                         nt_errstr(nt_status)));
1756                 return -1;
1757         }
1758
1759         /* Querying info level 5 */
1760         
1761         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1762                                               5 /* info level */, domain_name,
1763                                               &domain_sid);
1764         if (NT_STATUS_IS_ERR(nt_status)) {
1765                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1766                         nt_errstr(nt_status)));
1767                 return -1;
1768         }
1769
1770
1771
1772
1773         /* There should be actually query info level 3 (following nt serv behaviour),
1774            but I still don't know if it's _really_ necessary */
1775                         
1776         /*
1777          * Store the password in secrets db
1778          */
1779
1780         if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
1781                                                    wks_info.uni_lan_grp.uni_str_len, opt_password,
1782                                                    domain_sid)) {
1783                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
1784                 return -1;
1785         }
1786         
1787         /*
1788          * Close the pipes and clean up
1789          */
1790          
1791         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1792         if (NT_STATUS_IS_ERR(nt_status)) {
1793                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
1794                         nt_errstr(nt_status)));
1795                 return -1;
1796         }
1797
1798         if (cli->nt_pipe_fnum)
1799                 cli_nt_session_close(cli);
1800          
1801         talloc_destroy(mem_ctx);
1802          
1803         DEBUG(0, ("Success!\n"));
1804         return 0;
1805 }
1806
1807 /**
1808  * Revoke trust relationship to the remote domain
1809  *
1810  * @param argc standard argc
1811  * @param argv standard argv without initial components
1812  *
1813  * @return Integer status (0 means success)
1814  **/
1815
1816 static int rpc_trustdom_revoke(int argc, const char **argv)
1817 {
1818         char* domain_name;
1819
1820         if (argc < 1) return -1;
1821         
1822         /* generate upper cased domain name */
1823         domain_name = smb_xstrdup(argv[0]);
1824         strupper(domain_name);
1825
1826         /* delete password of the trust */
1827         if (!trusted_domain_password_delete(domain_name)) {
1828                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
1829                           domain_name));
1830                 return -1;
1831         };
1832         
1833         return 0;
1834 }
1835
1836 /**
1837  * Usage for 'net rpc trustdom' command
1838  *
1839  * @param argc standard argc
1840  * @param argv standard argv without inital components
1841  *
1842  * @return Integer status returned to shell
1843  **/
1844  
1845 static int rpc_trustdom_usage(int argc, const char **argv)
1846 {
1847         d_printf("  net rpc trustdom add \t\t add trusting domain's account\n");
1848         d_printf("  net rpc trustdom del \t\t delete trusting domain's account\n");
1849         d_printf("  net rpc trustdom establish \t establish relationship to trusted domain\n");
1850         d_printf("  net rpc trustdom revoke \t abandon relationship to trusted domain\n");
1851         d_printf("  net rpc trustdom list \t show current interdomain trust relationships\n");
1852         return -1;
1853 }
1854
1855
1856 static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
1857                               int argc, const char **argv)
1858 {
1859         fstring str_sid;
1860         sid_to_string(str_sid, domain_sid);
1861         d_printf("%s\n", str_sid);
1862         return NT_STATUS_OK;
1863 };
1864
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         const 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_t *trusting_dom_rids;
1889         
1890         /*
1891          * Listing trusted domains (stored in secrets.tdb, if local)
1892          */
1893
1894         mem_ctx = talloc_init("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         
1901         if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
1902                 domain_name = opt_workgroup;
1903                 opt_target_workgroup = opt_workgroup;
1904         } else {
1905                 fstrcpy(pdc_name, lp_netbios_name());
1906                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
1907                 opt_target_workgroup = domain_name;
1908         };
1909
1910         /* open \PIPE\lsarpc and open policy handle */
1911         if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
1912                 DEBUG(0, ("Couldn't connect to domain controller\n"));
1913                 return -1;
1914         };
1915
1916         if (!cli_nt_session_open(cli, PI_LSARPC)) {
1917                 DEBUG(0, ("Could not initialise lsa pipe\n"));
1918                 return -1;
1919         };
1920
1921         nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
1922                                         &connect_hnd);
1923         if (NT_STATUS_IS_ERR(nt_status)) {
1924                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
1925                         nt_errstr(nt_status)));
1926                 return -1;
1927         };
1928         
1929         /* query info level 5 to obtain sid of a domain being queried */
1930         nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
1931                                         5 /* info level */, domain_name, &queried_dom_sid);
1932         if (NT_STATUS_IS_ERR(nt_status)) {
1933                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
1934                         nt_errstr(nt_status)));
1935                 return -1;
1936         }
1937                 
1938         /*
1939          * Keep calling LsaEnumTrustdom over opened pipe until
1940          * the end of enumeration is reached
1941          */
1942          
1943         d_printf("Trusted domains list:\n\n");
1944
1945         do {
1946                 nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
1947                                                    &num_domains,
1948                                                    &trusted_dom_names, &domain_sids);
1949                 
1950                 if (NT_STATUS_IS_ERR(nt_status)) {
1951                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
1952                                 nt_errstr(nt_status)));
1953                         return -1;
1954                 };
1955                 
1956                 for (i = 0; i < num_domains; i++) {
1957                         /* convert sid into ascii string */
1958                         sid_to_string(ascii_sid, &(domain_sids[i]));
1959                 
1960                         /* calculate padding space for d_printf to look nicer */
1961                         pad_len = col_len - strlen(trusted_dom_names[i]);
1962                         padding[pad_len] = 0;
1963                         do padding[--pad_len] = ' '; while (pad_len);
1964                         
1965                         d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
1966                 };
1967                 
1968                 /*
1969                  * in case of no trusted domains say something rather
1970                  * than just display blank line
1971                  */
1972                 if (!num_domains) d_printf("none\n");
1973
1974         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
1975
1976         /* close this connection before doing next one */
1977         nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
1978         if (NT_STATUS_IS_ERR(nt_status)) {
1979                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
1980                         nt_errstr(nt_status)));
1981                 return -1;
1982         };
1983         
1984         cli_nt_session_close(cli);
1985
1986         /*
1987          * Listing trusting domains (stored in passdb backend, if local)
1988          */
1989         
1990         d_printf("\nTrusting domains list:\n\n");
1991
1992         /*
1993          * Open \PIPE\samr and get needed policy handles
1994          */
1995         if (!cli_nt_session_open(cli, PI_SAMR)) {
1996                 DEBUG(0, ("Could not initialise samr pipe\n"));
1997                 return -1;
1998         };
1999         
2000         /* SamrConnect */
2001         nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
2002                                                                  &connect_hnd);
2003         if (!NT_STATUS_IS_OK(nt_status)) {
2004                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
2005                         nt_errstr(nt_status)));
2006                 return -1;
2007         };
2008         
2009         /* SamrOpenDomain - we have to open domain policy handle in order to be
2010            able to enumerate accounts*/
2011         nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
2012                                                                          SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
2013                                                                          &queried_dom_sid, &domain_hnd);                                                                         
2014         if (!NT_STATUS_IS_OK(nt_status)) {
2015                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
2016                         nt_errstr(nt_status)));
2017                 return -1;
2018         };
2019         
2020         /*
2021          * perform actual enumeration
2022          */
2023          
2024         enum_ctx = 0;   /* reset enumeration context from last enumeration */
2025         do {
2026                         
2027                 nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
2028                                                     &enum_ctx, ACB_DOMTRUST, 0xffff,
2029                                                     &trusting_dom_names, &trusting_dom_rids,
2030                                                     &num_domains);
2031                 if (NT_STATUS_IS_ERR(nt_status)) {
2032                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
2033                                 nt_errstr(nt_status)));
2034                         return -1;
2035                 };
2036                 
2037                 for (i = 0; i < num_domains; i++) {
2038
2039                         /*
2040                          * get each single domain's sid (do we _really_ need this ?):
2041                          *  1) connect to domain's pdc
2042                          *  2) query the pdc for domain's sid
2043                          */
2044
2045                         /* get rid of '$' tail */
2046                         ascii_dom_name_len = strlen(trusting_dom_names[i]);
2047                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
2048                                 trusting_dom_names[i][ascii_dom_name_len - 1] = '\0';
2049                         
2050                         /* calculate padding space for d_printf to look nicer */
2051                         pad_len = col_len - strlen(trusting_dom_names[i]);
2052                         padding[pad_len] = 0;
2053                         do padding[--pad_len] = ' '; while (pad_len);
2054
2055                         /* set opt_* variables to remote domain */
2056                         strupper(trusting_dom_names[i]);
2057                         opt_workgroup = talloc_strdup(mem_ctx, trusting_dom_names[i]);
2058                         opt_target_workgroup = opt_workgroup;
2059                         
2060                         d_printf("%s%s", trusting_dom_names[i], padding);
2061                         
2062                         /* connect to remote domain controller */
2063                         remote_cli = net_make_ipc_connection(NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS);
2064                         if (remote_cli) {                       
2065                                 /* query for domain's sid */
2066                                 if (run_rpc_command(remote_cli, PI_LSARPC, 0, rpc_query_domain_sid, argc, argv))
2067                                         d_printf("couldn't get domain's sid\n");
2068
2069                                 cli_shutdown(remote_cli);
2070                         
2071                         } else {
2072                                 d_printf("domain controller is not responding\n");
2073                         };
2074                 };
2075                 
2076                 if (!num_domains) d_printf("none\n");
2077                 
2078         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
2079
2080         /* close opened samr and domain policy handles */
2081         nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
2082         if (!NT_STATUS_IS_OK(nt_status)) {
2083                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
2084         };
2085         
2086         nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
2087         if (!NT_STATUS_IS_OK(nt_status)) {
2088                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
2089         };
2090         
2091         /* close samr pipe and connection to IPC$ */
2092         cli_nt_session_close(cli);
2093         cli_shutdown(cli);
2094
2095         talloc_destroy(mem_ctx);         
2096         return 0;
2097 }
2098
2099 /**
2100  * Entrypoint for 'net rpc trustdom' code
2101  *
2102  * @param argc standard argc
2103  * @param argv standard argv without initial components
2104  *
2105  * @return Integer status (0 means success)
2106  */
2107
2108 static int rpc_trustdom(int argc, const char **argv)
2109 {
2110         struct functable func[] = {
2111                 {"add", rpc_trustdom_add},
2112                 {"del", rpc_trustdom_del},
2113                 {"establish", rpc_trustdom_establish},
2114                 {"revoke", rpc_trustdom_revoke},
2115                 {"help", rpc_trustdom_usage},
2116                 {"list", rpc_trustdom_list},
2117                 {NULL, NULL}
2118         };
2119
2120         if (argc == 0) {
2121                 rpc_trustdom_usage(argc, argv);
2122                 return -1;
2123         }
2124
2125         return (net_run_function(argc, argv, func, rpc_user_usage));
2126 }
2127
2128 /**
2129  * Check if a server will take rpc commands
2130  * @param flags Type of server to connect to (PDC, DMB, localhost)
2131  *              if the host is not explicitly specified
2132  * @return  BOOL (true means rpc supported)
2133  */
2134 BOOL net_rpc_check(unsigned flags)
2135 {
2136         struct cli_state cli;
2137         BOOL ret = False;
2138         struct in_addr server_ip;
2139         char *server_name = NULL;
2140
2141         /* flags (i.e. server type) may depend on command */
2142         if (!net_find_server(flags, &server_ip, &server_name))
2143                 return False;
2144
2145         ZERO_STRUCT(cli);
2146         if (cli_initialise(&cli) == False)
2147                 return False;
2148
2149         if (!cli_connect(&cli, server_name, &server_ip))
2150                 goto done;
2151         if (!attempt_netbios_session_request(&cli, lp_netbios_name(), 
2152                                              server_name, &server_ip))
2153                 goto done;
2154         if (!cli_negprot(&cli))
2155                 goto done;
2156         if (cli.protocol < PROTOCOL_NT1)
2157                 goto done;
2158
2159         ret = True;
2160  done:
2161         cli_shutdown(&cli);
2162         return ret;
2163 }
2164
2165
2166 /****************************************************************************/
2167
2168
2169 /** 
2170  * Basic usage function for 'net rpc'
2171  * @param argc  Standard main() style argc
2172  * @param argv  Standard main() style argv.  Initial components are already
2173  *              stripped
2174  **/
2175
2176 int net_rpc_usage(int argc, const char **argv) 
2177 {
2178         d_printf("  net rpc info \t\t\tshow basic info about a domain \n");
2179         d_printf("  net rpc join \t\t\tto join a domain \n");
2180         d_printf("  net rpc testjoin \t\ttests that a join is valid\n");
2181         d_printf("  net rpc user \t\t\tto add, delete and list users\n");
2182         d_printf("  net rpc group \t\tto list groups\n");
2183         d_printf("  net rpc share \t\tto add, delete, and list shares\n");
2184         d_printf("  net rpc file \t\t\tto list open files\n");
2185         d_printf("  net rpc changetrustpw \tto change the trust account password\n");
2186         d_printf("  net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
2187         d_printf("  net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
2188         d_printf("  net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
2189         d_printf("  net rpc trustdom \t\tto create trusting domain's account\n"
2190                  "\t\t\t\t\tor establish trust\n");
2191         d_printf("  net rpc abortshutdown \tto abort the shutdown of a remote server\n");
2192         d_printf("  net rpc shutdown \t\tto shutdown a remote server\n");
2193         d_printf("\n");
2194         d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
2195         d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
2196         d_printf("\t-f or --force\trequest the remote server force its shutdown\n");
2197         d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n");
2198         d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n");
2199         return -1;
2200 }
2201
2202
2203 /**
2204  * Help function for 'net rpc'.  Calls command specific help if requested
2205  * or displays usage of net rpc
2206  * @param argc  Standard main() style argc
2207  * @param argv  Standard main() style argv.  Initial components are already
2208  *              stripped
2209  **/
2210
2211 int net_rpc_help(int argc, const char **argv)
2212 {
2213         struct functable func[] = {
2214                 {"join", rpc_join_usage},
2215                 {"user", rpc_user_usage},
2216                 {"group", rpc_group_usage},
2217                 {"share", rpc_share_usage},
2218                 /*{"changetrustpw", rpc_changetrustpw_usage}, */
2219                 {"trustdom", rpc_trustdom_usage},
2220                 /*{"abortshutdown", rpc_shutdown_abort_usage},*/
2221                 /*{"shutdown", rpc_shutdown_usage}, */
2222                 {NULL, NULL}
2223         };
2224
2225         if (argc == 0) {
2226                 net_rpc_usage(argc, argv);
2227                 return -1;
2228         }
2229
2230         return (net_run_function(argc, argv, func, rpc_user_usage));
2231 }
2232
2233
2234 /** 
2235  * 'net rpc' entrypoint.
2236  * @param argc  Standard main() style argc
2237  * @param argv  Standard main() style argv.  Initial components are already
2238  *              stripped
2239  **/
2240
2241 int net_rpc(int argc, const char **argv)
2242 {
2243         struct functable func[] = {
2244                 {"info", net_rpc_info},
2245                 {"join", net_rpc_join},
2246                 {"testjoin", net_rpc_testjoin},
2247                 {"user", net_rpc_user},
2248                 {"group", net_rpc_group},
2249                 {"share", net_rpc_share},
2250                 {"file", net_rpc_file},
2251                 {"changetrustpw", rpc_changetrustpw},
2252                 {"trustdom", rpc_trustdom},
2253                 {"abortshutdown", rpc_shutdown_abort},
2254                 {"shutdown", rpc_shutdown},
2255                 {"samdump", rpc_samdump},
2256                 {"vampire", rpc_vampire},
2257                 {"getsid", net_rpc_getsid},
2258                 {"help", net_rpc_help},
2259                 {NULL, NULL}
2260         };
2261         return net_run_function(argc, argv, func, net_rpc_usage);
2262 }