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