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