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