s3-net: Use wbcSidToStringBuf
[mat/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    Copyright (C) 2004,2008 Guenther Deschner (gd@samba.org)
7    Copyright (C) 2005 Jeremy Allison (jra@samba.org)
8    Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org)
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
23 #include "includes.h"
24 #include "utils/net.h"
25 #include "rpc_client/cli_pipe.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/cli_samr.h"
29 #include "rpc_client/init_samr.h"
30 #include "../librpc/gen_ndr/ndr_lsa_c.h"
31 #include "rpc_client/cli_lsarpc.h"
32 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
33 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
34 #include "../librpc/gen_ndr/ndr_spoolss.h"
35 #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
36 #include "../librpc/gen_ndr/ndr_winreg_c.h"
37 #include "secrets.h"
38 #include "lib/netapi/netapi.h"
39 #include "lib/netapi/netapi_net.h"
40 #include "rpc_client/init_lsa.h"
41 #include "../libcli/security/security.h"
42
43 static int net_mode_share;
44 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask);
45
46 /**
47  * @file net_rpc.c
48  *
49  * @brief RPC based subcommands for the 'net' utility.
50  *
51  * This file should contain much of the functionality that used to
52  * be found in rpcclient, execpt that the commands should change
53  * less often, and the fucntionality should be sane (the user is not
54  * expected to know a rid/sid before they conduct an operation etc.)
55  *
56  * @todo Perhaps eventually these should be split out into a number
57  * of files, as this could get quite big.
58  **/
59
60
61 /**
62  * Many of the RPC functions need the domain sid.  This function gets
63  *  it at the start of every run
64  *
65  * @param cli A cli_state already connected to the remote machine
66  *
67  * @return The Domain SID of the remote machine.
68  **/
69
70 NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
71                                    struct dom_sid **domain_sid,
72                                    const char **domain_name)
73 {
74         struct rpc_pipe_client *lsa_pipe = NULL;
75         struct policy_handle pol;
76         NTSTATUS status, result;
77         union lsa_PolicyInformation *info = NULL;
78         struct dcerpc_binding_handle *b;
79
80         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
81                                           &lsa_pipe);
82         if (!NT_STATUS_IS_OK(status)) {
83                 d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
84                 return status;
85         }
86
87         b = lsa_pipe->binding_handle;
88
89         status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, false,
90                                      SEC_FLAG_MAXIMUM_ALLOWED,
91                                      &pol);
92         if (!NT_STATUS_IS_OK(status)) {
93                 d_fprintf(stderr, "open_policy %s: %s\n",
94                           _("failed"),
95                           nt_errstr(status));
96                 return status;
97         }
98
99         status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
100                                             &pol,
101                                             LSA_POLICY_INFO_ACCOUNT_DOMAIN,
102                                             &info,
103                                             &result);
104         if (!NT_STATUS_IS_OK(status)) {
105                 d_fprintf(stderr, "lsaquery %s: %s\n",
106                           _("failed"),
107                           nt_errstr(status));
108                 return status;
109         }
110         if (!NT_STATUS_IS_OK(result)) {
111                 d_fprintf(stderr, "lsaquery %s: %s\n",
112                           _("failed"),
113                           nt_errstr(result));
114                 return result;
115         }
116
117         *domain_name = info->account_domain.name.string;
118         *domain_sid = info->account_domain.sid;
119
120         dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
121         TALLOC_FREE(lsa_pipe);
122
123         return NT_STATUS_OK;
124 }
125
126 /**
127  * Run a single RPC command, from start to finish.
128  *
129  * @param pipe_name the pipe to connect to (usually a PIPE_ constant)
130  * @param conn_flag a NET_FLAG_ combination.  Passed to
131  *                   net_make_ipc_connection.
132  * @param argc  Standard main() style argc.
133  * @param argv  Standard main() style argv. Initial components are already
134  *              stripped.
135  * @return A shell status integer (0 for success).
136  */
137
138 int run_rpc_command(struct net_context *c,
139                         struct cli_state *cli_arg,
140                         const struct ndr_syntax_id *interface,
141                         int conn_flags,
142                         rpc_command_fn fn,
143                         int argc,
144                         const char **argv)
145 {
146         struct cli_state *cli = NULL;
147         struct rpc_pipe_client *pipe_hnd = NULL;
148         TALLOC_CTX *mem_ctx;
149         NTSTATUS nt_status;
150         struct dom_sid *domain_sid;
151         const char *domain_name;
152         int ret = -1;
153
154         /* make use of cli_state handed over as an argument, if possible */
155         if (!cli_arg) {
156                 nt_status = net_make_ipc_connection(c, conn_flags, &cli);
157                 if (!NT_STATUS_IS_OK(nt_status)) {
158                         DEBUG(1, ("failed to make ipc connection: %s\n",
159                                   nt_errstr(nt_status)));
160                         return -1;
161                 }
162         } else {
163                 cli = cli_arg;
164         }
165
166         if (!cli) {
167                 return -1;
168         }
169
170         /* Create mem_ctx */
171
172         if (!(mem_ctx = talloc_init("run_rpc_command"))) {
173                 DEBUG(0, ("talloc_init() failed\n"));
174                 goto fail;
175         }
176
177         nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
178                                               &domain_name);
179         if (!NT_STATUS_IS_OK(nt_status)) {
180                 goto fail;
181         }
182
183         if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
184                 if (lp_client_schannel()
185                     && (ndr_syntax_id_equal(interface,
186                                             &ndr_table_netlogon.syntax_id))) {
187                         /* Always try and create an schannel netlogon pipe. */
188                         nt_status = cli_rpc_pipe_open_schannel(
189                                 cli, interface, NCACN_NP,
190                                 DCERPC_AUTH_LEVEL_PRIVACY, domain_name,
191                                 &pipe_hnd);
192                         if (!NT_STATUS_IS_OK(nt_status)) {
193                                 DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
194                                         nt_errstr(nt_status) ));
195                                 goto fail;
196                         }
197                 } else {
198                         if (conn_flags & NET_FLAGS_SEAL) {
199                                 nt_status = cli_rpc_pipe_open_ntlmssp(
200                                         cli, interface,
201                                         (conn_flags & NET_FLAGS_TCP) ?
202                                         NCACN_IP_TCP : NCACN_NP,
203                                         DCERPC_AUTH_LEVEL_PRIVACY,
204                                         lp_workgroup(), c->opt_user_name,
205                                         c->opt_password, &pipe_hnd);
206                         } else {
207                                 nt_status = cli_rpc_pipe_open_noauth(
208                                         cli, interface,
209                                         &pipe_hnd);
210                         }
211                         if (!NT_STATUS_IS_OK(nt_status)) {
212                                 DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
213                                           get_pipe_name_from_syntax(
214                                                   talloc_tos(), interface),
215                                         nt_errstr(nt_status) ));
216                                 goto fail;
217                         }
218                 }
219         }
220
221         nt_status = fn(c, domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
222
223         if (!NT_STATUS_IS_OK(nt_status)) {
224                 DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
225         } else {
226                 ret = 0;
227                 DEBUG(5, ("rpc command function succedded\n"));
228         }
229
230         if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
231                 if (pipe_hnd) {
232                         TALLOC_FREE(pipe_hnd);
233                 }
234         }
235
236 fail:
237         /* close the connection only if it was opened here */
238         if (!cli_arg) {
239                 cli_shutdown(cli);
240         }
241
242         talloc_destroy(mem_ctx);
243         return ret;
244 }
245
246 /**
247  * Force a change of the trust acccount password.
248  *
249  * All parameters are provided by the run_rpc_command function, except for
250  * argc, argv which are passed through.
251  *
252  * @param domain_sid The domain sid acquired from the remote server.
253  * @param cli A cli_state connected to the server.
254  * @param mem_ctx Talloc context, destroyed on completion of the function.
255  * @param argc  Standard main() style argc.
256  * @param argv  Standard main() style argv. Initial components are already
257  *              stripped.
258  *
259  * @return Normal NTSTATUS return.
260  **/
261
262 static NTSTATUS rpc_changetrustpw_internals(struct net_context *c,
263                                         const struct dom_sid *domain_sid,
264                                         const char *domain_name,
265                                         struct cli_state *cli,
266                                         struct rpc_pipe_client *pipe_hnd,
267                                         TALLOC_CTX *mem_ctx,
268                                         int argc,
269                                         const char **argv)
270 {
271         NTSTATUS status;
272
273         status = trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup);
274         if (!NT_STATUS_IS_OK(status)) {
275                 d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
276                         nt_errstr(status));
277                 return status;
278         }
279
280         return NT_STATUS_OK;
281 }
282
283 /**
284  * Force a change of the trust acccount password.
285  *
286  * @param argc  Standard main() style argc.
287  * @param argv  Standard main() style argv. Initial components are already
288  *              stripped.
289  *
290  * @return A shell status integer (0 for success).
291  **/
292
293 int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv)
294 {
295         if (c->display_usage) {
296                 d_printf(  "%s\n"
297                            "net rpc changetrustpw\n"
298                            "    %s\n",
299                          _("Usage:"),
300                          _("Change the machine trust password"));
301                 return 0;
302         }
303
304         return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
305                                NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
306                                rpc_changetrustpw_internals,
307                                argc, argv);
308 }
309
310 /**
311  * Join a domain, the old way.
312  *
313  * This uses 'machinename' as the inital password, and changes it.
314  *
315  * The password should be created with 'server manager' or equiv first.
316  *
317  * All parameters are provided by the run_rpc_command function, except for
318  * argc, argv which are passed through.
319  *
320  * @param domain_sid The domain sid acquired from the remote server.
321  * @param cli A cli_state connected to the server.
322  * @param mem_ctx Talloc context, destroyed on completion of the function.
323  * @param argc  Standard main() style argc.
324  * @param argv  Standard main() style argv. Initial components are already
325  *              stripped.
326  *
327  * @return Normal NTSTATUS return.
328  **/
329
330 static NTSTATUS rpc_oldjoin_internals(struct net_context *c,
331                                         const struct dom_sid *domain_sid,
332                                         const char *domain_name,
333                                         struct cli_state *cli,
334                                         struct rpc_pipe_client *pipe_hnd,
335                                         TALLOC_CTX *mem_ctx,
336                                         int argc,
337                                         const char **argv)
338 {
339
340         fstring trust_passwd;
341         unsigned char orig_trust_passwd_hash[16];
342         NTSTATUS result;
343         enum netr_SchannelType sec_channel_type;
344
345         result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
346                                           &pipe_hnd);
347         if (!NT_STATUS_IS_OK(result)) {
348                 DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
349                         "error was %s\n",
350                         cli->desthost,
351                         nt_errstr(result) ));
352                 return result;
353         }
354
355         /*
356            check what type of join - if the user want's to join as
357            a BDC, the server must agree that we are a BDC.
358         */
359         if (argc >= 0) {
360                 sec_channel_type = get_sec_channel_type(argv[0]);
361         } else {
362                 sec_channel_type = get_sec_channel_type(NULL);
363         }
364
365         fstrcpy(trust_passwd, global_myname());
366         strlower_m(trust_passwd);
367
368         /*
369          * Machine names can be 15 characters, but the max length on
370          * a password is 14.  --jerry
371          */
372
373         trust_passwd[14] = '\0';
374
375         E_md4hash(trust_passwd, orig_trust_passwd_hash);
376
377         result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup,
378                                               global_myname(),
379                                               orig_trust_passwd_hash,
380                                               sec_channel_type);
381
382         if (NT_STATUS_IS_OK(result))
383                 printf(_("Joined domain %s.\n"), c->opt_target_workgroup);
384
385
386         if (!secrets_store_domain_sid(c->opt_target_workgroup, domain_sid)) {
387                 DEBUG(0, ("error storing domain sid for %s\n", c->opt_target_workgroup));
388                 result = NT_STATUS_UNSUCCESSFUL;
389         }
390
391         return result;
392 }
393
394 /**
395  * Join a domain, the old way.
396  *
397  * @param argc  Standard main() style argc.
398  * @param argv  Standard main() style argv. Initial components are already
399  *              stripped.
400  *
401  * @return A shell status integer (0 for success).
402  **/
403
404 static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv)
405 {
406         return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
407                                NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
408                                rpc_oldjoin_internals,
409                                argc, argv);
410 }
411
412 /**
413  * Join a domain, the old way.  This function exists to allow
414  * the message to be displayed when oldjoin was explicitly
415  * requested, but not when it was implied by "net rpc join".
416  *
417  * @param argc  Standard main() style argc.
418  * @param argv  Standard main() style argv. Initial components are already
419  *              stripped.
420  *
421  * @return A shell status integer (0 for success).
422  **/
423
424 static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
425 {
426         int rc = -1;
427
428         if (c->display_usage) {
429                 d_printf(  "%s\n"
430                            "net rpc oldjoin\n"
431                            "    %s\n",
432                          _("Usage:"),
433                          _("Join a domain the old way"));
434                 return 0;
435         }
436
437         rc = net_rpc_perform_oldjoin(c, argc, argv);
438
439         if (rc) {
440                 d_fprintf(stderr, _("Failed to join domain\n"));
441         }
442
443         return rc;
444 }
445
446 /**
447  * 'net rpc join' entrypoint.
448  * @param argc  Standard main() style argc.
449  * @param argv  Standard main() style argv. Initial components are already
450  *              stripped
451  *
452  * Main 'net_rpc_join()' (where the admin username/password is used) is
453  * in net_rpc_join.c.
454  * Try to just change the password, but if that doesn't work, use/prompt
455  * for a username/password.
456  **/
457
458 int net_rpc_join(struct net_context *c, int argc, const char **argv)
459 {
460         if (c->display_usage) {
461                 d_printf("%s\n%s",
462                          _("Usage:"),
463                          _("net rpc join -U <username>[%%password] <type>\n"
464                            "  Join a domain\n"
465                            "    username\tName of the admin user"
466                            "    password\tPassword of the admin user, will "
467                            "prompt if not specified\n"
468                            "    type\tCan be one of the following:\n"
469                            "\t\tMEMBER\tJoin as member server (default)\n"
470                            "\t\tBDC\tJoin as BDC\n"
471                            "\t\tPDC\tJoin as PDC\n"));
472                 return 0;
473         }
474
475         if (lp_server_role() == ROLE_STANDALONE) {
476                 d_printf(_("cannot join as standalone machine\n"));
477                 return -1;
478         }
479
480         if (strlen(global_myname()) > 15) {
481                 d_printf(_("Our netbios name can be at most 15 chars long, "
482                            "\"%s\" is %u chars long\n"),
483                          global_myname(), (unsigned int)strlen(global_myname()));
484                 return -1;
485         }
486
487         if ((net_rpc_perform_oldjoin(c, argc, argv) == 0))
488                 return 0;
489
490         return net_rpc_join_newstyle(c, argc, argv);
491 }
492
493 /**
494  * display info about a rpc domain
495  *
496  * All parameters are provided by the run_rpc_command function, except for
497  * argc, argv which are passed through.
498  *
499  * @param domain_sid The domain sid acquired from the remote server
500  * @param cli A cli_state connected to the server.
501  * @param mem_ctx Talloc context, destroyed on completion of the function.
502  * @param argc  Standard main() style argc.
503  * @param argv  Standard main() style argv. Initial components are already
504  *              stripped.
505  *
506  * @return Normal NTSTATUS return.
507  **/
508
509 NTSTATUS rpc_info_internals(struct net_context *c,
510                         const struct dom_sid *domain_sid,
511                         const char *domain_name,
512                         struct cli_state *cli,
513                         struct rpc_pipe_client *pipe_hnd,
514                         TALLOC_CTX *mem_ctx,
515                         int argc,
516                         const char **argv)
517 {
518         struct policy_handle connect_pol, domain_pol;
519         NTSTATUS status, result;
520         union samr_DomainInfo *info = NULL;
521         fstring sid_str;
522         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
523
524         sid_to_fstring(sid_str, domain_sid);
525
526         /* Get sam policy handle */
527         status = dcerpc_samr_Connect2(b, mem_ctx,
528                                       pipe_hnd->desthost,
529                                       MAXIMUM_ALLOWED_ACCESS,
530                                       &connect_pol,
531                                       &result);
532         if (!NT_STATUS_IS_OK(status)) {
533                 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
534                           nt_errstr(status));
535                 goto done;
536         }
537
538         if (!NT_STATUS_IS_OK(result)) {
539                 status = result;
540                 d_fprintf(stderr, _("Could not connect to SAM: %s\n"),
541                           nt_errstr(result));
542                 goto done;
543         }
544
545         /* Get domain policy handle */
546         status = dcerpc_samr_OpenDomain(b, mem_ctx,
547                                         &connect_pol,
548                                         MAXIMUM_ALLOWED_ACCESS,
549                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
550                                         &domain_pol,
551                                         &result);
552         if (!NT_STATUS_IS_OK(status)) {
553                 d_fprintf(stderr, _("Could not open domain: %s\n"),
554                           nt_errstr(status));
555                 goto done;
556         }
557         if (!NT_STATUS_IS_OK(result)) {
558                 status = result;
559                 d_fprintf(stderr, _("Could not open domain: %s\n"),
560                           nt_errstr(result));
561                 goto done;
562         }
563
564         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
565                                              &domain_pol,
566                                              2,
567                                              &info,
568                                              &result);
569         if (!NT_STATUS_IS_OK(status)) {
570                 goto done;
571         }
572         status = result;
573         if (NT_STATUS_IS_OK(result)) {
574                 d_printf(_("Domain Name: %s\n"),
575                          info->general.domain_name.string);
576                 d_printf(_("Domain SID: %s\n"), sid_str);
577                 d_printf(_("Sequence number: %llu\n"),
578                         (unsigned long long)info->general.sequence_num);
579                 d_printf(_("Num users: %u\n"), info->general.num_users);
580                 d_printf(_("Num domain groups: %u\n"),info->general.num_groups);
581                 d_printf(_("Num local groups: %u\n"),info->general.num_aliases);
582         }
583
584  done:
585         return status;
586 }
587
588 /**
589  * 'net rpc info' entrypoint.
590  * @param argc  Standard main() style argc.
591  * @param argv  Standard main() style argv. Initial components are already
592  *              stripped.
593  **/
594
595 int net_rpc_info(struct net_context *c, int argc, const char **argv)
596 {
597         if (c->display_usage) {
598                 d_printf(  "%s\n"
599                            "net rpc info\n"
600                            "  %s\n",
601                          _("Usage:"),
602                          _("Display information about the domain"));
603                 return 0;
604         }
605
606         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
607                                NET_FLAGS_PDC, rpc_info_internals,
608                                argc, argv);
609 }
610
611 /**
612  * Fetch domain SID into the local secrets.tdb.
613  *
614  * All parameters are provided by the run_rpc_command function, except for
615  * argc, argv which are passed through.
616  *
617  * @param domain_sid The domain sid acquired from the remote server.
618  * @param cli A cli_state connected to the server.
619  * @param mem_ctx Talloc context, destroyed on completion of the function.
620  * @param argc  Standard main() style argc.
621  * @param argv  Standard main() style argv. Initial components are already
622  *              stripped.
623  *
624  * @return Normal NTSTATUS return.
625  **/
626
627 static NTSTATUS rpc_getsid_internals(struct net_context *c,
628                         const struct dom_sid *domain_sid,
629                         const char *domain_name,
630                         struct cli_state *cli,
631                         struct rpc_pipe_client *pipe_hnd,
632                         TALLOC_CTX *mem_ctx,
633                         int argc,
634                         const char **argv)
635 {
636         fstring sid_str;
637
638         sid_to_fstring(sid_str, domain_sid);
639         d_printf(_("Storing SID %s for Domain %s in secrets.tdb\n"),
640                  sid_str, domain_name);
641
642         if (!secrets_store_domain_sid(domain_name, domain_sid)) {
643                 DEBUG(0,("Can't store domain SID\n"));
644                 return NT_STATUS_UNSUCCESSFUL;
645         }
646
647         return NT_STATUS_OK;
648 }
649
650 /**
651  * 'net rpc getsid' entrypoint.
652  * @param argc  Standard main() style argc.
653  * @param argv  Standard main() style argv. Initial components are already
654  *              stripped.
655  **/
656
657 int net_rpc_getsid(struct net_context *c, int argc, const char **argv)
658 {
659         int conn_flags = NET_FLAGS_PDC;
660
661         if (!c->opt_user_specified) {
662                 conn_flags |= NET_FLAGS_ANONYMOUS;
663         }
664
665         if (c->display_usage) {
666                 d_printf(  "%s\n"
667                            "net rpc getsid\n"
668                            "    %s\n",
669                          _("Usage:"),
670                          _("Fetch domain SID into local secrets.tdb"));
671                 return 0;
672         }
673
674         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id,
675                                conn_flags,
676                                rpc_getsid_internals,
677                                argc, argv);
678 }
679
680 /****************************************************************************/
681
682 /**
683  * Basic usage function for 'net rpc user'.
684  * @param argc  Standard main() style argc.
685  * @param argv  Standard main() style argv. Initial components are already
686  *              stripped.
687  **/
688
689 static int rpc_user_usage(struct net_context *c, int argc, const char **argv)
690 {
691         return net_user_usage(c, argc, argv);
692 }
693
694 /**
695  * Add a new user to a remote RPC server.
696  *
697  * @param argc  Standard main() style argc.
698  * @param argv  Standard main() style argv. Initial components are already
699  *              stripped.
700  *
701  * @return A shell status integer (0 for success).
702  **/
703
704 static int rpc_user_add(struct net_context *c, int argc, const char **argv)
705 {
706         NET_API_STATUS status;
707         struct USER_INFO_1 info1;
708         uint32_t parm_error = 0;
709
710         if (argc < 1 || c->display_usage) {
711                 rpc_user_usage(c, argc, argv);
712                 return 0;
713         }
714
715         ZERO_STRUCT(info1);
716
717         info1.usri1_name = argv[0];
718         if (argc == 2) {
719                 info1.usri1_password = argv[1];
720         }
721
722         status = NetUserAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
723
724         if (status != 0) {
725                 d_fprintf(stderr,_("Failed to add user '%s' with error: %s.\n"),
726                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
727                                                             status));
728                 return -1;
729         } else {
730                 d_printf(_("Added user '%s'.\n"), argv[0]);
731         }
732
733         return 0;
734 }
735
736 /**
737  * Rename a user on a remote RPC server.
738  *
739  * @param argc  Standard main() style argc.
740  * @param argv  Standard main() style argv. Initial components are already
741  *              stripped.
742  *
743  * @return A shell status integer (0 for success).
744  **/
745
746 static int rpc_user_rename(struct net_context *c, int argc, const char **argv)
747 {
748         NET_API_STATUS status;
749         struct USER_INFO_0 u0;
750         uint32_t parm_err = 0;
751
752         if (argc != 2 || c->display_usage) {
753                 rpc_user_usage(c, argc, argv);
754                 return 0;
755         }
756
757         u0.usri0_name = argv[1];
758
759         status = NetUserSetInfo(c->opt_host, argv[0],
760                                 0, (uint8_t *)&u0, &parm_err);
761         if (status) {
762                 d_fprintf(stderr,
763                           _("Failed to rename user from %s to %s - %s\n"),
764                           argv[0], argv[1],
765                           libnetapi_get_error_string(c->netapi_ctx, status));
766         } else {
767                 d_printf(_("Renamed user from %s to %s\n"), argv[0], argv[1]);
768         }
769
770         return status;
771 }
772
773 /**
774  * Set a user's primary group
775  *
776  * @param argc  Standard main() style argc.
777  * @param argv  Standard main() style argv. Initial components are already
778  *              stripped.
779  *
780  * @return A shell status integer (0 for success).
781  **/
782
783 static int rpc_user_setprimarygroup(struct net_context *c, int argc,
784                                     const char **argv)
785 {
786         NET_API_STATUS status;
787         uint8_t *buffer;
788         struct GROUP_INFO_2 *g2;
789         struct USER_INFO_1051 u1051;
790         uint32_t parm_err = 0;
791
792         if (argc != 2 || c->display_usage) {
793                 rpc_user_usage(c, argc, argv);
794                 return 0;
795         }
796
797         status = NetGroupGetInfo(c->opt_host, argv[1], 2, &buffer);
798         if (status) {
799                 d_fprintf(stderr, _("Failed to find group name %s -- %s\n"),
800                           argv[1],
801                           libnetapi_get_error_string(c->netapi_ctx, status));
802                 return status;
803         }
804         g2 = (struct GROUP_INFO_2 *)buffer;
805
806         u1051.usri1051_primary_group_id = g2->grpi2_group_id;
807
808         NetApiBufferFree(buffer);
809
810         status = NetUserSetInfo(c->opt_host, argv[0], 1051,
811                                 (uint8_t *)&u1051, &parm_err);
812         if (status) {
813                 d_fprintf(stderr,
814                           _("Failed to set user's primary group %s to %s - "
815                             "%s\n"), argv[0], argv[1],
816                           libnetapi_get_error_string(c->netapi_ctx, status));
817         } else {
818                 d_printf(_("Set primary group of user %s to %s\n"), argv[0],
819                          argv[1]);
820         }
821         return status;
822 }
823
824 /**
825  * Delete a user from a remote RPC server.
826  *
827  * @param argc  Standard main() style argc.
828  * @param argv  Standard main() style argv. Initial components are already
829  *              stripped.
830  *
831  * @return A shell status integer (0 for success).
832  **/
833
834 static int rpc_user_delete(struct net_context *c, int argc, const char **argv)
835 {
836         NET_API_STATUS status;
837
838         if (argc < 1 || c->display_usage) {
839                 rpc_user_usage(c, argc, argv);
840                 return 0;
841         }
842
843         status = NetUserDel(c->opt_host, argv[0]);
844
845         if (status != 0) {
846                 d_fprintf(stderr, _("Failed to delete user '%s' with: %s.\n"),
847                           argv[0],
848                           libnetapi_get_error_string(c->netapi_ctx, status));
849                 return -1;
850         } else {
851                 d_printf(_("Deleted user '%s'.\n"), argv[0]);
852         }
853
854         return 0;
855 }
856
857 /**
858  * Set a user's password on a remote RPC server.
859  *
860  * @param argc  Standard main() style argc.
861  * @param argv  Standard main() style argv. Initial components are already
862  *              stripped.
863  *
864  * @return A shell status integer (0 for success).
865  **/
866
867 static int rpc_user_password(struct net_context *c, int argc, const char **argv)
868 {
869         NET_API_STATUS status;
870         char *prompt = NULL;
871         struct USER_INFO_1003 u1003;
872         uint32_t parm_err = 0;
873         int ret;
874
875         if (argc < 1 || c->display_usage) {
876                 rpc_user_usage(c, argc, argv);
877                 return 0;
878         }
879
880         if (argv[1]) {
881                 u1003.usri1003_password = argv[1];
882         } else {
883                 ret = asprintf(&prompt, _("Enter new password for %s:"),
884                                argv[0]);
885                 if (ret == -1) {
886                         return -1;
887                 }
888                 u1003.usri1003_password = talloc_strdup(c, getpass(prompt));
889                 SAFE_FREE(prompt);
890                 if (u1003.usri1003_password == NULL) {
891                         return -1;
892                 }
893         }
894
895         status = NetUserSetInfo(c->opt_host, argv[0], 1003, (uint8_t *)&u1003, &parm_err);
896
897         /* Display results */
898         if (status != 0) {
899                 d_fprintf(stderr,
900                         _("Failed to set password for '%s' with error: %s.\n"),
901                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
902                                                             status));
903                 return -1;
904         }
905
906         return 0;
907 }
908
909 /**
910  * List a user's groups from a remote RPC server.
911  *
912  * @param argc  Standard main() style argc.
913  * @param argv  Standard main() style argv. Initial components are already
914  *              stripped.
915  *
916  * @return A shell status integer (0 for success)
917  **/
918
919 static int rpc_user_info(struct net_context *c, int argc, const char **argv)
920
921 {
922         NET_API_STATUS status;
923         struct GROUP_USERS_INFO_0 *u0 = NULL;
924         uint32_t entries_read = 0;
925         uint32_t total_entries = 0;
926         int i;
927
928
929         if (argc < 1 || c->display_usage) {
930                 rpc_user_usage(c, argc, argv);
931                 return 0;
932         }
933
934         status = NetUserGetGroups(c->opt_host,
935                                   argv[0],
936                                   0,
937                                   (uint8_t **)(void *)&u0,
938                                   (uint32_t)-1,
939                                   &entries_read,
940                                   &total_entries);
941         if (status != 0) {
942                 d_fprintf(stderr,
943                         _("Failed to get groups for '%s' with error: %s.\n"),
944                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
945                                                             status));
946                 return -1;
947         }
948
949         for (i=0; i < entries_read; i++) {
950                 printf("%s\n", u0->grui0_name);
951                 u0++;
952         }
953
954         return 0;
955 }
956
957 /**
958  * List users on a remote RPC server.
959  *
960  * All parameters are provided by the run_rpc_command function, except for
961  * argc, argv which are passed through.
962  *
963  * @param domain_sid The domain sid acquired from the remote server.
964  * @param cli A cli_state connected to the server.
965  * @param mem_ctx Talloc context, destroyed on completion of the function.
966  * @param argc  Standard main() style argc.
967  * @param argv  Standard main() style argv. Initial components are already
968  *              stripped.
969  *
970  * @return Normal NTSTATUS return.
971  **/
972
973 static int rpc_user_list(struct net_context *c, int argc, const char **argv)
974 {
975         NET_API_STATUS status;
976         uint32_t start_idx=0, num_entries, i, loop_count = 0;
977         struct NET_DISPLAY_USER *info = NULL;
978         void *buffer = NULL;
979
980         /* Query domain users */
981         if (c->opt_long_list_entries)
982                 d_printf(_("\nUser name             Comment"
983                            "\n-----------------------------\n"));
984         do {
985                 uint32_t max_entries, max_size;
986
987                 dcerpc_get_query_dispinfo_params(
988                         loop_count, &max_entries, &max_size);
989
990                 status = NetQueryDisplayInformation(c->opt_host,
991                                                     1,
992                                                     start_idx,
993                                                     max_entries,
994                                                     max_size,
995                                                     &num_entries,
996                                                     &buffer);
997                 if (status != 0 && status != ERROR_MORE_DATA) {
998                         return status;
999                 }
1000
1001                 info = (struct NET_DISPLAY_USER *)buffer;
1002
1003                 for (i = 0; i < num_entries; i++) {
1004
1005                         if (c->opt_long_list_entries)
1006                                 printf("%-21.21s %s\n", info->usri1_name,
1007                                         info->usri1_comment);
1008                         else
1009                                 printf("%s\n", info->usri1_name);
1010                         info++;
1011                 }
1012
1013                 NetApiBufferFree(buffer);
1014
1015                 loop_count++;
1016                 start_idx += num_entries;
1017
1018         } while (status == ERROR_MORE_DATA);
1019
1020         return status;
1021 }
1022
1023 /**
1024  * 'net rpc user' entrypoint.
1025  * @param argc  Standard main() style argc.
1026  * @param argv  Standard main() style argv. Initial components are already
1027  *              stripped.
1028  **/
1029
1030 int net_rpc_user(struct net_context *c, int argc, const char **argv)
1031 {
1032         NET_API_STATUS status;
1033
1034         struct functable func[] = {
1035                 {
1036                         "add",
1037                         rpc_user_add,
1038                         NET_TRANSPORT_RPC,
1039                         N_("Add specified user"),
1040                         N_("net rpc user add\n"
1041                            "    Add specified user")
1042                 },
1043                 {
1044                         "info",
1045                         rpc_user_info,
1046                         NET_TRANSPORT_RPC,
1047                         N_("List domain groups of user"),
1048                         N_("net rpc user info\n"
1049                            "    List domain groups of user")
1050                 },
1051                 {
1052                         "delete",
1053                         rpc_user_delete,
1054                         NET_TRANSPORT_RPC,
1055                         N_("Remove specified user"),
1056                         N_("net rpc user delete\n"
1057                            "    Remove specified user")
1058                 },
1059                 {
1060                         "password",
1061                         rpc_user_password,
1062                         NET_TRANSPORT_RPC,
1063                         N_("Change user password"),
1064                         N_("net rpc user password\n"
1065                            "    Change user password")
1066                 },
1067                 {
1068                         "rename",
1069                         rpc_user_rename,
1070                         NET_TRANSPORT_RPC,
1071                         N_("Rename specified user"),
1072                         N_("net rpc user rename\n"
1073                            "    Rename specified user")
1074                 },
1075                 {
1076                         "setprimarygroup",
1077                         rpc_user_setprimarygroup,
1078                         NET_TRANSPORT_RPC,
1079                         "Set a user's primary group",
1080                         "net rpc user setprimarygroup\n"
1081                         "    Set a user's primary group"
1082                 },
1083                 {NULL, NULL, 0, NULL, NULL}
1084         };
1085
1086         status = libnetapi_net_init(&c->netapi_ctx);
1087         if (status != 0) {
1088                 return -1;
1089         }
1090         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
1091         libnetapi_set_password(c->netapi_ctx, c->opt_password);
1092         if (c->opt_kerberos) {
1093                 libnetapi_set_use_kerberos(c->netapi_ctx);
1094         }
1095
1096         if (argc == 0) {
1097                 if (c->display_usage) {
1098                         d_printf(  "%s\n"
1099                                    "net rpc user\n"
1100                                    "    %s\n",
1101                                  _("Usage:"),
1102                                  _("List all users"));
1103                         net_display_usage_from_functable(func);
1104                         return 0;
1105                 }
1106
1107                 return rpc_user_list(c, argc, argv);
1108         }
1109
1110         return net_run_function(c, argc, argv, "net rpc user", func);
1111 }
1112
1113 static NTSTATUS rpc_sh_user_list(struct net_context *c,
1114                                  TALLOC_CTX *mem_ctx,
1115                                  struct rpc_sh_ctx *ctx,
1116                                  struct rpc_pipe_client *pipe_hnd,
1117                                  int argc, const char **argv)
1118 {
1119         return werror_to_ntstatus(W_ERROR(rpc_user_list(c, argc, argv)));
1120 }
1121
1122 static NTSTATUS rpc_sh_user_info(struct net_context *c,
1123                                  TALLOC_CTX *mem_ctx,
1124                                  struct rpc_sh_ctx *ctx,
1125                                  struct rpc_pipe_client *pipe_hnd,
1126                                  int argc, const char **argv)
1127 {
1128         return werror_to_ntstatus(W_ERROR(rpc_user_info(c, argc, argv)));
1129 }
1130
1131 static NTSTATUS rpc_sh_handle_user(struct net_context *c,
1132                                    TALLOC_CTX *mem_ctx,
1133                                    struct rpc_sh_ctx *ctx,
1134                                    struct rpc_pipe_client *pipe_hnd,
1135                                    int argc, const char **argv,
1136                                    NTSTATUS (*fn)(
1137                                            struct net_context *c,
1138                                            TALLOC_CTX *mem_ctx,
1139                                            struct rpc_sh_ctx *ctx,
1140                                            struct rpc_pipe_client *pipe_hnd,
1141                                            struct policy_handle *user_hnd,
1142                                            int argc, const char **argv))
1143 {
1144         struct policy_handle connect_pol, domain_pol, user_pol;
1145         NTSTATUS status, result;
1146         struct dom_sid sid;
1147         uint32 rid;
1148         enum lsa_SidType type;
1149         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1150
1151         if (argc == 0) {
1152                 d_fprintf(stderr, "%s %s <username>\n", _("Usage:"),
1153                           ctx->whoami);
1154                 return NT_STATUS_INVALID_PARAMETER;
1155         }
1156
1157         ZERO_STRUCT(connect_pol);
1158         ZERO_STRUCT(domain_pol);
1159         ZERO_STRUCT(user_pol);
1160
1161         status = net_rpc_lookup_name(c, mem_ctx, rpc_pipe_np_smb_conn(pipe_hnd),
1162                                      argv[0], NULL, NULL, &sid, &type);
1163         if (!NT_STATUS_IS_OK(status)) {
1164                 d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
1165                           nt_errstr(status));
1166                 goto done;
1167         }
1168
1169         if (type != SID_NAME_USER) {
1170                 d_fprintf(stderr, _("%s is a %s, not a user\n"), argv[0],
1171                           sid_type_lookup(type));
1172                 status = NT_STATUS_NO_SUCH_USER;
1173                 goto done;
1174         }
1175
1176         if (!sid_peek_check_rid(ctx->domain_sid, &sid, &rid)) {
1177                 d_fprintf(stderr, _("%s is not in our domain\n"), argv[0]);
1178                 status = NT_STATUS_NO_SUCH_USER;
1179                 goto done;
1180         }
1181
1182         status = dcerpc_samr_Connect2(b, mem_ctx,
1183                                       pipe_hnd->desthost,
1184                                       MAXIMUM_ALLOWED_ACCESS,
1185                                       &connect_pol,
1186                                       &result);
1187         if (!NT_STATUS_IS_OK(status)) {
1188                 goto done;
1189         }
1190         if (!NT_STATUS_IS_OK(result)) {
1191                 status = result;
1192                 goto done;
1193         }
1194
1195         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1196                                         &connect_pol,
1197                                         MAXIMUM_ALLOWED_ACCESS,
1198                                         ctx->domain_sid,
1199                                         &domain_pol,
1200                                         &result);
1201         if (!NT_STATUS_IS_OK(status)) {
1202                 goto done;
1203         }
1204         if (!NT_STATUS_IS_OK(result)) {
1205                 status = result;
1206                 goto done;
1207         }
1208
1209         status = dcerpc_samr_OpenUser(b, mem_ctx,
1210                                       &domain_pol,
1211                                       MAXIMUM_ALLOWED_ACCESS,
1212                                       rid,
1213                                       &user_pol,
1214                                       &result);
1215         if (!NT_STATUS_IS_OK(status)) {
1216                 goto done;
1217         }
1218         if (!NT_STATUS_IS_OK(result)) {
1219                 status = result;
1220                 goto done;
1221         }
1222
1223         status = fn(c, mem_ctx, ctx, pipe_hnd, &user_pol, argc-1, argv+1);
1224
1225  done:
1226         if (is_valid_policy_hnd(&user_pol)) {
1227                 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1228         }
1229         if (is_valid_policy_hnd(&domain_pol)) {
1230                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
1231         }
1232         if (is_valid_policy_hnd(&connect_pol)) {
1233                 dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
1234         }
1235         return status;
1236 }
1237
1238 static NTSTATUS rpc_sh_user_show_internals(struct net_context *c,
1239                                            TALLOC_CTX *mem_ctx,
1240                                            struct rpc_sh_ctx *ctx,
1241                                            struct rpc_pipe_client *pipe_hnd,
1242                                            struct policy_handle *user_hnd,
1243                                            int argc, const char **argv)
1244 {
1245         NTSTATUS status, result;
1246         union samr_UserInfo *info = NULL;
1247         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1248
1249         if (argc != 0) {
1250                 d_fprintf(stderr, "%s %s show <username>\n", _("Usage:"),
1251                           ctx->whoami);
1252                 return NT_STATUS_INVALID_PARAMETER;
1253         }
1254
1255         status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1256                                            user_hnd,
1257                                            21,
1258                                            &info,
1259                                            &result);
1260         if (!NT_STATUS_IS_OK(status)) {
1261                 return status;
1262         }
1263         if (!NT_STATUS_IS_OK(result)) {
1264                 return result;
1265         }
1266
1267         d_printf(_("user rid: %d, group rid: %d\n"),
1268                 info->info21.rid,
1269                 info->info21.primary_gid);
1270
1271         return result;
1272 }
1273
1274 static NTSTATUS rpc_sh_user_show(struct net_context *c,
1275                                  TALLOC_CTX *mem_ctx,
1276                                  struct rpc_sh_ctx *ctx,
1277                                  struct rpc_pipe_client *pipe_hnd,
1278                                  int argc, const char **argv)
1279 {
1280         return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1281                                   rpc_sh_user_show_internals);
1282 }
1283
1284 #define FETCHSTR(name, rec) \
1285 do { if (strequal(ctx->thiscmd, name)) { \
1286         oldval = talloc_strdup(mem_ctx, info->info21.rec.string); } \
1287 } while (0);
1288
1289 #define SETSTR(name, rec, flag) \
1290 do { if (strequal(ctx->thiscmd, name)) { \
1291         init_lsa_String(&(info->info21.rec), argv[0]); \
1292         info->info21.fields_present |= SAMR_FIELD_##flag; } \
1293 } while (0);
1294
1295 static NTSTATUS rpc_sh_user_str_edit_internals(struct net_context *c,
1296                                                TALLOC_CTX *mem_ctx,
1297                                                struct rpc_sh_ctx *ctx,
1298                                                struct rpc_pipe_client *pipe_hnd,
1299                                                struct policy_handle *user_hnd,
1300                                                int argc, const char **argv)
1301 {
1302         NTSTATUS status, result;
1303         const char *username;
1304         const char *oldval = "";
1305         union samr_UserInfo *info = NULL;
1306         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1307
1308         if (argc > 1) {
1309                 d_fprintf(stderr, "%s %s <username> [new value|NULL]\n",
1310                           _("Usage:"), ctx->whoami);
1311                 return NT_STATUS_INVALID_PARAMETER;
1312         }
1313
1314         status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1315                                            user_hnd,
1316                                            21,
1317                                            &info,
1318                                            &result);
1319         if (!NT_STATUS_IS_OK(status)) {
1320                 return status;
1321         }
1322         if (!NT_STATUS_IS_OK(result)) {
1323                 return result;
1324         }
1325
1326         username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1327
1328         FETCHSTR("fullname", full_name);
1329         FETCHSTR("homedir", home_directory);
1330         FETCHSTR("homedrive", home_drive);
1331         FETCHSTR("logonscript", logon_script);
1332         FETCHSTR("profilepath", profile_path);
1333         FETCHSTR("description", description);
1334
1335         if (argc == 0) {
1336                 d_printf(_("%s's %s: [%s]\n"), username, ctx->thiscmd, oldval);
1337                 goto done;
1338         }
1339
1340         if (strcmp(argv[0], "NULL") == 0) {
1341                 argv[0] = "";
1342         }
1343
1344         ZERO_STRUCT(info->info21);
1345
1346         SETSTR("fullname", full_name, FULL_NAME);
1347         SETSTR("homedir", home_directory, HOME_DIRECTORY);
1348         SETSTR("homedrive", home_drive, HOME_DRIVE);
1349         SETSTR("logonscript", logon_script, LOGON_SCRIPT);
1350         SETSTR("profilepath", profile_path, PROFILE_PATH);
1351         SETSTR("description", description, DESCRIPTION);
1352
1353         status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1354                                          user_hnd,
1355                                          21,
1356                                          info,
1357                                          &result);
1358         if (!NT_STATUS_IS_OK(status)) {
1359                 return status;
1360         }
1361
1362         status = result;
1363
1364         d_printf(_("Set %s's %s from [%s] to [%s]\n"), username,
1365                  ctx->thiscmd, oldval, argv[0]);
1366
1367  done:
1368
1369         return status;
1370 }
1371
1372 #define HANDLEFLG(name, rec) \
1373 do { if (strequal(ctx->thiscmd, name)) { \
1374         oldval = (oldflags & ACB_##rec) ? "yes" : "no"; \
1375         if (newval) { \
1376                 newflags = oldflags | ACB_##rec; \
1377         } else { \
1378                 newflags = oldflags & ~ACB_##rec; \
1379         } } } while (0);
1380
1381 static NTSTATUS rpc_sh_user_str_edit(struct net_context *c,
1382                                      TALLOC_CTX *mem_ctx,
1383                                      struct rpc_sh_ctx *ctx,
1384                                      struct rpc_pipe_client *pipe_hnd,
1385                                      int argc, const char **argv)
1386 {
1387         return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1388                                   rpc_sh_user_str_edit_internals);
1389 }
1390
1391 static NTSTATUS rpc_sh_user_flag_edit_internals(struct net_context *c,
1392                                                 TALLOC_CTX *mem_ctx,
1393                                                 struct rpc_sh_ctx *ctx,
1394                                                 struct rpc_pipe_client *pipe_hnd,
1395                                                 struct policy_handle *user_hnd,
1396                                                 int argc, const char **argv)
1397 {
1398         NTSTATUS status, result;
1399         const char *username;
1400         const char *oldval = "unknown";
1401         uint32 oldflags, newflags;
1402         bool newval;
1403         union samr_UserInfo *info = NULL;
1404         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1405
1406         if ((argc > 1) ||
1407             ((argc == 1) && !strequal(argv[0], "yes") &&
1408              !strequal(argv[0], "no"))) {
1409                 /* TRANSATORS: The yes|no here are program keywords. Please do
1410                    not translate. */
1411                 d_fprintf(stderr, _("Usage: %s <username> [yes|no]\n"),
1412                           ctx->whoami);
1413                 return NT_STATUS_INVALID_PARAMETER;
1414         }
1415
1416         newval = strequal(argv[0], "yes");
1417
1418         status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1419                                            user_hnd,
1420                                            21,
1421                                            &info,
1422                                            &result);
1423         if (!NT_STATUS_IS_OK(status)) {
1424                 return status;
1425         }
1426         if (!NT_STATUS_IS_OK(result)) {
1427                 return result;
1428         }
1429
1430         username = talloc_strdup(mem_ctx, info->info21.account_name.string);
1431         oldflags = info->info21.acct_flags;
1432         newflags = info->info21.acct_flags;
1433
1434         HANDLEFLG("disabled", DISABLED);
1435         HANDLEFLG("pwnotreq", PWNOTREQ);
1436         HANDLEFLG("autolock", AUTOLOCK);
1437         HANDLEFLG("pwnoexp", PWNOEXP);
1438
1439         if (argc == 0) {
1440                 d_printf(_("%s's %s flag: %s\n"), username, ctx->thiscmd,
1441                          oldval);
1442                 goto done;
1443         }
1444
1445         ZERO_STRUCT(info->info21);
1446
1447         info->info21.acct_flags = newflags;
1448         info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS;
1449
1450         status = dcerpc_samr_SetUserInfo(b, mem_ctx,
1451                                          user_hnd,
1452                                          21,
1453                                          info,
1454                                          &result);
1455         if (!NT_STATUS_IS_OK(status)) {
1456                 goto done;
1457         }
1458         status = result;
1459         if (NT_STATUS_IS_OK(result)) {
1460                 d_printf(_("Set %s's %s flag from [%s] to [%s]\n"), username,
1461                          ctx->thiscmd, oldval, argv[0]);
1462         }
1463
1464  done:
1465
1466         return status;
1467 }
1468
1469 static NTSTATUS rpc_sh_user_flag_edit(struct net_context *c,
1470                                       TALLOC_CTX *mem_ctx,
1471                                       struct rpc_sh_ctx *ctx,
1472                                       struct rpc_pipe_client *pipe_hnd,
1473                                       int argc, const char **argv)
1474 {
1475         return rpc_sh_handle_user(c, mem_ctx, ctx, pipe_hnd, argc, argv,
1476                                   rpc_sh_user_flag_edit_internals);
1477 }
1478
1479 struct rpc_sh_cmd *net_rpc_user_edit_cmds(struct net_context *c,
1480                                           TALLOC_CTX *mem_ctx,
1481                                           struct rpc_sh_ctx *ctx)
1482 {
1483         static struct rpc_sh_cmd cmds[] = {
1484
1485                 { "fullname", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1486                   N_("Show/Set a user's full name") },
1487
1488                 { "homedir", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1489                   N_("Show/Set a user's home directory") },
1490
1491                 { "homedrive", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1492                   N_("Show/Set a user's home drive") },
1493
1494                 { "logonscript", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1495                   N_("Show/Set a user's logon script") },
1496
1497                 { "profilepath", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1498                   N_("Show/Set a user's profile path") },
1499
1500                 { "description", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_str_edit,
1501                   N_("Show/Set a user's description") },
1502
1503                 { "disabled", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1504                   N_("Show/Set whether a user is disabled") },
1505
1506                 { "autolock", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1507                   N_("Show/Set whether a user locked out") },
1508
1509                 { "pwnotreq", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1510                   N_("Show/Set whether a user does not need a password") },
1511
1512                 { "pwnoexp", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_flag_edit,
1513                   N_("Show/Set whether a user's password does not expire") },
1514
1515                 { NULL, NULL, 0, NULL, NULL }
1516         };
1517
1518         return cmds;
1519 }
1520
1521 struct rpc_sh_cmd *net_rpc_user_cmds(struct net_context *c,
1522                                      TALLOC_CTX *mem_ctx,
1523                                      struct rpc_sh_ctx *ctx)
1524 {
1525         static struct rpc_sh_cmd cmds[] = {
1526
1527                 { "list", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_list,
1528                   N_("List available users") },
1529
1530                 { "info", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_info,
1531                   N_("List the domain groups a user is member of") },
1532
1533                 { "show", NULL, &ndr_table_samr.syntax_id, rpc_sh_user_show,
1534                   N_("Show info about a user") },
1535
1536                 { "edit", net_rpc_user_edit_cmds, 0, NULL,
1537                   N_("Show/Modify a user's fields") },
1538
1539                 { NULL, NULL, 0, NULL, NULL }
1540         };
1541
1542         return cmds;
1543 }
1544
1545 /****************************************************************************/
1546
1547 /**
1548  * Basic usage function for 'net rpc group'.
1549  * @param argc  Standard main() style argc.
1550  * @param argv  Standard main() style argv. Initial components are already
1551  *              stripped.
1552  **/
1553
1554 static int rpc_group_usage(struct net_context *c, int argc, const char **argv)
1555 {
1556         return net_group_usage(c, argc, argv);
1557 }
1558
1559 /**
1560  * Delete group on a remote RPC server.
1561  *
1562  * All parameters are provided by the run_rpc_command function, except for
1563  * argc, argv which are passed through.
1564  *
1565  * @param domain_sid The domain sid acquired from the remote server.
1566  * @param cli A cli_state connected to the server.
1567  * @param mem_ctx Talloc context, destroyed on completion of the function.
1568  * @param argc  Standard main() style argc.
1569  * @param argv  Standard main() style argv. Initial components are already
1570  *              stripped.
1571  *
1572  * @return Normal NTSTATUS return.
1573  **/
1574
1575 static NTSTATUS rpc_group_delete_internals(struct net_context *c,
1576                                         const struct dom_sid *domain_sid,
1577                                         const char *domain_name,
1578                                         struct cli_state *cli,
1579                                         struct rpc_pipe_client *pipe_hnd,
1580                                         TALLOC_CTX *mem_ctx,
1581                                         int argc,
1582                                         const char **argv)
1583 {
1584         struct policy_handle connect_pol, domain_pol, group_pol, user_pol;
1585         bool group_is_primary = false;
1586         NTSTATUS status, result;
1587         uint32_t group_rid;
1588         struct samr_RidAttrArray *rids = NULL;
1589         /* char **names; */
1590         int i;
1591         /* struct samr_RidWithAttribute *user_gids; */
1592         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1593
1594         struct samr_Ids group_rids, name_types;
1595         struct lsa_String lsa_acct_name;
1596         union samr_UserInfo *info = NULL;
1597
1598         if (argc < 1 || c->display_usage) {
1599                 rpc_group_usage(c, argc,argv);
1600                 return NT_STATUS_OK; /* ok? */
1601         }
1602
1603         status = dcerpc_samr_Connect2(b, mem_ctx,
1604                                       pipe_hnd->desthost,
1605                                       MAXIMUM_ALLOWED_ACCESS,
1606                                       &connect_pol,
1607                                       &result);
1608         if (!NT_STATUS_IS_OK(status)) {
1609                 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1610                 goto done;
1611         }
1612
1613         if (!NT_STATUS_IS_OK(result)) {
1614                 status = result;
1615                 d_fprintf(stderr, _("Request samr_Connect2 failed\n"));
1616                 goto done;
1617         }
1618
1619         status = dcerpc_samr_OpenDomain(b, mem_ctx,
1620                                         &connect_pol,
1621                                         MAXIMUM_ALLOWED_ACCESS,
1622                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
1623                                         &domain_pol,
1624                                         &result);
1625         if (!NT_STATUS_IS_OK(status)) {
1626                 d_fprintf(stderr, _("Request open_domain failed\n"));
1627                 goto done;
1628         }
1629
1630         if (!NT_STATUS_IS_OK(result)) {
1631                 status = result;
1632                 d_fprintf(stderr, _("Request open_domain failed\n"));
1633                 goto done;
1634         }
1635
1636         init_lsa_String(&lsa_acct_name, argv[0]);
1637
1638         status = dcerpc_samr_LookupNames(b, mem_ctx,
1639                                          &domain_pol,
1640                                          1,
1641                                          &lsa_acct_name,
1642                                          &group_rids,
1643                                          &name_types,
1644                                          &result);
1645         if (!NT_STATUS_IS_OK(status)) {
1646                 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1647                 goto done;
1648         }
1649
1650         if (!NT_STATUS_IS_OK(result)) {
1651                 status = result;
1652                 d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
1653                 goto done;
1654         }
1655
1656         switch (name_types.ids[0])
1657         {
1658         case SID_NAME_DOM_GRP:
1659                 status = dcerpc_samr_OpenGroup(b, mem_ctx,
1660                                                &domain_pol,
1661                                                MAXIMUM_ALLOWED_ACCESS,
1662                                                group_rids.ids[0],
1663                                                &group_pol,
1664                                                &result);
1665                 if (!NT_STATUS_IS_OK(status)) {
1666                         d_fprintf(stderr, _("Request open_group failed"));
1667                         goto done;
1668                 }
1669
1670                 if (!NT_STATUS_IS_OK(result)) {
1671                         status = result;
1672                         d_fprintf(stderr, _("Request open_group failed"));
1673                         goto done;
1674                 }
1675
1676                 group_rid = group_rids.ids[0];
1677
1678                 status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
1679                                                       &group_pol,
1680                                                       &rids,
1681                                                       &result);
1682                 if (!NT_STATUS_IS_OK(status)) {
1683                         d_fprintf(stderr,
1684                                   _("Unable to query group members of %s"),
1685                                   argv[0]);
1686                         goto done;
1687                 }
1688
1689                 if (!NT_STATUS_IS_OK(result)) {
1690                         status = result;
1691                         d_fprintf(stderr,
1692                                   _("Unable to query group members of %s"),
1693                                   argv[0]);
1694                         goto done;
1695                 }
1696
1697                 if (c->opt_verbose) {
1698                         d_printf(
1699                                 _("Domain Group %s (rid: %d) has %d members\n"),
1700                                 argv[0],group_rid, rids->count);
1701                 }
1702
1703                 /* Check if group is anyone's primary group */
1704                 for (i = 0; i < rids->count; i++)
1705                 {
1706                         status = dcerpc_samr_OpenUser(b, mem_ctx,
1707                                                       &domain_pol,
1708                                                       MAXIMUM_ALLOWED_ACCESS,
1709                                                       rids->rids[i],
1710                                                       &user_pol,
1711                                                       &result);
1712                         if (!NT_STATUS_IS_OK(status)) {
1713                                 d_fprintf(stderr,
1714                                         _("Unable to open group member %d\n"),
1715                                         rids->rids[i]);
1716                                 goto done;
1717                         }
1718
1719                         if (!NT_STATUS_IS_OK(result)) {
1720                                 status = result;
1721                                 d_fprintf(stderr,
1722                                         _("Unable to open group member %d\n"),
1723                                         rids->rids[i]);
1724                                 goto done;
1725                         }
1726
1727                         status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
1728                                                            &user_pol,
1729                                                            21,
1730                                                            &info,
1731                                                            &result);
1732                         if (!NT_STATUS_IS_OK(status)) {
1733                                 d_fprintf(stderr,
1734                                         _("Unable to lookup userinfo for group "
1735                                           "member %d\n"),
1736                                         rids->rids[i]);
1737                                 goto done;
1738                         }
1739
1740                         if (!NT_STATUS_IS_OK(result)) {
1741                                 status = result;
1742                                 d_fprintf(stderr,
1743                                         _("Unable to lookup userinfo for group "
1744                                           "member %d\n"),
1745                                         rids->rids[i]);
1746                                 goto done;
1747                         }
1748
1749                         if (info->info21.primary_gid == group_rid) {
1750                                 if (c->opt_verbose) {
1751                                         d_printf(_("Group is primary group "
1752                                                    "of %s\n"),
1753                                                 info->info21.account_name.string);
1754                                 }
1755                                 group_is_primary = true;
1756                         }
1757
1758                         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
1759                 }
1760
1761                 if (group_is_primary) {
1762                         d_fprintf(stderr, _("Unable to delete group because "
1763                                  "some of it's members have it as primary "
1764                                  "group\n"));
1765                         status = NT_STATUS_MEMBERS_PRIMARY_GROUP;
1766                         goto done;
1767                 }
1768
1769                 /* remove all group members */
1770                 for (i = 0; i < rids->count; i++)
1771                 {
1772                         if (c->opt_verbose)
1773                                 d_printf(_("Remove group member %d..."),
1774                                         rids->rids[i]);
1775                         status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
1776                                                                &group_pol,
1777                                                                rids->rids[i],
1778                                                                &result);
1779                         if (!NT_STATUS_IS_OK(status)) {
1780                                 goto done;
1781                         }
1782                         status = result;
1783                         if (NT_STATUS_IS_OK(result)) {
1784                                 if (c->opt_verbose)
1785                                         d_printf(_("ok\n"));
1786                         } else {
1787                                 if (c->opt_verbose)
1788                                         d_printf("%s\n", _("failed"));
1789                                 goto done;
1790                         }
1791                 }
1792
1793                 status = dcerpc_samr_DeleteDomainGroup(b, mem_ctx,
1794                                                        &group_pol,
1795                                                        &result);
1796                 if (!NT_STATUS_IS_OK(status)) {
1797                         break;
1798                 }
1799
1800                 status = result;
1801
1802                 break;
1803         /* removing a local group is easier... */
1804         case SID_NAME_ALIAS:
1805                 status = dcerpc_samr_OpenAlias(b, mem_ctx,
1806                                                &domain_pol,
1807                                                MAXIMUM_ALLOWED_ACCESS,
1808                                                group_rids.ids[0],
1809                                                &group_pol,
1810                                                &result);
1811                 if (!NT_STATUS_IS_OK(status)) {
1812                         d_fprintf(stderr, _("Request open_alias failed\n"));
1813                         goto done;
1814                 }
1815                 if (!NT_STATUS_IS_OK(result)) {
1816                         status = result;
1817                         d_fprintf(stderr, _("Request open_alias failed\n"));
1818                         goto done;
1819                 }
1820
1821                 status = dcerpc_samr_DeleteDomAlias(b, mem_ctx,
1822                                                     &group_pol,
1823                                                     &result);
1824                 if (!NT_STATUS_IS_OK(status)) {
1825                         break;
1826                 }
1827
1828                 status = result;
1829
1830                 break;
1831         default:
1832                 d_fprintf(stderr, _("%s is of type %s. This command is only "
1833                                     "for deleting local or global groups\n"),
1834                         argv[0],sid_type_lookup(name_types.ids[0]));
1835                 status = NT_STATUS_UNSUCCESSFUL;
1836                 goto done;
1837         }
1838
1839         if (NT_STATUS_IS_OK(status)) {
1840                 if (c->opt_verbose)
1841                         d_printf(_("Deleted %s '%s'\n"),
1842                                  sid_type_lookup(name_types.ids[0]), argv[0]);
1843         } else {
1844                 d_fprintf(stderr, _("Deleting of %s failed: %s\n"), argv[0],
1845                         get_friendly_nt_error_msg(status));
1846         }
1847
1848  done:
1849         return status;
1850
1851 }
1852
1853 static int rpc_group_delete(struct net_context *c, int argc, const char **argv)
1854 {
1855         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
1856                                rpc_group_delete_internals, argc,argv);
1857 }
1858
1859 static int rpc_group_add_internals(struct net_context *c, int argc, const char **argv)
1860 {
1861         NET_API_STATUS status;
1862         struct GROUP_INFO_1 info1;
1863         uint32_t parm_error = 0;
1864
1865         if (argc != 1 || c->display_usage) {
1866                 rpc_group_usage(c, argc, argv);
1867                 return 0;
1868         }
1869
1870         ZERO_STRUCT(info1);
1871
1872         info1.grpi1_name = argv[0];
1873         if (c->opt_comment && strlen(c->opt_comment) > 0) {
1874                 info1.grpi1_comment = c->opt_comment;
1875         }
1876
1877         status = NetGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1878
1879         if (status != 0) {
1880                 d_fprintf(stderr,
1881                         _("Failed to add group '%s' with error: %s.\n"),
1882                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
1883                                                             status));
1884                 return -1;
1885         } else {
1886                 d_printf(_("Added group '%s'.\n"), argv[0]);
1887         }
1888
1889         return 0;
1890 }
1891
1892 static int rpc_alias_add_internals(struct net_context *c, int argc, const char **argv)
1893 {
1894         NET_API_STATUS status;
1895         struct LOCALGROUP_INFO_1 info1;
1896         uint32_t parm_error = 0;
1897
1898         if (argc != 1 || c->display_usage) {
1899                 rpc_group_usage(c, argc, argv);
1900                 return 0;
1901         }
1902
1903         ZERO_STRUCT(info1);
1904
1905         info1.lgrpi1_name = argv[0];
1906         if (c->opt_comment && strlen(c->opt_comment) > 0) {
1907                 info1.lgrpi1_comment = c->opt_comment;
1908         }
1909
1910         status = NetLocalGroupAdd(c->opt_host, 1, (uint8_t *)&info1, &parm_error);
1911
1912         if (status != 0) {
1913                 d_fprintf(stderr,
1914                         _("Failed to add alias '%s' with error: %s.\n"),
1915                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
1916                                                             status));
1917                 return -1;
1918         } else {
1919                 d_printf(_("Added alias '%s'.\n"), argv[0]);
1920         }
1921
1922         return 0;
1923 }
1924
1925 static int rpc_group_add(struct net_context *c, int argc, const char **argv)
1926 {
1927         if (c->opt_localgroup)
1928                 return rpc_alias_add_internals(c, argc, argv);
1929
1930         return rpc_group_add_internals(c, argc, argv);
1931 }
1932
1933 static NTSTATUS get_sid_from_name(struct cli_state *cli,
1934                                 TALLOC_CTX *mem_ctx,
1935                                 const char *name,
1936                                 struct dom_sid *sid,
1937                                 enum lsa_SidType *type)
1938 {
1939         struct dom_sid *sids = NULL;
1940         enum lsa_SidType *types = NULL;
1941         struct rpc_pipe_client *pipe_hnd = NULL;
1942         struct policy_handle lsa_pol;
1943         NTSTATUS status, result;
1944         struct dcerpc_binding_handle *b;
1945
1946         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
1947                                           &pipe_hnd);
1948         if (!NT_STATUS_IS_OK(status)) {
1949                 goto done;
1950         }
1951
1952         b = pipe_hnd->binding_handle;
1953
1954         status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, false,
1955                                      SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
1956
1957         if (!NT_STATUS_IS_OK(status)) {
1958                 goto done;
1959         }
1960
1961         status = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
1962                                       &name, NULL, 1, &sids, &types);
1963
1964         if (NT_STATUS_IS_OK(status)) {
1965                 sid_copy(sid, &sids[0]);
1966                 *type = types[0];
1967         }
1968
1969         dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
1970
1971  done:
1972         if (pipe_hnd) {
1973                 TALLOC_FREE(pipe_hnd);
1974         }
1975
1976         if (!NT_STATUS_IS_OK(status) && (StrnCaseCmp(name, "S-", 2) == 0)) {
1977
1978                 /* Try as S-1-5-whatever */
1979
1980                 struct dom_sid tmp_sid;
1981
1982                 if (string_to_sid(&tmp_sid, name)) {
1983                         sid_copy(sid, &tmp_sid);
1984                         *type = SID_NAME_UNKNOWN;
1985                         status = NT_STATUS_OK;
1986                 }
1987         }
1988
1989         return status;
1990 }
1991
1992 static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
1993                                 TALLOC_CTX *mem_ctx,
1994                                 const struct dom_sid *group_sid,
1995                                 const char *member)
1996 {
1997         struct policy_handle connect_pol, domain_pol;
1998         NTSTATUS status, result;
1999         uint32 group_rid;
2000         struct policy_handle group_pol;
2001         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2002
2003         struct samr_Ids rids, rid_types;
2004         struct lsa_String lsa_acct_name;
2005
2006         struct dom_sid sid;
2007
2008         sid_copy(&sid, group_sid);
2009
2010         if (!sid_split_rid(&sid, &group_rid)) {
2011                 return NT_STATUS_UNSUCCESSFUL;
2012         }
2013
2014         /* Get sam policy handle */
2015         status = dcerpc_samr_Connect2(b, mem_ctx,
2016                                       pipe_hnd->desthost,
2017                                       MAXIMUM_ALLOWED_ACCESS,
2018                                       &connect_pol,
2019                                       &result);
2020         if (!NT_STATUS_IS_OK(status)) {
2021                 return status;
2022         }
2023         if (!NT_STATUS_IS_OK(result)) {
2024                 return result;
2025         }
2026
2027         /* Get domain policy handle */
2028         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2029                                         &connect_pol,
2030                                         MAXIMUM_ALLOWED_ACCESS,
2031                                         &sid,
2032                                         &domain_pol,
2033                                         &result);
2034         if (!NT_STATUS_IS_OK(status)) {
2035                 return status;
2036         }
2037         if (!NT_STATUS_IS_OK(result)) {
2038                 return result;
2039         }
2040
2041         init_lsa_String(&lsa_acct_name, member);
2042
2043         status = dcerpc_samr_LookupNames(b, mem_ctx,
2044                                          &domain_pol,
2045                                          1,
2046                                          &lsa_acct_name,
2047                                          &rids,
2048                                          &rid_types,
2049                                          &result);
2050         if (!NT_STATUS_IS_OK(status)) {
2051                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2052                           member);
2053                 goto done;
2054         }
2055
2056         if (!NT_STATUS_IS_OK(result)) {
2057                 status = result;
2058                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2059                           member);
2060                 goto done;
2061         }
2062
2063         status = dcerpc_samr_OpenGroup(b, mem_ctx,
2064                                        &domain_pol,
2065                                        MAXIMUM_ALLOWED_ACCESS,
2066                                        group_rid,
2067                                        &group_pol,
2068                                        &result);
2069         if (!NT_STATUS_IS_OK(status)) {
2070                 goto done;
2071         }
2072
2073         if (!NT_STATUS_IS_OK(result)) {
2074                 status = result;
2075                 goto done;
2076         }
2077
2078         status = dcerpc_samr_AddGroupMember(b, mem_ctx,
2079                                             &group_pol,
2080                                             rids.ids[0],
2081                                             0x0005, /* unknown flags */
2082                                             &result);
2083         if (!NT_STATUS_IS_OK(status)) {
2084                 goto done;
2085         }
2086
2087         status = result;
2088
2089  done:
2090         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2091         return status;
2092 }
2093
2094 static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
2095                                 TALLOC_CTX *mem_ctx,
2096                                 const struct dom_sid *alias_sid,
2097                                 const char *member)
2098 {
2099         struct policy_handle connect_pol, domain_pol;
2100         NTSTATUS status, result;
2101         uint32 alias_rid;
2102         struct policy_handle alias_pol;
2103         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2104
2105         struct dom_sid member_sid;
2106         enum lsa_SidType member_type;
2107
2108         struct dom_sid sid;
2109
2110         sid_copy(&sid, alias_sid);
2111
2112         if (!sid_split_rid(&sid, &alias_rid)) {
2113                 return NT_STATUS_UNSUCCESSFUL;
2114         }
2115
2116         result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2117                                    member, &member_sid, &member_type);
2118
2119         if (!NT_STATUS_IS_OK(result)) {
2120                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2121                           member);
2122                 return result;
2123         }
2124
2125         /* Get sam policy handle */
2126         status = dcerpc_samr_Connect2(b, mem_ctx,
2127                                       pipe_hnd->desthost,
2128                                       MAXIMUM_ALLOWED_ACCESS,
2129                                       &connect_pol,
2130                                       &result);
2131         if (!NT_STATUS_IS_OK(status)) {
2132                 goto done;
2133         }
2134         if (!NT_STATUS_IS_OK(result)) {
2135                 status = result;
2136                 goto done;
2137         }
2138
2139         /* Get domain policy handle */
2140         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2141                                         &connect_pol,
2142                                         MAXIMUM_ALLOWED_ACCESS,
2143                                         &sid,
2144                                         &domain_pol,
2145                                         &result);
2146         if (!NT_STATUS_IS_OK(status)) {
2147                 goto done;
2148         }
2149         if (!NT_STATUS_IS_OK(result)) {
2150                 status = result;
2151                 goto done;
2152         }
2153
2154         status = dcerpc_samr_OpenAlias(b, mem_ctx,
2155                                        &domain_pol,
2156                                        MAXIMUM_ALLOWED_ACCESS,
2157                                        alias_rid,
2158                                        &alias_pol,
2159                                        &result);
2160         if (!NT_STATUS_IS_OK(status)) {
2161                 return status;
2162         }
2163         if (!NT_STATUS_IS_OK(result)) {
2164                 return result;
2165         }
2166
2167         status = dcerpc_samr_AddAliasMember(b, mem_ctx,
2168                                             &alias_pol,
2169                                             &member_sid,
2170                                             &result);
2171         if (!NT_STATUS_IS_OK(status)) {
2172                 return status;
2173         }
2174
2175         status = result;
2176
2177  done:
2178         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2179         return status;
2180 }
2181
2182 static NTSTATUS rpc_group_addmem_internals(struct net_context *c,
2183                                         const struct dom_sid *domain_sid,
2184                                         const char *domain_name,
2185                                         struct cli_state *cli,
2186                                         struct rpc_pipe_client *pipe_hnd,
2187                                         TALLOC_CTX *mem_ctx,
2188                                         int argc,
2189                                         const char **argv)
2190 {
2191         struct dom_sid group_sid;
2192         enum lsa_SidType group_type;
2193
2194         if (argc != 2 || c->display_usage) {
2195                 d_printf("%s\n%s",
2196                          _("Usage:"),
2197                          _("net rpc group addmem <group> <member>\n"
2198                            "  Add a member to a group\n"
2199                            "    group\tGroup to add member to\n"
2200                            "    member\tMember to add to group\n"));
2201                 return NT_STATUS_UNSUCCESSFUL;
2202         }
2203
2204         if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2205                                                &group_sid, &group_type))) {
2206                 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2207                           argv[0]);
2208                 return NT_STATUS_UNSUCCESSFUL;
2209         }
2210
2211         if (group_type == SID_NAME_DOM_GRP) {
2212                 NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
2213                                                    &group_sid, argv[1]);
2214
2215                 if (!NT_STATUS_IS_OK(result)) {
2216                         d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2217                                  argv[1], argv[0], nt_errstr(result));
2218                 }
2219                 return result;
2220         }
2221
2222         if (group_type == SID_NAME_ALIAS) {
2223                 NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
2224                                                    &group_sid, argv[1]);
2225
2226                 if (!NT_STATUS_IS_OK(result)) {
2227                         d_fprintf(stderr, _("Could not add %s to %s: %s\n"),
2228                                  argv[1], argv[0], nt_errstr(result));
2229                 }
2230                 return result;
2231         }
2232
2233         d_fprintf(stderr, _("Can only add members to global or local groups "
2234                  "which %s is not\n"), argv[0]);
2235
2236         return NT_STATUS_UNSUCCESSFUL;
2237 }
2238
2239 static int rpc_group_addmem(struct net_context *c, int argc, const char **argv)
2240 {
2241         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2242                                rpc_group_addmem_internals,
2243                                argc, argv);
2244 }
2245
2246 static NTSTATUS rpc_del_groupmem(struct net_context *c,
2247                                 struct rpc_pipe_client *pipe_hnd,
2248                                 TALLOC_CTX *mem_ctx,
2249                                 const struct dom_sid *group_sid,
2250                                 const char *member)
2251 {
2252         struct policy_handle connect_pol, domain_pol;
2253         NTSTATUS status, result;
2254         uint32 group_rid;
2255         struct policy_handle group_pol;
2256         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2257
2258         struct samr_Ids rids, rid_types;
2259         struct lsa_String lsa_acct_name;
2260
2261         struct dom_sid sid;
2262
2263         sid_copy(&sid, group_sid);
2264
2265         if (!sid_split_rid(&sid, &group_rid))
2266                 return NT_STATUS_UNSUCCESSFUL;
2267
2268         /* Get sam policy handle */
2269         status = dcerpc_samr_Connect2(b, mem_ctx,
2270                                       pipe_hnd->desthost,
2271                                       MAXIMUM_ALLOWED_ACCESS,
2272                                       &connect_pol,
2273                                       &result);
2274         if (!NT_STATUS_IS_OK(status)) {
2275                 return status;
2276         }
2277         if (!NT_STATUS_IS_OK(result)) {
2278                 return result;
2279         }
2280
2281
2282         /* Get domain policy handle */
2283         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2284                                         &connect_pol,
2285                                         MAXIMUM_ALLOWED_ACCESS,
2286                                         &sid,
2287                                         &domain_pol,
2288                                         &result);
2289         if (!NT_STATUS_IS_OK(status)) {
2290                 return status;
2291         }
2292         if (!NT_STATUS_IS_OK(result)) {
2293                 return result;
2294         }
2295
2296         init_lsa_String(&lsa_acct_name, member);
2297
2298         status = dcerpc_samr_LookupNames(b, mem_ctx,
2299                                          &domain_pol,
2300                                          1,
2301                                          &lsa_acct_name,
2302                                          &rids,
2303                                          &rid_types,
2304                                          &result);
2305         if (!NT_STATUS_IS_OK(status)) {
2306                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2307                           member);
2308                 goto done;
2309         }
2310
2311         if (!NT_STATUS_IS_OK(result)) {
2312                 status = result;
2313                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2314                           member);
2315                 goto done;
2316         }
2317
2318         status = dcerpc_samr_OpenGroup(b, mem_ctx,
2319                                        &domain_pol,
2320                                        MAXIMUM_ALLOWED_ACCESS,
2321                                        group_rid,
2322                                        &group_pol,
2323                                        &result);
2324         if (!NT_STATUS_IS_OK(status)) {
2325                 goto done;
2326         }
2327         if (!NT_STATUS_IS_OK(result)) {
2328                 status = result;
2329                 goto done;
2330         }
2331
2332         status = dcerpc_samr_DeleteGroupMember(b, mem_ctx,
2333                                                &group_pol,
2334                                                rids.ids[0],
2335                                                &result);
2336         if (!NT_STATUS_IS_OK(status)) {
2337                 goto done;
2338         }
2339
2340         status = result;
2341  done:
2342         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2343         return status;
2344 }
2345
2346 static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
2347                                 TALLOC_CTX *mem_ctx,
2348                                 const struct dom_sid *alias_sid,
2349                                 const char *member)
2350 {
2351         struct policy_handle connect_pol, domain_pol;
2352         NTSTATUS status, result;
2353         uint32 alias_rid;
2354         struct policy_handle alias_pol;
2355         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2356
2357         struct dom_sid member_sid;
2358         enum lsa_SidType member_type;
2359
2360         struct dom_sid sid;
2361
2362         sid_copy(&sid, alias_sid);
2363
2364         if (!sid_split_rid(&sid, &alias_rid))
2365                 return NT_STATUS_UNSUCCESSFUL;
2366
2367         result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
2368                                    member, &member_sid, &member_type);
2369
2370         if (!NT_STATUS_IS_OK(result)) {
2371                 d_fprintf(stderr, _("Could not lookup up group member %s\n"),
2372                           member);
2373                 return result;
2374         }
2375
2376         /* Get sam policy handle */
2377         status = dcerpc_samr_Connect2(b, mem_ctx,
2378                                       pipe_hnd->desthost,
2379                                       MAXIMUM_ALLOWED_ACCESS,
2380                                       &connect_pol,
2381                                       &result);
2382         if (!NT_STATUS_IS_OK(status)) {
2383                 goto done;
2384         }
2385         if (!NT_STATUS_IS_OK(result)) {
2386                 status = result;
2387                 goto done;
2388         }
2389
2390         /* Get domain policy handle */
2391         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2392                                         &connect_pol,
2393                                         MAXIMUM_ALLOWED_ACCESS,
2394                                         &sid,
2395                                         &domain_pol,
2396                                         &result);
2397         if (!NT_STATUS_IS_OK(status)) {
2398                 goto done;
2399         }
2400         if (!NT_STATUS_IS_OK(result)) {
2401                 status = result;
2402                 goto done;
2403         }
2404
2405         status = dcerpc_samr_OpenAlias(b, mem_ctx,
2406                                        &domain_pol,
2407                                        MAXIMUM_ALLOWED_ACCESS,
2408                                        alias_rid,
2409                                        &alias_pol,
2410                                        &result);
2411         if (!NT_STATUS_IS_OK(status)) {
2412                 return status;
2413         }
2414
2415         if (!NT_STATUS_IS_OK(result)) {
2416                 return result;
2417         }
2418
2419         status = dcerpc_samr_DeleteAliasMember(b, mem_ctx,
2420                                                &alias_pol,
2421                                                &member_sid,
2422                                                &result);
2423
2424         if (!NT_STATUS_IS_OK(status)) {
2425                 return status;
2426         }
2427
2428         status = result;
2429
2430  done:
2431         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
2432         return status;
2433 }
2434
2435 static NTSTATUS rpc_group_delmem_internals(struct net_context *c,
2436                                         const struct dom_sid *domain_sid,
2437                                         const char *domain_name,
2438                                         struct cli_state *cli,
2439                                         struct rpc_pipe_client *pipe_hnd,
2440                                         TALLOC_CTX *mem_ctx,
2441                                         int argc,
2442                                         const char **argv)
2443 {
2444         struct dom_sid group_sid;
2445         enum lsa_SidType group_type;
2446
2447         if (argc != 2 || c->display_usage) {
2448                 d_printf("%s\n%s",
2449                          _("Usage:"),
2450                          _("net rpc group delmem <group> <member>\n"
2451                            "  Delete a member from a group\n"
2452                            "    group\tGroup to delete member from\n"
2453                            "    member\tMember to delete from group\n"));
2454                 return NT_STATUS_UNSUCCESSFUL;
2455         }
2456
2457         if (!NT_STATUS_IS_OK(get_sid_from_name(cli, mem_ctx, argv[0],
2458                                                &group_sid, &group_type))) {
2459                 d_fprintf(stderr, _("Could not lookup group name %s\n"),
2460                           argv[0]);
2461                 return NT_STATUS_UNSUCCESSFUL;
2462         }
2463
2464         if (group_type == SID_NAME_DOM_GRP) {
2465                 NTSTATUS result = rpc_del_groupmem(c, pipe_hnd, mem_ctx,
2466                                                    &group_sid, argv[1]);
2467
2468                 if (!NT_STATUS_IS_OK(result)) {
2469                         d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2470                                  argv[1], argv[0], nt_errstr(result));
2471                 }
2472                 return result;
2473         }
2474
2475         if (group_type == SID_NAME_ALIAS) {
2476                 NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
2477                                                    &group_sid, argv[1]);
2478
2479                 if (!NT_STATUS_IS_OK(result)) {
2480                         d_fprintf(stderr, _("Could not del %s from %s: %s\n"),
2481                                  argv[1], argv[0], nt_errstr(result));
2482                 }
2483                 return result;
2484         }
2485
2486         d_fprintf(stderr, _("Can only delete members from global or local "
2487                  "groups which %s is not\n"), argv[0]);
2488
2489         return NT_STATUS_UNSUCCESSFUL;
2490 }
2491
2492 static int rpc_group_delmem(struct net_context *c, int argc, const char **argv)
2493 {
2494         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2495                                rpc_group_delmem_internals,
2496                                argc, argv);
2497 }
2498
2499 /**
2500  * List groups on a remote RPC server.
2501  *
2502  * All parameters are provided by the run_rpc_command function, except for
2503  * argc, argv which are passes through.
2504  *
2505  * @param domain_sid The domain sid acquired from the remote server.
2506  * @param cli A cli_state connected to the server.
2507  * @param mem_ctx Talloc context, destroyed on completion of the function.
2508  * @param argc  Standard main() style argc.
2509  * @param argv  Standard main() style argv. Initial components are already
2510  *              stripped.
2511  *
2512  * @return Normal NTSTATUS return.
2513  **/
2514
2515 static NTSTATUS rpc_group_list_internals(struct net_context *c,
2516                                         const struct dom_sid *domain_sid,
2517                                         const char *domain_name,
2518                                         struct cli_state *cli,
2519                                         struct rpc_pipe_client *pipe_hnd,
2520                                         TALLOC_CTX *mem_ctx,
2521                                         int argc,
2522                                         const char **argv)
2523 {
2524         struct policy_handle connect_pol, domain_pol;
2525         NTSTATUS status, result;
2526         uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
2527         struct samr_SamArray *groups = NULL;
2528         bool global = false;
2529         bool local = false;
2530         bool builtin = false;
2531         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2532
2533         if (c->display_usage) {
2534                 d_printf("%s\n%s",
2535                          _("Usage:"),
2536                          _("net rpc group list [global] [local] [builtin]\n"
2537                            "  List groups on RPC server\n"
2538                            "    global\tList global groups\n"
2539                            "    local\tList local groups\n"
2540                            "    builtin\tList builtin groups\n"
2541                            "    If none of global, local or builtin is "
2542                            "specified, all three options are considered "
2543                            "set\n"));
2544                 return NT_STATUS_OK;
2545         }
2546
2547         if (argc == 0) {
2548                 global = true;
2549                 local = true;
2550                 builtin = true;
2551         }
2552
2553         for (i=0; i<argc; i++) {
2554                 if (strequal(argv[i], "global"))
2555                         global = true;
2556
2557                 if (strequal(argv[i], "local"))
2558                         local = true;
2559
2560                 if (strequal(argv[i], "builtin"))
2561                         builtin = true;
2562         }
2563
2564         /* Get sam policy handle */
2565
2566         status = dcerpc_samr_Connect2(b, mem_ctx,
2567                                       pipe_hnd->desthost,
2568                                       MAXIMUM_ALLOWED_ACCESS,
2569                                       &connect_pol,
2570                                       &result);
2571         if (!NT_STATUS_IS_OK(status)) {
2572                 goto done;
2573         }
2574         if (!NT_STATUS_IS_OK(result)) {
2575                 status = result;
2576                 goto done;
2577         }
2578
2579         /* Get domain policy handle */
2580
2581         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2582                                         &connect_pol,
2583                                         MAXIMUM_ALLOWED_ACCESS,
2584                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
2585                                         &domain_pol,
2586                                         &result);
2587         if (!NT_STATUS_IS_OK(status)) {
2588                 goto done;
2589         }
2590         if (!NT_STATUS_IS_OK(result)) {
2591                 status = result;
2592                 goto done;
2593         }
2594
2595         /* Query domain groups */
2596         if (c->opt_long_list_entries)
2597                 d_printf(_("\nGroup name            Comment"
2598                            "\n-----------------------------\n"));
2599         do {
2600                 uint32_t max_size, total_size, returned_size;
2601                 union samr_DispInfo info;
2602
2603                 if (!global) break;
2604
2605                 dcerpc_get_query_dispinfo_params(
2606                         loop_count, &max_entries, &max_size);
2607
2608                 status = dcerpc_samr_QueryDisplayInfo(b, mem_ctx,
2609                                                       &domain_pol,
2610                                                       3,
2611                                                       start_idx,
2612                                                       max_entries,
2613                                                       max_size,
2614                                                       &total_size,
2615                                                       &returned_size,
2616                                                       &info,
2617                                                       &result);
2618                 if (!NT_STATUS_IS_OK(status)) {
2619                         goto done;
2620                 }
2621                 num_entries = info.info3.count;
2622                 start_idx += info.info3.count;
2623
2624                 if (!NT_STATUS_IS_OK(result) &&
2625                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2626                         break;
2627
2628                 for (i = 0; i < num_entries; i++) {
2629
2630                         const char *group = NULL;
2631                         const char *desc = NULL;
2632
2633                         group = info.info3.entries[i].account_name.string;
2634                         desc = info.info3.entries[i].description.string;
2635
2636                         if (c->opt_long_list_entries)
2637                                 printf("%-21.21s %-50.50s\n",
2638                                        group, desc);
2639                         else
2640                                 printf("%s\n", group);
2641                 }
2642         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2643         /* query domain aliases */
2644         start_idx = 0;
2645         do {
2646                 if (!local) break;
2647
2648                 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2649                                                        &domain_pol,
2650                                                        &start_idx,
2651                                                        &groups,
2652                                                        0xffff,
2653                                                        &num_entries,
2654                                                        &result);
2655                 if (!NT_STATUS_IS_OK(status)) {
2656                         goto done;
2657                 }
2658                 if (!NT_STATUS_IS_OK(result) &&
2659                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
2660                         break;
2661
2662                 for (i = 0; i < num_entries; i++) {
2663
2664                         const char *description = NULL;
2665
2666                         if (c->opt_long_list_entries) {
2667
2668                                 struct policy_handle alias_pol;
2669                                 union samr_AliasInfo *info = NULL;
2670                                 NTSTATUS _result;
2671
2672                                 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2673                                                                &domain_pol,
2674                                                                0x8,
2675                                                                groups->entries[i].idx,
2676                                                                &alias_pol,
2677                                                                &_result);
2678                                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2679                                         status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
2680                                                                             &alias_pol,
2681                                                                             3,
2682                                                                             &info,
2683                                                                             &_result);
2684                                         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2685                                                 status = dcerpc_samr_Close(b, mem_ctx,
2686                                                                            &alias_pol,
2687                                                                            &_result);
2688                                                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2689                                                         description = info->description.string;
2690                                                 }
2691                                         }
2692                                 }
2693                         }
2694
2695                         if (description != NULL) {
2696                                 printf("%-21.21s %-50.50s\n",
2697                                        groups->entries[i].name.string,
2698                                        description);
2699                         } else {
2700                                 printf("%s\n", groups->entries[i].name.string);
2701                         }
2702                 }
2703         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2704         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
2705         /* Get builtin policy handle */
2706
2707         status = dcerpc_samr_OpenDomain(b, mem_ctx,
2708                                         &connect_pol,
2709                                         MAXIMUM_ALLOWED_ACCESS,
2710                                         CONST_DISCARD(struct dom_sid2 *, &global_sid_Builtin),
2711                                         &domain_pol,
2712                                         &result);
2713         if (!NT_STATUS_IS_OK(status)) {
2714                 goto done;
2715         }
2716         if (!NT_STATUS_IS_OK(result)) {
2717                 status = result;
2718                 goto done;
2719         }
2720
2721         /* query builtin aliases */
2722         start_idx = 0;
2723         do {
2724                 if (!builtin) break;
2725
2726                 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
2727                                                        &domain_pol,
2728                                                        &start_idx,
2729                                                        &groups,
2730                                                        max_entries,
2731                                                        &num_entries,
2732                                                        &result);
2733                 if (!NT_STATUS_IS_OK(status)) {
2734                         break;
2735                 }
2736                 if (!NT_STATUS_IS_OK(result) &&
2737                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
2738                         status = result;
2739                         break;
2740                 }
2741
2742                 for (i = 0; i < num_entries; i++) {
2743
2744                         const char *description = NULL;
2745
2746                         if (c->opt_long_list_entries) {
2747
2748                                 struct policy_handle alias_pol;
2749                                 union samr_AliasInfo *info = NULL;
2750                                 NTSTATUS _result;
2751
2752                                 status = dcerpc_samr_OpenAlias(b, mem_ctx,
2753                                                                &domain_pol,
2754                                                                0x8,
2755                                                                groups->entries[i].idx,
2756                                                                &alias_pol,
2757                                                                &_result);
2758                                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2759                                         status = dcerpc_samr_QueryAliasInfo(b, mem_ctx,
2760                                                                             &alias_pol,
2761                                                                             3,
2762                                                                             &info,
2763                                                                             &_result);
2764                                         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2765                                                 status = dcerpc_samr_Close(b, mem_ctx,
2766                                                                            &alias_pol,
2767                                                                            &_result);
2768                                                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(_result)) {
2769                                                         description = info->description.string;
2770                                                 }
2771                                         }
2772                                 }
2773                         }
2774
2775                         if (description != NULL) {
2776                                 printf("%-21.21s %-50.50s\n",
2777                                        groups->entries[i].name.string,
2778                                        description);
2779                         } else {
2780                                 printf("%s\n", groups->entries[i].name.string);
2781                         }
2782                 }
2783         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
2784
2785         status = result;
2786
2787  done:
2788         return status;
2789 }
2790
2791 static int rpc_group_list(struct net_context *c, int argc, const char **argv)
2792 {
2793         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
2794                                rpc_group_list_internals,
2795                                argc, argv);
2796 }
2797
2798 static NTSTATUS rpc_list_group_members(struct net_context *c,
2799                                         struct rpc_pipe_client *pipe_hnd,
2800                                         TALLOC_CTX *mem_ctx,
2801                                         const char *domain_name,
2802                                         const struct dom_sid *domain_sid,
2803                                         struct policy_handle *domain_pol,
2804                                         uint32 rid)
2805 {
2806         NTSTATUS result, status;
2807         struct policy_handle group_pol;
2808         uint32 num_members, *group_rids;
2809         int i;
2810         struct samr_RidAttrArray *rids = NULL;
2811         struct lsa_Strings names;
2812         struct samr_Ids types;
2813         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2814
2815         fstring sid_str;
2816         sid_to_fstring(sid_str, domain_sid);
2817
2818         status = dcerpc_samr_OpenGroup(b, mem_ctx,
2819                                        domain_pol,
2820                                        MAXIMUM_ALLOWED_ACCESS,
2821                                        rid,
2822                                        &group_pol,
2823                                        &result);
2824         if (!NT_STATUS_IS_OK(status)) {
2825                 return status;
2826         }
2827         if (!NT_STATUS_IS_OK(result)) {
2828                 return result;
2829         }
2830
2831         status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
2832                                               &group_pol,
2833                                               &rids,
2834                                               &result);
2835         if (!NT_STATUS_IS_OK(status)) {
2836                 return status;
2837         }
2838         if (!NT_STATUS_IS_OK(result)) {
2839                 return result;
2840         }
2841
2842         num_members = rids->count;
2843         group_rids = rids->rids;
2844
2845         while (num_members > 0) {
2846                 int this_time = 512;
2847
2848                 if (num_members < this_time)
2849                         this_time = num_members;
2850
2851                 status = dcerpc_samr_LookupRids(b, mem_ctx,
2852                                                 domain_pol,
2853                                                 this_time,
2854                                                 group_rids,
2855                                                 &names,
2856                                                 &types,
2857                                                 &result);
2858                 if (!NT_STATUS_IS_OK(status)) {
2859                         return status;
2860                 }
2861                 if (!NT_STATUS_IS_OK(result)) {
2862                         return result;
2863                 }
2864
2865                 /* We only have users as members, but make the output
2866                    the same as the output of alias members */
2867
2868                 for (i = 0; i < this_time; i++) {
2869
2870                         if (c->opt_long_list_entries) {
2871                                 printf("%s-%d %s\\%s %d\n", sid_str,
2872                                        group_rids[i], domain_name,
2873                                        names.names[i].string,
2874                                        SID_NAME_USER);
2875                         } else {
2876                                 printf("%s\\%s\n", domain_name,
2877                                         names.names[i].string);
2878                         }
2879                 }
2880
2881                 num_members -= this_time;
2882                 group_rids += 512;
2883         }
2884
2885         return NT_STATUS_OK;
2886 }
2887
2888 static NTSTATUS rpc_list_alias_members(struct net_context *c,
2889                                         struct rpc_pipe_client *pipe_hnd,
2890                                         TALLOC_CTX *mem_ctx,
2891                                         struct policy_handle *domain_pol,
2892                                         uint32 rid)
2893 {
2894         NTSTATUS result, status;
2895         struct rpc_pipe_client *lsa_pipe;
2896         struct policy_handle alias_pol, lsa_pol;
2897         uint32 num_members;
2898         struct dom_sid *alias_sids;
2899         char **domains;
2900         char **names;
2901         enum lsa_SidType *types;
2902         int i;
2903         struct lsa_SidArray sid_array;
2904         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
2905
2906         status = dcerpc_samr_OpenAlias(b, mem_ctx,
2907                                        domain_pol,
2908                                        MAXIMUM_ALLOWED_ACCESS,
2909                                        rid,
2910                                        &alias_pol,
2911                                        &result);
2912         if (!NT_STATUS_IS_OK(status)) {
2913                 return status;
2914         }
2915         if (!NT_STATUS_IS_OK(result)) {
2916                 return result;
2917         }
2918
2919         status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
2920                                                &alias_pol,
2921                                                &sid_array,
2922                                                &result);
2923         if (!NT_STATUS_IS_OK(status)) {
2924                 d_fprintf(stderr, _("Couldn't list alias members\n"));
2925                 return status;
2926         }
2927         if (!NT_STATUS_IS_OK(result)) {
2928                 d_fprintf(stderr, _("Couldn't list alias members\n"));
2929                 return result;
2930         }
2931
2932         num_members = sid_array.num_sids;
2933
2934         if (num_members == 0) {
2935                 return NT_STATUS_OK;
2936         }
2937
2938         result = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd),
2939                                           &ndr_table_lsarpc.syntax_id,
2940                                           &lsa_pipe);
2941         if (!NT_STATUS_IS_OK(result)) {
2942                 d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
2943                         nt_errstr(result) );
2944                 return result;
2945         }
2946
2947         result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, true,
2948                                      SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol);
2949
2950         if (!NT_STATUS_IS_OK(result)) {
2951                 d_fprintf(stderr, _("Couldn't open LSA policy handle\n"));
2952                 TALLOC_FREE(lsa_pipe);
2953                 return result;
2954         }
2955
2956         alias_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);
2957         if (!alias_sids) {
2958                 d_fprintf(stderr, _("Out of memory\n"));
2959                 TALLOC_FREE(lsa_pipe);
2960                 return NT_STATUS_NO_MEMORY;
2961         }
2962
2963         for (i=0; i<num_members; i++) {
2964                 sid_copy(&alias_sids[i], sid_array.sids[i].sid);
2965         }
2966
2967         result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol,
2968                                      num_members,  alias_sids,
2969                                      &domains, &names, &types);
2970
2971         if (!NT_STATUS_IS_OK(result) &&
2972             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
2973                 d_fprintf(stderr, _("Couldn't lookup SIDs\n"));
2974                 TALLOC_FREE(lsa_pipe);
2975                 return result;
2976         }
2977
2978         for (i = 0; i < num_members; i++) {
2979                 fstring sid_str;
2980                 sid_to_fstring(sid_str, &alias_sids[i]);
2981
2982                 if (c->opt_long_list_entries) {
2983                         printf("%s %s\\%s %d\n", sid_str,
2984                                domains[i] ? domains[i] : _("*unknown*"),
2985                                names[i] ? names[i] : _("*unknown*"), types[i]);
2986                 } else {
2987                         if (domains[i])
2988                                 printf("%s\\%s\n", domains[i], names[i]);
2989                         else
2990                                 printf("%s\n", sid_str);
2991                 }
2992         }
2993
2994         TALLOC_FREE(lsa_pipe);
2995         return NT_STATUS_OK;
2996 }
2997
2998 static NTSTATUS rpc_group_members_internals(struct net_context *c,
2999                                         const struct dom_sid *domain_sid,
3000                                         const char *domain_name,
3001                                         struct cli_state *cli,
3002                                         struct rpc_pipe_client *pipe_hnd,
3003                                         TALLOC_CTX *mem_ctx,
3004                                         int argc,
3005                                         const char **argv)
3006 {
3007         NTSTATUS result, status;
3008         struct policy_handle connect_pol, domain_pol;
3009         struct samr_Ids rids, rid_types;
3010         struct lsa_String lsa_acct_name;
3011         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3012
3013         /* Get sam policy handle */
3014
3015         status = dcerpc_samr_Connect2(b, mem_ctx,
3016                                       pipe_hnd->desthost,
3017                                       MAXIMUM_ALLOWED_ACCESS,
3018                                       &connect_pol,
3019                                       &result);
3020         if (!NT_STATUS_IS_OK(status)) {
3021                 return status;
3022         }
3023         if (!NT_STATUS_IS_OK(result)) {
3024                 return result;
3025         }
3026
3027         /* Get domain policy handle */
3028
3029         status = dcerpc_samr_OpenDomain(b, mem_ctx,
3030                                         &connect_pol,
3031                                         MAXIMUM_ALLOWED_ACCESS,
3032                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
3033                                         &domain_pol,
3034                                         &result);
3035         if (!NT_STATUS_IS_OK(status)) {
3036                 return status;
3037         }
3038         if (!NT_STATUS_IS_OK(result)) {
3039                 return result;
3040         }
3041
3042         init_lsa_String(&lsa_acct_name, argv[0]); /* sure? */
3043
3044         status = dcerpc_samr_LookupNames(b, mem_ctx,
3045                                          &domain_pol,
3046                                          1,
3047                                          &lsa_acct_name,
3048                                          &rids,
3049                                          &rid_types,
3050                                          &result);
3051         if (!NT_STATUS_IS_OK(status)) {
3052                 return status;
3053         }
3054
3055         if (!NT_STATUS_IS_OK(result)) {
3056
3057                 /* Ok, did not find it in the global sam, try with builtin */
3058
3059                 struct dom_sid sid_Builtin;
3060
3061                 dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
3062
3063                 sid_copy(&sid_Builtin, &global_sid_Builtin);
3064
3065                 status = dcerpc_samr_OpenDomain(b, mem_ctx,
3066                                                 &connect_pol,
3067                                                 MAXIMUM_ALLOWED_ACCESS,
3068                                                 &sid_Builtin,
3069                                                 &domain_pol,
3070                                                 &result);
3071                 if (!NT_STATUS_IS_OK(status)) {
3072                         return status;
3073                 }
3074                 if (!NT_STATUS_IS_OK(result)) {
3075                         d_fprintf(stderr, _("Couldn't find group %s\n"),
3076                                   argv[0]);
3077                         return result;
3078                 }
3079
3080                 status = dcerpc_samr_LookupNames(b, mem_ctx,
3081                                                  &domain_pol,
3082                                                  1,
3083                                                  &lsa_acct_name,
3084                                                  &rids,
3085                                                  &rid_types,
3086                                                  &result);
3087                 if (!NT_STATUS_IS_OK(status)) {
3088                         return status;
3089                 }
3090                 if (!NT_STATUS_IS_OK(result)) {
3091                         d_fprintf(stderr, _("Couldn't find group %s\n"),
3092                                   argv[0]);
3093                         return result;
3094                 }
3095         }
3096
3097         if (rids.count != 1) {
3098                 d_fprintf(stderr, _("Couldn't find group %s\n"),
3099                           argv[0]);
3100                 return result;
3101         }
3102
3103         if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
3104                 return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
3105                                               domain_sid, &domain_pol,
3106                                               rids.ids[0]);
3107         }
3108
3109         if (rid_types.ids[0] == SID_NAME_ALIAS) {
3110                 return rpc_list_alias_members(c, pipe_hnd, mem_ctx, &domain_pol,
3111                                               rids.ids[0]);
3112         }
3113
3114         return NT_STATUS_NO_SUCH_GROUP;
3115 }
3116
3117 static int rpc_group_members(struct net_context *c, int argc, const char **argv)
3118 {
3119         if (argc != 1 || c->display_usage) {
3120                 return rpc_group_usage(c, argc, argv);
3121         }
3122
3123         return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
3124                                rpc_group_members_internals,
3125                                argc, argv);
3126 }
3127
3128 static int rpc_group_rename_internals(struct net_context *c, int argc, const char **argv)
3129 {
3130         NET_API_STATUS status;
3131         struct GROUP_INFO_0 g0;
3132         uint32_t parm_err;
3133
3134         if (argc != 2) {
3135                 d_printf(_("Usage:\n"));
3136                 d_printf("net rpc group rename group newname\n");
3137                 return -1;
3138         }
3139
3140         g0.grpi0_name = argv[1];
3141
3142         status = NetGroupSetInfo(c->opt_host,
3143                                  argv[0],
3144                                  0,
3145                                  (uint8_t *)&g0,
3146                                  &parm_err);
3147
3148         if (status != 0) {
3149                 d_fprintf(stderr, _("Renaming group %s failed with: %s\n"),
3150                         argv[0], libnetapi_get_error_string(c->netapi_ctx,
3151                         status));
3152                 return -1;
3153         }
3154
3155         return 0;
3156 }
3157
3158 static int rpc_group_rename(struct net_context *c, int argc, const char **argv)
3159 {
3160         if (argc != 2 || c->display_usage) {
3161                 return rpc_group_usage(c, argc, argv);
3162         }
3163
3164         return rpc_group_rename_internals(c, argc, argv);
3165 }
3166
3167 /**
3168  * 'net rpc group' entrypoint.
3169  * @param argc  Standard main() style argc.
3170  * @param argv  Standard main() style argv. Initial components are already
3171  *              stripped.
3172  **/
3173
3174 int net_rpc_group(struct net_context *c, int argc, const char **argv)
3175 {
3176         NET_API_STATUS status;
3177
3178         struct functable func[] = {
3179                 {
3180                         "add",
3181                         rpc_group_add,
3182                         NET_TRANSPORT_RPC,
3183                         N_("Create specified group"),
3184                         N_("net rpc group add\n"
3185                            "    Create specified group")
3186                 },
3187                 {
3188                         "delete",
3189                         rpc_group_delete,
3190                         NET_TRANSPORT_RPC,
3191                         N_("Delete specified group"),
3192                         N_("net rpc group delete\n"
3193                            "    Delete specified group")
3194                 },
3195                 {
3196                         "addmem",
3197                         rpc_group_addmem,
3198                         NET_TRANSPORT_RPC,
3199                         N_("Add member to group"),
3200                         N_("net rpc group addmem\n"
3201                            "    Add member to group")
3202                 },
3203                 {
3204                         "delmem",
3205                         rpc_group_delmem,
3206                         NET_TRANSPORT_RPC,
3207                         N_("Remove member from group"),
3208                         N_("net rpc group delmem\n"
3209                            "    Remove member from group")
3210                 },
3211                 {
3212                         "list",
3213                         rpc_group_list,
3214                         NET_TRANSPORT_RPC,
3215                         N_("List groups"),
3216                         N_("net rpc group list\n"
3217                            "    List groups")
3218                 },
3219                 {
3220                         "members",
3221                         rpc_group_members,
3222                         NET_TRANSPORT_RPC,
3223                         N_("List group members"),
3224                         N_("net rpc group members\n"
3225                            "    List group members")
3226                 },
3227                 {
3228                         "rename",
3229                         rpc_group_rename,
3230                         NET_TRANSPORT_RPC,
3231                         N_("Rename group"),
3232                         N_("net rpc group rename\n"
3233                            "    Rename group")
3234                 },
3235                 {NULL, NULL, 0, NULL, NULL}
3236         };
3237
3238         status = libnetapi_net_init(&c->netapi_ctx);
3239         if (status != 0) {
3240                 return -1;
3241         }
3242         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
3243         libnetapi_set_password(c->netapi_ctx, c->opt_password);
3244         if (c->opt_kerberos) {
3245                 libnetapi_set_use_kerberos(c->netapi_ctx);
3246         }
3247
3248         if (argc == 0) {
3249                 if (c->display_usage) {
3250                         d_printf(_("Usage:\n"));
3251                         d_printf(_("net rpc group\n"
3252                                    "    Alias for net rpc group list global "
3253                                    "local builtin\n"));
3254                         net_display_usage_from_functable(func);
3255                         return 0;
3256                 }
3257
3258                 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
3259                                        rpc_group_list_internals,
3260                                        argc, argv);
3261         }
3262
3263         return net_run_function(c, argc, argv, "net rpc group", func);
3264 }
3265
3266 /****************************************************************************/
3267
3268 static int rpc_share_usage(struct net_context *c, int argc, const char **argv)
3269 {
3270         return net_share_usage(c, argc, argv);
3271 }
3272
3273 /**
3274  * Add a share on a remote RPC server.
3275  *
3276  * @param argc  Standard main() style argc.
3277  * @param argv  Standard main() style argv. Initial components are already
3278  *              stripped.
3279  *
3280  * @return A shell status integer (0 for success).
3281  **/
3282
3283 static int rpc_share_add(struct net_context *c, int argc, const char **argv)
3284 {
3285         NET_API_STATUS status;
3286         char *sharename;
3287         char *path;
3288         uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
3289         uint32 num_users=0, perms=0;
3290         char *password=NULL; /* don't allow a share password */
3291         struct SHARE_INFO_2 i2;
3292         uint32_t parm_error = 0;
3293
3294         if ((argc < 1) || !strchr(argv[0], '=') || c->display_usage) {
3295                 return rpc_share_usage(c, argc, argv);
3296         }
3297
3298         if ((sharename = talloc_strdup(c, argv[0])) == NULL) {
3299                 return -1;
3300         }
3301
3302         path = strchr(sharename, '=');
3303         if (!path) {
3304                 return -1;
3305         }
3306
3307         *path++ = '\0';
3308
3309         i2.shi2_netname         = sharename;
3310         i2.shi2_type            = type;
3311         i2.shi2_remark          = c->opt_comment;
3312         i2.shi2_permissions     = perms;
3313         i2.shi2_max_uses        = c->opt_maxusers;
3314         i2.shi2_current_uses    = num_users;
3315         i2.shi2_path            = path;
3316         i2.shi2_passwd          = password;
3317
3318         status = NetShareAdd(c->opt_host,
3319                              2,
3320                              (uint8_t *)&i2,
3321                              &parm_error);
3322         if (status != 0) {
3323                 printf(_("NetShareAdd failed with: %s\n"),
3324                         libnetapi_get_error_string(c->netapi_ctx, status));
3325         }
3326
3327         return status;
3328 }
3329
3330 /**
3331  * Delete a share on a remote RPC server.
3332  *
3333  * @param domain_sid The domain sid acquired from the remote server.
3334  * @param argc  Standard main() style argc.
3335  * @param argv  Standard main() style argv. Initial components are already
3336  *              stripped.
3337  *
3338  * @return A shell status integer (0 for success).
3339  **/
3340 static int rpc_share_delete(struct net_context *c, int argc, const char **argv)
3341 {
3342         if (argc < 1 || c->display_usage) {
3343                 return rpc_share_usage(c, argc, argv);
3344         }
3345
3346         return NetShareDel(c->opt_host, argv[0], 0);
3347 }
3348
3349 /**
3350  * Formatted print of share info
3351  *
3352  * @param r  pointer to SHARE_INFO_1 to format
3353  **/
3354
3355 static void display_share_info_1(struct net_context *c,
3356                                  struct SHARE_INFO_1 *r)
3357 {
3358         if (c->opt_long_list_entries) {
3359                 d_printf("%-12s %-8.8s %-50s\n",
3360                          r->shi1_netname,
3361                          net_share_type_str(r->shi1_type & ~(STYPE_TEMPORARY|STYPE_HIDDEN)),
3362                          r->shi1_remark);
3363         } else {
3364                 d_printf("%s\n", r->shi1_netname);
3365         }
3366 }
3367
3368 static WERROR get_share_info(struct net_context *c,
3369                              struct rpc_pipe_client *pipe_hnd,
3370                              TALLOC_CTX *mem_ctx,
3371                              uint32 level,
3372                              int argc,
3373                              const char **argv,
3374                              struct srvsvc_NetShareInfoCtr *info_ctr)
3375 {
3376         WERROR result;
3377         NTSTATUS status;
3378         union srvsvc_NetShareInfo info;
3379         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
3380
3381         /* no specific share requested, enumerate all */
3382         if (argc == 0) {
3383
3384                 uint32_t preferred_len = 0xffffffff;
3385                 uint32_t total_entries = 0;
3386                 uint32_t resume_handle = 0;
3387
3388                 info_ctr->level = level;
3389
3390                 status = dcerpc_srvsvc_NetShareEnumAll(b, mem_ctx,
3391                                                        pipe_hnd->desthost,
3392                                                        info_ctr,
3393                                                        preferred_len,
3394                                                        &total_entries,
3395                                                        &resume_handle,
3396                                                        &result);
3397                 if (!NT_STATUS_IS_OK(status)) {
3398                         return ntstatus_to_werror(status);
3399                 }
3400                 return result;
3401         }
3402
3403         /* request just one share */
3404         status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
3405                                                pipe_hnd->desthost,
3406                                                argv[0],
3407                                                level,
3408                                                &info,
3409                                                &result);
3410
3411         if (!NT_STATUS_IS_OK(status)) {
3412                 result = ntstatus_to_werror(status);
3413                 goto done;
3414         }
3415
3416         if (!W_ERROR_IS_OK(result)) {
3417                 goto done;
3418         }
3419
3420         /* construct ctr */
3421         ZERO_STRUCTP(info_ctr);
3422
3423         info_ctr->level = level;
3424
3425         switch (level) {
3426         case 1:
3427         {
3428                 struct srvsvc_NetShareCtr1 *ctr1;
3429
3430                 ctr1 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr1);
3431                 W_ERROR_HAVE_NO_MEMORY(ctr1);
3432
3433                 ctr1->count = 1;
3434                 ctr1->array = info.info1;
3435
3436                 info_ctr->ctr.ctr1 = ctr1;
3437
3438                 break;
3439         }
3440         case 2:
3441         {
3442                 struct srvsvc_NetShareCtr2 *ctr2;
3443
3444                 ctr2 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr2);
3445                 W_ERROR_HAVE_NO_MEMORY(ctr2);
3446
3447                 ctr2->count = 1;
3448                 ctr2->array = info.info2;
3449
3450                 info_ctr->ctr.ctr2 = ctr2;
3451
3452                 break;
3453         }
3454         case 502:
3455         {
3456                 struct srvsvc_NetShareCtr502 *ctr502;
3457
3458                 ctr502 = TALLOC_ZERO_P(mem_ctx, struct srvsvc_NetShareCtr502);
3459                 W_ERROR_HAVE_NO_MEMORY(ctr502);
3460
3461                 ctr502->count = 1;
3462                 ctr502->array = info.info502;
3463
3464                 info_ctr->ctr.ctr502 = ctr502;
3465
3466                 break;
3467         }
3468         } /* switch */
3469 done:
3470         return result;
3471 }
3472
3473 /***
3474  * 'net rpc share list' entrypoint.
3475  * @param argc  Standard main() style argc.
3476  * @param argv  Standard main() style argv. Initial components are already
3477  *              stripped.
3478  **/
3479 static int rpc_share_list(struct net_context *c, int argc, const char **argv)
3480 {
3481         NET_API_STATUS status;
3482         struct SHARE_INFO_1 *i1 = NULL;
3483         uint32_t entries_read = 0;
3484         uint32_t total_entries = 0;
3485         uint32_t resume_handle = 0;
3486         uint32_t i, level = 1;
3487
3488         if (c->display_usage) {
3489                 d_printf(  "%s\n"
3490                            "net rpc share list\n"
3491                            "    %s\n",
3492                          _("Usage:"),
3493                          _("List shares on remote server"));
3494                 return 0;
3495         }
3496
3497         status = NetShareEnum(c->opt_host,
3498                               level,
3499                               (uint8_t **)(void *)&i1,
3500                               (uint32_t)-1,
3501                               &entries_read,
3502                               &total_entries,
3503                               &resume_handle);
3504         if (status != 0) {
3505                 goto done;
3506         }
3507
3508         /* Display results */
3509
3510         if (c->opt_long_list_entries) {
3511                 d_printf(_(
3512         "\nEnumerating shared resources (exports) on remote server:\n\n"
3513         "\nShare name   Type     Description\n"
3514         "----------   ----     -----------\n"));
3515         }
3516         for (i = 0; i < entries_read; i++)
3517                 display_share_info_1(c, &i1[i]);
3518  done:
3519         return status;
3520 }
3521
3522 static bool check_share_availability(struct cli_state *cli, const char *netname)
3523 {
3524         NTSTATUS status;
3525
3526         status = cli_tcon_andx(cli, netname, "A:", "", 0);
3527         if (!NT_STATUS_IS_OK(status)) {
3528                 d_printf(_("skipping   [%s]: not a file share.\n"), netname);
3529                 return false;
3530         }
3531
3532         status = cli_tdis(cli);
3533         if (!NT_STATUS_IS_OK(status)) {
3534                 d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
3535                 return false;
3536         }
3537
3538         return true;
3539 }
3540
3541 static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
3542                                const char *netname, uint32 type)
3543 {
3544         /* only support disk shares */
3545         if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
3546                 printf(_("share [%s] is not a diskshare (type: %x)\n"), netname,
3547                        type);
3548                 return false;
3549         }
3550
3551         /* skip builtin shares */
3552         /* FIXME: should print$ be added too ? */
3553         if (strequal(netname,"IPC$") || strequal(netname,"ADMIN$") ||
3554             strequal(netname,"global"))
3555                 return false;
3556
3557         if (c->opt_exclude && in_list(netname, c->opt_exclude, false)) {
3558                 printf(_("excluding  [%s]\n"), netname);
3559                 return false;
3560         }
3561
3562         return check_share_availability(cli, netname);
3563 }
3564
3565 /**
3566  * Migrate shares from a remote RPC server to the local RPC server.
3567  *
3568  * All parameters are provided by the run_rpc_command function, except for
3569  * argc, argv which are passed through.
3570  *
3571  * @param domain_sid The domain sid acquired from the remote server.
3572  * @param cli A cli_state connected to the server.
3573  * @param mem_ctx Talloc context, destroyed on completion of the function.
3574  * @param argc  Standard main() style argc.
3575  * @param argv  Standard main() style argv. Initial components are already
3576  *              stripped.
3577  *
3578  * @return Normal NTSTATUS return.
3579  **/
3580
3581 static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c,
3582                                                 const struct dom_sid *domain_sid,
3583                                                 const char *domain_name,
3584                                                 struct cli_state *cli,
3585                                                 struct rpc_pipe_client *pipe_hnd,
3586                                                 TALLOC_CTX *mem_ctx,
3587                                                 int argc,
3588                                                 const char **argv)
3589 {
3590         WERROR result;
3591         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3592         struct srvsvc_NetShareInfoCtr ctr_src;
3593         uint32 i;
3594         struct rpc_pipe_client *srvsvc_pipe = NULL;
3595         struct cli_state *cli_dst = NULL;
3596         uint32 level = 502; /* includes secdesc */
3597         uint32_t parm_error = 0;
3598         struct dcerpc_binding_handle *b;
3599
3600         result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3601                                 &ctr_src);
3602         if (!W_ERROR_IS_OK(result))
3603                 goto done;
3604
3605         /* connect destination PI_SRVSVC */
3606         nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
3607                                      &ndr_table_srvsvc.syntax_id);
3608         if (!NT_STATUS_IS_OK(nt_status))
3609                 return nt_status;
3610
3611         b = srvsvc_pipe->binding_handle;
3612
3613         for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3614
3615                 union srvsvc_NetShareInfo info;
3616                 struct srvsvc_NetShareInfo502 info502 =
3617                         ctr_src.ctr.ctr502->array[i];
3618
3619                 /* reset error-code */
3620                 nt_status = NT_STATUS_UNSUCCESSFUL;
3621
3622                 if (!check_share_sanity(c, cli, info502.name, info502.type))
3623                         continue;
3624
3625                 /* finally add the share on the dst server */
3626
3627                 printf(_("migrating: [%s], path: %s, comment: %s, without "
3628                          "share-ACLs\n"),
3629                         info502.name, info502.path, info502.comment);
3630
3631                 info.info502 = &info502;
3632
3633                 nt_status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
3634                                                       srvsvc_pipe->desthost,
3635                                                       502,
3636                                                       &info,
3637                                                       &parm_error,
3638                                                       &result);
3639                 if (!NT_STATUS_IS_OK(nt_status)) {
3640                         printf(_("cannot add share: %s\n"),
3641                                 nt_errstr(nt_status));
3642                         goto done;
3643                 }
3644                 if (W_ERROR_V(result) == W_ERROR_V(WERR_FILE_EXISTS)) {
3645                         printf(_("           [%s] does already exist\n"),
3646                                 info502.name);
3647                         continue;
3648                 }
3649
3650                 if (!W_ERROR_IS_OK(result)) {
3651                         nt_status = werror_to_ntstatus(result);
3652                         printf(_("cannot add share: %s\n"),
3653                                 win_errstr(result));
3654                         goto done;
3655                 }
3656
3657         }
3658
3659         nt_status = NT_STATUS_OK;
3660
3661 done:
3662         if (cli_dst) {
3663                 cli_shutdown(cli_dst);
3664         }
3665
3666         return nt_status;
3667
3668 }
3669
3670 /**
3671  * Migrate shares from a RPC server to another.
3672  *
3673  * @param argc  Standard main() style argc.
3674  * @param argv  Standard main() style argv. Initial components are already
3675  *              stripped.
3676  *
3677  * @return A shell status integer (0 for success).
3678  **/
3679 static int rpc_share_migrate_shares(struct net_context *c, int argc,
3680                                     const char **argv)
3681 {
3682         if (c->display_usage) {
3683                 d_printf(  "%s\n"
3684                            "net rpc share migrate shares\n"
3685                            "    %s\n",
3686                          _("Usage:"),
3687                          _("Migrate shares to local server"));
3688                 return 0;
3689         }
3690
3691         if (!c->opt_host) {
3692                 printf(_("no server to migrate\n"));
3693                 return -1;
3694         }
3695
3696         return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
3697                                rpc_share_migrate_shares_internals,
3698                                argc, argv);
3699 }
3700
3701 /**
3702  * Copy a file/dir
3703  *
3704  * @param f     file_info
3705  * @param mask  current search mask
3706  * @param state arg-pointer
3707  *
3708  **/
3709 static NTSTATUS copy_fn(const char *mnt, struct file_info *f,
3710                     const char *mask, void *state)
3711 {
3712         static NTSTATUS nt_status;
3713         static struct copy_clistate *local_state;
3714         static fstring filename, new_mask;
3715         fstring dir;
3716         char *old_dir;
3717         struct net_context *c;
3718
3719         local_state = (struct copy_clistate *)state;
3720         nt_status = NT_STATUS_UNSUCCESSFUL;
3721
3722         c = local_state->c;
3723
3724         if (strequal(f->name, ".") || strequal(f->name, ".."))
3725                 return NT_STATUS_OK;
3726
3727         DEBUG(3,("got mask: %s, name: %s\n", mask, f->name));
3728
3729         /* DIRECTORY */
3730         if (f->mode & aDIR) {
3731
3732                 DEBUG(3,("got dir: %s\n", f->name));
3733
3734                 fstrcpy(dir, local_state->cwd);
3735                 fstrcat(dir, "\\");
3736                 fstrcat(dir, f->name);
3737
3738                 switch (net_mode_share)
3739                 {
3740                 case NET_MODE_SHARE_MIGRATE:
3741                         /* create that directory */
3742                         nt_status = net_copy_file(c, local_state->mem_ctx,
3743                                                   local_state->cli_share_src,
3744                                                   local_state->cli_share_dst,
3745                                                   dir, dir,
3746                                                   c->opt_acls? true : false,
3747                                                   c->opt_attrs? true : false,
3748                                                   c->opt_timestamps? true:false,
3749                                                   false);
3750                         break;
3751                 default:
3752                         d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3753                         return NT_STATUS_INTERNAL_ERROR;
3754                 }
3755
3756                 if (!NT_STATUS_IS_OK(nt_status)) {
3757                         printf(_("could not handle dir %s: %s\n"),
3758                                 dir, nt_errstr(nt_status));
3759                         return nt_status;
3760                 }
3761
3762                 /* search below that directory */
3763                 fstrcpy(new_mask, dir);
3764                 fstrcat(new_mask, "\\*");
3765
3766                 old_dir = local_state->cwd;
3767                 local_state->cwd = dir;
3768                 nt_status = sync_files(local_state, new_mask);
3769                 if (!NT_STATUS_IS_OK(nt_status)) {
3770                         printf(_("could not handle files\n"));
3771                 }
3772                 local_state->cwd = old_dir;
3773
3774                 return nt_status;
3775         }
3776
3777
3778         /* FILE */
3779         fstrcpy(filename, local_state->cwd);
3780         fstrcat(filename, "\\");
3781         fstrcat(filename, f->name);
3782
3783         DEBUG(3,("got file: %s\n", filename));
3784
3785         switch (net_mode_share)
3786         {
3787         case NET_MODE_SHARE_MIGRATE:
3788                 nt_status = net_copy_file(c, local_state->mem_ctx,
3789                                           local_state->cli_share_src,
3790                                           local_state->cli_share_dst,
3791                                           filename, filename,
3792                                           c->opt_acls? true : false,
3793                                           c->opt_attrs? true : false,
3794                                           c->opt_timestamps? true: false,
3795                                           true);
3796                 break;
3797         default:
3798                 d_fprintf(stderr, _("Unsupported file mode %d\n"),
3799                           net_mode_share);
3800                 return NT_STATUS_INTERNAL_ERROR;
3801         }
3802
3803         if (!NT_STATUS_IS_OK(nt_status))
3804                 printf(_("could not handle file %s: %s\n"),
3805                         filename, nt_errstr(nt_status));
3806         return nt_status;
3807 }
3808
3809 /**
3810  * sync files, can be called recursivly to list files
3811  * and then call copy_fn for each file
3812  *
3813  * @param cp_clistate   pointer to the copy_clistate we work with
3814  * @param mask          the current search mask
3815  *
3816  * @return              Boolean result
3817  **/
3818 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask)
3819 {
3820         struct cli_state *targetcli;
3821         char *targetpath = NULL;
3822         NTSTATUS status;
3823
3824         DEBUG(3,("calling cli_list with mask: %s\n", mask));
3825
3826         if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
3827                                 mask, &targetcli, &targetpath ) ) {
3828                 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
3829                                     "%s\n"),
3830                         mask, cli_errstr(cp_clistate->cli_share_src));
3831                 return cli_nt_error(cp_clistate->cli_share_src);
3832         }
3833
3834         status = cli_list(targetcli, targetpath, cp_clistate->attribute,
3835                           copy_fn, cp_clistate);
3836         if (!NT_STATUS_IS_OK(status)) {
3837                 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
3838                           mask, nt_errstr(status));
3839         }
3840
3841         return status;
3842 }
3843
3844
3845 /**
3846  * Set the top level directory permissions before we do any further copies.
3847  * Should set up ACL inheritance.
3848  **/
3849
3850 bool copy_top_level_perms(struct net_context *c,
3851                                 struct copy_clistate *cp_clistate,
3852                                 const char *sharename)
3853 {
3854         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3855
3856         switch (net_mode_share) {
3857         case NET_MODE_SHARE_MIGRATE:
3858                 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3859                 nt_status = net_copy_fileattr(c,
3860                                                 cp_clistate->mem_ctx,
3861                                                 cp_clistate->cli_share_src,
3862                                                 cp_clistate->cli_share_dst,
3863                                                 "\\", "\\",
3864                                                 c->opt_acls? true : false,
3865                                                 c->opt_attrs? true : false,
3866                                                 c->opt_timestamps? true: false,
3867                                                 false);
3868                 break;
3869         default:
3870                 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3871                 break;
3872         }
3873
3874         if (!NT_STATUS_IS_OK(nt_status))  {
3875                 printf(_("Could handle directory attributes for top level "
3876                          "directory of share %s. Error %s\n"),
3877                         sharename, nt_errstr(nt_status));
3878                 return false;
3879         }
3880
3881         return true;
3882 }
3883
3884 /**
3885  * Sync all files inside a remote share to another share (over smb).
3886  *
3887  * All parameters are provided by the run_rpc_command function, except for
3888  * argc, argv which are passed through.
3889  *
3890  * @param domain_sid The domain sid acquired from the remote server.
3891  * @param cli A cli_state connected to the server.
3892  * @param mem_ctx Talloc context, destroyed on completion of the function.
3893  * @param argc  Standard main() style argc.
3894  * @param argv  Standard main() style argv. Initial components are already
3895  *              stripped.
3896  *
3897  * @return Normal NTSTATUS return.
3898  **/
3899
3900 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
3901                                                 const struct dom_sid *domain_sid,
3902                                                 const char *domain_name,
3903                                                 struct cli_state *cli,
3904                                                 struct rpc_pipe_client *pipe_hnd,
3905                                                 TALLOC_CTX *mem_ctx,
3906                                                 int argc,
3907                                                 const char **argv)
3908 {
3909         WERROR result;
3910         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3911         struct srvsvc_NetShareInfoCtr ctr_src;
3912         uint32 i;
3913         uint32 level = 502;
3914         struct copy_clistate cp_clistate;
3915         bool got_src_share = false;
3916         bool got_dst_share = false;
3917         const char *mask = "\\*";
3918         char *dst = NULL;
3919
3920         dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
3921         if (dst == NULL) {
3922                 nt_status = NT_STATUS_NO_MEMORY;
3923                 goto done;
3924         }
3925
3926         result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3927                                 &ctr_src);
3928
3929         if (!W_ERROR_IS_OK(result))
3930                 goto done;
3931
3932         for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3933
3934                 struct srvsvc_NetShareInfo502 info502 =
3935                         ctr_src.ctr.ctr502->array[i];
3936
3937                 if (!check_share_sanity(c, cli, info502.name, info502.type))
3938                         continue;
3939
3940                 /* one might not want to mirror whole discs :) */
3941                 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
3942                         d_printf(_("skipping   [%s]: builtin/hidden share\n"),
3943                                  info502.name);
3944                         continue;
3945                 }
3946
3947                 switch (net_mode_share)
3948                 {
3949                 case NET_MODE_SHARE_MIGRATE:
3950                         printf("syncing");
3951                         break;
3952                 default:
3953                         d_fprintf(stderr, _("Unsupported mode %d\n"),
3954                                   net_mode_share);
3955                         break;
3956                 }
3957                 printf(_("    [%s] files and directories %s ACLs, %s DOS "
3958                          "Attributes %s\n"),
3959                         info502.name,
3960                         c->opt_acls ? _("including") : _("without"),
3961                         c->opt_attrs ? _("including") : _("without"),
3962                         c->opt_timestamps ? _("(preserving timestamps)") : "");
3963
3964                 cp_clistate.mem_ctx = mem_ctx;
3965                 cp_clistate.cli_share_src = NULL;
3966                 cp_clistate.cli_share_dst = NULL;
3967                 cp_clistate.cwd = NULL;
3968                 cp_clistate.attribute = aSYSTEM | aHIDDEN | aDIR;
3969                 cp_clistate.c = c;
3970
3971                 /* open share source */
3972                 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
3973                                                &cli->dest_ss, cli->desthost,
3974                                                info502.name, "A:");
3975                 if (!NT_STATUS_IS_OK(nt_status))
3976                         goto done;
3977
3978                 got_src_share = true;
3979
3980                 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3981                         /* open share destination */
3982                         nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
3983                                                        NULL, dst, info502.name, "A:");
3984                         if (!NT_STATUS_IS_OK(nt_status))
3985                                 goto done;
3986
3987                         got_dst_share = true;
3988                 }
3989
3990                 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
3991                         d_fprintf(stderr, _("Could not handle the top level "
3992                                             "directory permissions for the "
3993                                             "share: %s\n"), info502.name);
3994                         nt_status = NT_STATUS_UNSUCCESSFUL;
3995                         goto done;
3996                 }
3997
3998                 nt_status = sync_files(&cp_clistate, mask);
3999                 if (!NT_STATUS_IS_OK(nt_status)) {
4000                         d_fprintf(stderr, _("could not handle files for share: "
4001                                             "%s\n"), info502.name);
4002                         goto done;
4003                 }
4004         }
4005
4006         nt_status = NT_STATUS_OK;
4007
4008 done:
4009
4010         if (got_src_share)
4011                 cli_shutdown(cp_clistate.cli_share_src);
4012
4013         if (got_dst_share)
4014                 cli_shutdown(cp_clistate.cli_share_dst);
4015
4016         SAFE_FREE(dst);
4017         return nt_status;
4018
4019 }
4020
4021 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
4022 {
4023         if (c->display_usage) {
4024                 d_printf(  "%s\n"
4025                            "net share migrate files\n"
4026                            "    %s\n",
4027                          _("Usage:"),
4028                          _("Migrate files to local server"));
4029                 return 0;
4030         }
4031
4032         if (!c->opt_host) {
4033                 d_printf(_("no server to migrate\n"));
4034                 return -1;
4035         }
4036
4037         return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4038                                rpc_share_migrate_files_internals,
4039                                argc, argv);
4040 }
4041
4042 /**
4043  * Migrate share-ACLs from a remote RPC server to the local RPC server.
4044  *
4045  * All parameters are provided by the run_rpc_command function, except for
4046  * argc, argv which are passed through.
4047  *
4048  * @param domain_sid The domain sid acquired from the remote server.
4049  * @param cli A cli_state connected to the server.
4050  * @param mem_ctx Talloc context, destroyed on completion of the function.
4051  * @param argc  Standard main() style argc.
4052  * @param argv  Standard main() style argv. Initial components are already
4053  *              stripped.
4054  *
4055  * @return Normal NTSTATUS return.
4056  **/
4057
4058 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
4059                                                 const struct dom_sid *domain_sid,
4060                                                 const char *domain_name,
4061                                                 struct cli_state *cli,
4062                                                 struct rpc_pipe_client *pipe_hnd,
4063                                                 TALLOC_CTX *mem_ctx,
4064                                                 int argc,
4065                                                 const char **argv)
4066 {
4067         WERROR result;
4068         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4069         struct srvsvc_NetShareInfoCtr ctr_src;
4070         union srvsvc_NetShareInfo info;
4071         uint32 i;
4072         struct rpc_pipe_client *srvsvc_pipe = NULL;
4073         struct cli_state *cli_dst = NULL;
4074         uint32 level = 502; /* includes secdesc */
4075         uint32_t parm_error = 0;
4076         struct dcerpc_binding_handle *b;
4077
4078         result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4079                                 &ctr_src);
4080
4081         if (!W_ERROR_IS_OK(result))
4082                 goto done;
4083
4084         /* connect destination PI_SRVSVC */
4085         nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
4086                                      &ndr_table_srvsvc.syntax_id);
4087         if (!NT_STATUS_IS_OK(nt_status))
4088                 return nt_status;
4089
4090         b = srvsvc_pipe->binding_handle;
4091
4092         for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4093
4094                 struct srvsvc_NetShareInfo502 info502 =
4095                         ctr_src.ctr.ctr502->array[i];
4096
4097                 /* reset error-code */
4098                 nt_status = NT_STATUS_UNSUCCESSFUL;
4099
4100                 if (!check_share_sanity(c, cli, info502.name, info502.type))
4101                         continue;
4102
4103                 printf(_("migrating: [%s], path: %s, comment: %s, including "
4104                          "share-ACLs\n"),
4105                         info502.name, info502.path, info502.comment);
4106
4107                 if (c->opt_verbose)
4108                         display_sec_desc(info502.sd_buf.sd);
4109
4110                 /* FIXME: shouldn't we be able to just set the security descriptor ? */
4111                 info.info502 = &info502;
4112
4113                 /* finally modify the share on the dst server */
4114                 nt_status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx,
4115                                                           srvsvc_pipe->desthost,
4116                                                           info502.name,
4117                                                           level,
4118                                                           &info,
4119                                                           &parm_error,
4120                                                           &result);
4121                 if (!NT_STATUS_IS_OK(nt_status)) {
4122                         printf(_("cannot set share-acl: %s\n"),
4123                                nt_errstr(nt_status));
4124                         goto done;
4125                 }
4126                 if (!W_ERROR_IS_OK(result)) {
4127                         nt_status = werror_to_ntstatus(result);
4128                         printf(_("cannot set share-acl: %s\n"),
4129                                win_errstr(result));
4130                         goto done;
4131                 }
4132
4133         }
4134
4135         nt_status = NT_STATUS_OK;
4136
4137 done:
4138         if (cli_dst) {
4139                 cli_shutdown(cli_dst);
4140         }
4141
4142         return nt_status;
4143
4144 }
4145
4146 /**
4147  * Migrate share-acls from a RPC server to another.
4148  *
4149  * @param argc  Standard main() style argc.
4150  * @param argv  Standard main() style argv. Initial components are already
4151  *              stripped.
4152  *
4153  * @return A shell status integer (0 for success).
4154  **/
4155 static int rpc_share_migrate_security(struct net_context *c, int argc,
4156                                       const char **argv)
4157 {
4158         if (c->display_usage) {
4159                 d_printf(  "%s\n"
4160                            "net rpc share migrate security\n"
4161                            "    %s\n",
4162                          _("Usage:"),
4163                          _("Migrate share-acls to local server"));
4164                 return 0;
4165         }
4166
4167         if (!c->opt_host) {
4168                 d_printf(_("no server to migrate\n"));
4169                 return -1;
4170         }
4171
4172         return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4173                                rpc_share_migrate_security_internals,
4174                                argc, argv);
4175 }
4176
4177 /**
4178  * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4179  * from one server to another.
4180  *
4181  * @param argc  Standard main() style argc.
4182  * @param argv  Standard main() style argv. Initial components are already
4183  *              stripped.
4184  *
4185  * @return A shell status integer (0 for success).
4186  *
4187  **/
4188 static int rpc_share_migrate_all(struct net_context *c, int argc,
4189                                  const char **argv)
4190 {
4191         int ret;
4192
4193         if (c->display_usage) {
4194                 d_printf(  "%s\n"
4195                            "net rpc share migrate all\n"
4196                            "    %s\n",
4197                          _("Usage:"),
4198                          _("Migrates shares including all share settings"));
4199                 return 0;
4200         }
4201
4202         if (!c->opt_host) {
4203                 d_printf(_("no server to migrate\n"));
4204                 return -1;
4205         }
4206
4207         /* order is important. we don't want to be locked out by the share-acl
4208          * before copying files - gd */
4209
4210         ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4211                               rpc_share_migrate_shares_internals, argc, argv);
4212         if (ret)
4213                 return ret;
4214
4215         ret = run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4216                               rpc_share_migrate_files_internals, argc, argv);
4217         if (ret)
4218                 return ret;
4219
4220         return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
4221                                rpc_share_migrate_security_internals, argc,
4222                                argv);
4223 }
4224
4225
4226 /**
4227  * 'net rpc share migrate' entrypoint.
4228  * @param argc  Standard main() style argc.
4229  * @param argv  Standard main() style argv. Initial components are already
4230  *              stripped.
4231  **/
4232 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
4233 {
4234
4235         struct functable func[] = {
4236                 {
4237                         "all",
4238                         rpc_share_migrate_all,
4239                         NET_TRANSPORT_RPC,
4240                         N_("Migrate shares from remote to local server"),
4241                         N_("net rpc share migrate all\n"
4242                            "    Migrate shares from remote to local server")
4243                 },
4244                 {
4245                         "files",
4246                         rpc_share_migrate_files,
4247                         NET_TRANSPORT_RPC,
4248                         N_("Migrate files from remote to local server"),
4249                         N_("net rpc share migrate files\n"
4250                            "    Migrate files from remote to local server")
4251                 },
4252                 {
4253                         "security",
4254                         rpc_share_migrate_security,
4255                         NET_TRANSPORT_RPC,
4256                         N_("Migrate share-ACLs from remote to local server"),
4257                         N_("net rpc share migrate security\n"
4258                            "    Migrate share-ACLs from remote to local server")
4259                 },
4260                 {
4261                         "shares",
4262                         rpc_share_migrate_shares,
4263                         NET_TRANSPORT_RPC,
4264                         N_("Migrate shares from remote to local server"),
4265                         N_("net rpc share migrate shares\n"
4266                            "    Migrate shares from remote to local server")
4267                 },
4268                 {NULL, NULL, 0, NULL, NULL}
4269         };
4270
4271         net_mode_share = NET_MODE_SHARE_MIGRATE;
4272
4273         return net_run_function(c, argc, argv, "net rpc share migrate", func);
4274 }
4275
4276 struct full_alias {
4277         struct dom_sid sid;
4278         uint32 num_members;
4279         struct dom_sid *members;
4280 };
4281
4282 static int num_server_aliases;
4283 static struct full_alias *server_aliases;
4284
4285 /*
4286  * Add an alias to the static list.
4287  */
4288 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
4289 {
4290         if (server_aliases == NULL)
4291                 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
4292
4293         server_aliases[num_server_aliases] = *alias;
4294         num_server_aliases += 1;
4295 }
4296
4297 /*
4298  * For a specific domain on the server, fetch all the aliases
4299  * and their members. Add all of them to the server_aliases.
4300  */
4301
4302 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4303                                         TALLOC_CTX *mem_ctx,
4304                                         struct policy_handle *connect_pol,
4305                                         const struct dom_sid *domain_sid)
4306 {
4307         uint32 start_idx, max_entries, num_entries, i;
4308         struct samr_SamArray *groups = NULL;
4309         NTSTATUS result, status;
4310         struct policy_handle domain_pol;
4311         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4312
4313         /* Get domain policy handle */
4314
4315         status = dcerpc_samr_OpenDomain(b, mem_ctx,
4316                                         connect_pol,
4317                                         MAXIMUM_ALLOWED_ACCESS,
4318                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
4319                                         &domain_pol,
4320                                         &result);
4321         if (!NT_STATUS_IS_OK(status)) {
4322                 return status;
4323         }
4324         if (!NT_STATUS_IS_OK(result)) {
4325                 return result;
4326         }
4327
4328         start_idx = 0;
4329         max_entries = 250;
4330
4331         do {
4332                 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
4333                                                        &domain_pol,
4334                                                        &start_idx,
4335                                                        &groups,
4336                                                        max_entries,
4337                                                        &num_entries,
4338                                                        &result);
4339                 if (!NT_STATUS_IS_OK(status)) {
4340                         goto done;
4341                 }
4342                 for (i = 0; i < num_entries; i++) {
4343
4344                         struct policy_handle alias_pol;
4345                         struct full_alias alias;
4346                         struct lsa_SidArray sid_array;
4347                         int j;
4348                         NTSTATUS _result;
4349
4350                         status = dcerpc_samr_OpenAlias(b, mem_ctx,
4351                                                        &domain_pol,
4352                                                        MAXIMUM_ALLOWED_ACCESS,
4353                                                        groups->entries[i].idx,
4354                                                        &alias_pol,
4355                                                        &_result);
4356                         if (!NT_STATUS_IS_OK(status)) {
4357                                 goto done;
4358                         }
4359                         if (!NT_STATUS_IS_OK(_result)) {
4360                                 status = _result;
4361                                 goto done;
4362                         }
4363
4364                         status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
4365                                                                &alias_pol,
4366                                                                &sid_array,
4367                                                                &_result);
4368                         if (!NT_STATUS_IS_OK(status)) {
4369                                 goto done;
4370                         }
4371                         if (!NT_STATUS_IS_OK(_result)) {
4372                                 status = _result;
4373                                 goto done;
4374                         }
4375
4376                         alias.num_members = sid_array.num_sids;
4377
4378                         status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &_result);
4379                         if (!NT_STATUS_IS_OK(status)) {
4380                                 goto done;
4381                         }
4382                         if (!NT_STATUS_IS_OK(_result)) {
4383                                 status = _result;
4384                                 goto done;
4385                         }
4386
4387                         alias.members = NULL;
4388
4389                         if (alias.num_members > 0) {
4390                                 alias.members = SMB_MALLOC_ARRAY(struct dom_sid, alias.num_members);
4391
4392                                 for (j = 0; j < alias.num_members; j++)
4393                                         sid_copy(&alias.members[j],
4394                                                  sid_array.sids[j].sid);
4395                         }
4396
4397                         sid_compose(&alias.sid, domain_sid,
4398                                     groups->entries[i].idx);
4399
4400                         push_alias(mem_ctx, &alias);
4401                 }
4402         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4403
4404         status = NT_STATUS_OK;
4405
4406  done:
4407         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
4408
4409         return status;
4410 }
4411
4412 /*
4413  * Dump server_aliases as names for debugging purposes.
4414  */
4415
4416 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4417                                 const struct dom_sid *domain_sid,
4418                                 const char *domain_name,
4419                                 struct cli_state *cli,
4420                                 struct rpc_pipe_client *pipe_hnd,
4421                                 TALLOC_CTX *mem_ctx,
4422                                 int argc,
4423                                 const char **argv)
4424 {
4425         int i;
4426         NTSTATUS result;
4427         struct policy_handle lsa_pol;
4428         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4429
4430         result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4431                                      SEC_FLAG_MAXIMUM_ALLOWED,
4432                                      &lsa_pol);
4433         if (!NT_STATUS_IS_OK(result))
4434                 return result;
4435
4436         for (i=0; i<num_server_aliases; i++) {
4437                 char **names;
4438                 char **domains;
4439                 enum lsa_SidType *types;
4440                 int j;
4441
4442                 struct full_alias *alias = &server_aliases[i];
4443
4444                 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4445                                              &alias->sid,
4446                                              &domains, &names, &types);
4447                 if (!NT_STATUS_IS_OK(result))
4448                         continue;
4449
4450                 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4451
4452                 if (alias->num_members == 0) {
4453                         DEBUG(1, ("\n"));
4454                         continue;
4455                 }
4456
4457                 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4458                                              alias->num_members,
4459                                              alias->members,
4460                                              &domains, &names, &types);
4461
4462                 if (!NT_STATUS_IS_OK(result) &&
4463                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4464                         continue;
4465
4466                 for (j=0; j<alias->num_members; j++)
4467                         DEBUG(1, ("%s\\%s (%d); ",
4468                                   domains[j] ? domains[j] : "*unknown*", 
4469                                   names[j] ? names[j] : "*unknown*",types[j]));
4470                 DEBUG(1, ("\n"));
4471         }
4472
4473         dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
4474
4475         return NT_STATUS_OK;
4476 }
4477
4478 /*
4479  * Fetch a list of all server aliases and their members into
4480  * server_aliases.
4481  */
4482
4483 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4484                                         const struct dom_sid *domain_sid,
4485                                         const char *domain_name,
4486                                         struct cli_state *cli,
4487                                         struct rpc_pipe_client *pipe_hnd,
4488                                         TALLOC_CTX *mem_ctx,
4489                                         int argc,
4490                                         const char **argv)
4491 {
4492         NTSTATUS result, status;
4493         struct policy_handle connect_pol;
4494         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4495
4496         status = dcerpc_samr_Connect2(b, mem_ctx,
4497                                       pipe_hnd->desthost,
4498                                       MAXIMUM_ALLOWED_ACCESS,
4499                                       &connect_pol,
4500                                       &result);
4501         if (!NT_STATUS_IS_OK(status)) {
4502                 goto done;
4503         }
4504         if (!NT_STATUS_IS_OK(result)) {
4505                 status = result;
4506                 goto done;
4507         }
4508
4509         status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4510                                           &global_sid_Builtin);
4511         if (!NT_STATUS_IS_OK(status)) {
4512                 goto done;
4513         }
4514
4515         status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4516                                           domain_sid);
4517
4518         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
4519  done:
4520         return status;
4521 }
4522
4523 static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4524 {
4525         token->num_sids = 4;
4526
4527         if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4528                 d_fprintf(stderr, "malloc %s\n",_("failed"));
4529                 token->num_sids = 0;
4530                 return;
4531         }
4532
4533         token->sids[0] = *user_sid;
4534         sid_copy(&token->sids[1], &global_sid_World);
4535         sid_copy(&token->sids[2], &global_sid_Network);
4536         sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4537 }
4538
4539 static void free_user_token(struct security_token *token)
4540 {
4541         SAFE_FREE(token->sids);
4542 }
4543
4544 static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4545 {
4546         if (security_token_has_sid(token, sid))
4547                 return;
4548
4549         token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4550         if (!token->sids) {
4551                 return;
4552         }
4553
4554         sid_copy(&token->sids[token->num_sids], sid);
4555
4556         token->num_sids += 1;
4557 }
4558
4559 struct user_token {
4560         fstring name;
4561         struct security_token token;
4562 };
4563
4564 static void dump_user_token(struct user_token *token)
4565 {
4566         int i;
4567
4568         d_printf("%s\n", token->name);
4569
4570         for (i=0; i<token->token.num_sids; i++) {
4571                 d_printf(" %s\n", sid_string_tos(&token->token.sids[i]));
4572         }
4573 }
4574
4575 static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4576 {
4577         int i;
4578
4579         for (i=0; i<alias->num_members; i++) {
4580                 if (dom_sid_compare(sid, &alias->members[i]) == 0)
4581                         return true;
4582         }
4583
4584         return false;
4585 }
4586
4587 static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4588 {
4589         int i;
4590
4591         for (i=0; i<num_server_aliases; i++) {
4592                 if (is_alias_member(&sid, &server_aliases[i]))
4593                         add_sid_to_token(token, &server_aliases[i].sid);
4594         }
4595 }
4596
4597 /*
4598  * We got a user token with all the SIDs we can know about without asking the
4599  * server directly. These are the user and domain group sids. All of these can
4600  * be members of aliases. So scan the list of aliases for each of the SIDs and
4601  * add them to the token.
4602  */
4603
4604 static void collect_alias_memberships(struct security_token *token)
4605 {
4606         int num_global_sids = token->num_sids;
4607         int i;
4608
4609         for (i=0; i<num_global_sids; i++) {
4610                 collect_sid_memberships(token, token->sids[i]);
4611         }
4612 }
4613
4614 static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4615 {
4616         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4617         enum wbcSidType type;
4618         fstring full_name;
4619         struct wbcDomainSid wsid;
4620         char sid_str[WBC_SID_STRING_BUFLEN];
4621         struct dom_sid user_sid;
4622         uint32_t num_groups;
4623         gid_t *groups = NULL;
4624         uint32_t i;
4625
4626         fstr_sprintf(full_name, "%s%c%s",
4627                      domain, *lp_winbind_separator(), user);
4628
4629         /* First let's find out the user sid */
4630
4631         wbc_status = wbcLookupName(domain, user, &wsid, &type);
4632
4633         if (!WBC_ERROR_IS_OK(wbc_status)) {
4634                 DEBUG(1, ("winbind could not find %s: %s\n",
4635                           full_name, wbcErrorString(wbc_status)));
4636                 return false;
4637         }
4638
4639         wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4640
4641         if (type != WBC_SID_NAME_USER) {
4642                 DEBUG(1, ("%s is not a user\n", full_name));
4643                 return false;
4644         }
4645
4646         if (!string_to_sid(&user_sid, sid_str)) {
4647                 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4648                 return false;
4649         }
4650
4651         init_user_token(token, &user_sid);
4652
4653         /* And now the groups winbind knows about */
4654
4655         wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4656         if (!WBC_ERROR_IS_OK(wbc_status)) {
4657                 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4658                         full_name, wbcErrorString(wbc_status)));
4659                 return false;
4660         }
4661
4662         for (i = 0; i < num_groups; i++) {
4663                 gid_t gid = groups[i];
4664                 struct dom_sid sid;
4665
4666                 wbc_status = wbcGidToSid(gid, &wsid);
4667                 if (!WBC_ERROR_IS_OK(wbc_status)) {
4668                         DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4669                                   (unsigned int)gid, wbcErrorString(wbc_status)));
4670                         wbcFreeMemory(groups);
4671                         return false;
4672                 }
4673
4674                 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4675
4676                 DEBUG(3, (" %s\n", sid_str));
4677
4678                 string_to_sid(&sid, sid_str);
4679                 add_sid_to_token(token, &sid);
4680         }
4681         wbcFreeMemory(groups);
4682
4683         return true;
4684 }
4685
4686 /**
4687  * Get a list of all user tokens we want to look at
4688  **/
4689
4690 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4691                             struct user_token **user_tokens)
4692 {
4693         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4694         uint32_t i, num_users;
4695         const char **users;
4696         struct user_token *result;
4697         TALLOC_CTX *frame = NULL;
4698
4699         if (lp_winbind_use_default_domain() &&
4700             (c->opt_target_workgroup == NULL)) {
4701                 d_fprintf(stderr, _("winbind use default domain = yes set, "
4702                          "please specify a workgroup\n"));
4703                 return false;
4704         }
4705
4706         /* Send request to winbind daemon */
4707
4708         wbc_status = wbcListUsers(NULL, &num_users, &users);
4709         if (!WBC_ERROR_IS_OK(wbc_status)) {
4710                 DEBUG(1, (_("winbind could not list users: %s\n"),
4711                           wbcErrorString(wbc_status)));
4712                 return false;
4713         }
4714
4715         result = SMB_MALLOC_ARRAY(struct user_token, num_users);
4716
4717         if (result == NULL) {
4718                 DEBUG(1, ("Could not malloc sid array\n"));
4719                 wbcFreeMemory(users);
4720                 return false;
4721         }
4722
4723         frame = talloc_stackframe();
4724         for (i=0; i < num_users; i++) {
4725                 fstring domain, user;
4726                 char *p;
4727
4728                 fstrcpy(result[i].name, users[i]);
4729
4730                 p = strchr(users[i], *lp_winbind_separator());
4731
4732                 DEBUG(3, ("%s\n", users[i]));
4733
4734                 if (p == NULL) {
4735                         fstrcpy(domain, c->opt_target_workgroup);
4736                         fstrcpy(user, users[i]);
4737                 } else {
4738                         *p++ = '\0';
4739                         fstrcpy(domain, users[i]);
4740                         strupper_m(domain);
4741                         fstrcpy(user, p);
4742                 }
4743
4744                 get_user_sids(domain, user, &(result[i].token));
4745         }
4746         TALLOC_FREE(frame);
4747         wbcFreeMemory(users);
4748
4749         *num_tokens = num_users;
4750         *user_tokens = result;
4751
4752         return true;
4753 }
4754
4755 static bool get_user_tokens_from_file(FILE *f,
4756                                       int *num_tokens,
4757                                       struct user_token **tokens)
4758 {
4759         struct user_token *token = NULL;
4760
4761         while (!feof(f)) {
4762                 fstring line;
4763
4764                 if (fgets(line, sizeof(line)-1, f) == NULL) {
4765                         return true;
4766                 }
4767
4768                 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
4769                         line[strlen(line)-1] = '\0';
4770                 }
4771
4772                 if (line[0] == ' ') {
4773                         /* We have a SID */
4774
4775                         struct dom_sid sid;
4776                         if(!string_to_sid(&sid, &line[1])) {
4777                                 DEBUG(1,("get_user_tokens_from_file: Could "
4778                                         "not convert sid %s \n",&line[1]));
4779                                 return false;
4780                         }
4781
4782                         if (token == NULL) {
4783                                 DEBUG(0, ("File does not begin with username"));
4784                                 return false;
4785                         }
4786
4787                         add_sid_to_token(&token->token, &sid);
4788                         continue;
4789                 }
4790
4791                 /* And a new user... */
4792
4793                 *num_tokens += 1;
4794                 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4795                 if (*tokens == NULL) {
4796                         DEBUG(0, ("Could not realloc tokens\n"));
4797                         return false;
4798                 }
4799
4800                 token = &((*tokens)[*num_tokens-1]);
4801
4802                 fstrcpy(token->name, line);
4803                 token->token.num_sids = 0;
4804                 token->token.sids = NULL;
4805                 continue;
4806         }
4807         
4808         return false;
4809 }
4810
4811
4812 /*
4813  * Show the list of all users that have access to a share
4814  */
4815
4816 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4817                         TALLOC_CTX *mem_ctx,
4818                         const char *netname,
4819                         int num_tokens,
4820                         struct user_token *tokens)
4821 {
4822         uint16_t fnum;
4823         struct security_descriptor *share_sd = NULL;
4824         struct security_descriptor *root_sd = NULL;
4825         struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
4826         int i;
4827         union srvsvc_NetShareInfo info;
4828         WERROR result;
4829         NTSTATUS status;
4830         uint16 cnum;
4831         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4832
4833         status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
4834                                                pipe_hnd->desthost,
4835                                                netname,
4836                                                502,
4837                                                &info,
4838                                                &result);
4839
4840         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4841                 DEBUG(1, ("Coult not query secdesc for share %s\n",
4842                           netname));
4843                 return;
4844         }
4845
4846         share_sd = info.info502->sd_buf.sd;
4847         if (share_sd == NULL) {
4848                 DEBUG(1, ("Got no secdesc for share %s\n",
4849                           netname));
4850         }
4851
4852         cnum = cli->cnum;
4853
4854         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
4855                 return;
4856         }
4857
4858         if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
4859                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
4860                 root_sd = cli_query_secdesc(cli, fnum, mem_ctx);
4861         }
4862
4863         for (i=0; i<num_tokens; i++) {
4864                 uint32 acc_granted;
4865
4866                 if (share_sd != NULL) {
4867                         status = se_access_check(share_sd, &tokens[i].token,
4868                                              1, &acc_granted);
4869
4870                         if (!NT_STATUS_IS_OK(status)) {
4871                                 DEBUG(1, ("Could not check share_sd for "
4872                                           "user %s\n",
4873                                           tokens[i].name));
4874                                 continue;
4875                         }
4876                 }
4877
4878                 if (root_sd == NULL) {
4879                         d_printf(" %s\n", tokens[i].name);
4880                         continue;
4881                 }
4882
4883                 status = se_access_check(root_sd, &tokens[i].token,
4884                                      1, &acc_granted);
4885                 if (!NT_STATUS_IS_OK(status)) {
4886                         DEBUG(1, ("Could not check root_sd for user %s\n",
4887                                   tokens[i].name));
4888                         continue;
4889                 }
4890                 d_printf(" %s\n", tokens[i].name);
4891         }
4892
4893         if (fnum != (uint16_t)-1)
4894                 cli_close(cli, fnum);
4895         cli_tdis(cli);
4896         cli->cnum = cnum;
4897         
4898         return;
4899 }
4900
4901 struct share_list {
4902         int num_shares;
4903         char **shares;
4904 };
4905
4906 static void collect_share(const char *name, uint32 m,
4907                           const char *comment, void *state)
4908 {
4909         struct share_list *share_list = (struct share_list *)state;
4910
4911         if (m != STYPE_DISKTREE)
4912                 return;
4913
4914         share_list->num_shares += 1;
4915         share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4916         if (!share_list->shares) {
4917                 share_list->num_shares = 0;
4918                 return;
4919         }
4920         share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4921 }
4922
4923 /**
4924  * List shares on a remote RPC server, including the security descriptors.
4925  *
4926  * All parameters are provided by the run_rpc_command function, except for
4927  * argc, argv which are passed through.
4928  *
4929  * @param domain_sid The domain sid acquired from the remote server.
4930  * @param cli A cli_state connected to the server.
4931  * @param mem_ctx Talloc context, destroyed on completion of the function.
4932  * @param argc  Standard main() style argc.
4933  * @param argv  Standard main() style argv. Initial components are already
4934  *              stripped.
4935  *
4936  * @return Normal NTSTATUS return.
4937  **/
4938
4939 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
4940                                                 const struct dom_sid *domain_sid,
4941                                                 const char *domain_name,
4942                                                 struct cli_state *cli,
4943                                                 struct rpc_pipe_client *pipe_hnd,
4944                                                 TALLOC_CTX *mem_ctx,
4945                                                 int argc,
4946                                                 const char **argv)
4947 {
4948         int ret;
4949         bool r;
4950         uint32 i;
4951         FILE *f;
4952
4953         struct user_token *tokens = NULL;
4954         int num_tokens = 0;
4955
4956         struct share_list share_list;
4957
4958         if (argc == 0) {
4959                 f = stdin;
4960         } else {
4961                 f = fopen(argv[0], "r");
4962         }
4963
4964         if (f == NULL) {
4965                 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4966                 return NT_STATUS_UNSUCCESSFUL;
4967         }
4968
4969         r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4970
4971         if (f != stdin)
4972                 fclose(f);
4973
4974         if (!r) {
4975                 DEBUG(0, ("Could not read users from file\n"));
4976                 return NT_STATUS_UNSUCCESSFUL;
4977         }
4978
4979         for (i=0; i<num_tokens; i++)
4980                 collect_alias_memberships(&tokens[i].token);
4981
4982         share_list.num_shares = 0;
4983         share_list.shares = NULL;
4984
4985         ret = cli_RNetShareEnum(cli, collect_share, &share_list);
4986
4987         if (ret == -1) {
4988                 DEBUG(0, ("Error returning browse list: %s\n",
4989                           cli_errstr(cli)));
4990                 goto done;
4991         }
4992
4993         for (i = 0; i < share_list.num_shares; i++) {
4994                 char *netname = share_list.shares[i];
4995
4996                 if (netname[strlen(netname)-1] == '$')
4997                         continue;
4998
4999                 d_printf("%s\n", netname);
5000
5001                 show_userlist(pipe_hnd, mem_ctx, netname,
5002                               num_tokens, tokens);
5003         }
5004  done:
5005         for (i=0; i<num_tokens; i++) {
5006                 free_user_token(&tokens[i].token);
5007         }
5008         SAFE_FREE(tokens);
5009         SAFE_FREE(share_list.shares);
5010
5011         return NT_STATUS_OK;
5012 }
5013
5014 static int rpc_share_allowedusers(struct net_context *c, int argc,
5015                                   const char **argv)
5016 {
5017         int result;
5018
5019         if (c->display_usage) {
5020                 d_printf(  "%s\n"
5021                            "net rpc share allowedusers\n"
5022                             "    %s\n",
5023                           _("Usage:"),
5024                           _("List allowed users"));
5025                 return 0;
5026         }
5027
5028         result = run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5029                                  rpc_aliaslist_internals,
5030                                  argc, argv);
5031         if (result != 0)
5032                 return result;
5033
5034         result = run_rpc_command(c, NULL, &ndr_table_lsarpc.syntax_id, 0,
5035                                  rpc_aliaslist_dump,
5036                                  argc, argv);
5037         if (result != 0)
5038                 return result;
5039
5040         return run_rpc_command(c, NULL, &ndr_table_srvsvc.syntax_id, 0,
5041                                rpc_share_allowedusers_internals,
5042                                argc, argv);
5043 }
5044
5045 int net_usersidlist(struct net_context *c, int argc, const char **argv)
5046 {
5047         int num_tokens = 0;
5048         struct user_token *tokens = NULL;
5049         int i;
5050
5051         if (argc != 0) {
5052                 net_usersidlist_usage(c, argc, argv);
5053                 return 0;
5054         }
5055
5056         if (!get_user_tokens(c, &num_tokens, &tokens)) {
5057                 DEBUG(0, ("Could not get the user/sid list\n"));
5058                 return 0;
5059         }
5060
5061         for (i=0; i<num_tokens; i++) {
5062                 dump_user_token(&tokens[i]);
5063                 free_user_token(&tokens[i].token);
5064         }
5065
5066         SAFE_FREE(tokens);
5067         return 1;
5068 }
5069
5070 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
5071 {
5072         d_printf(_("net usersidlist\n"
5073                    "\tprints out a list of all users the running winbind knows\n"
5074                    "\tabout, together with all their SIDs. This is used as\n"
5075                    "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5076
5077         net_common_flags_usage(c, argc, argv);
5078         return -1;
5079 }
5080
5081 /**
5082  * 'net rpc share' entrypoint.
5083  * @param argc  Standard main() style argc.
5084  * @param argv  Standard main() style argv. Initial components are already
5085  *              stripped.
5086  **/
5087
5088 int net_rpc_share(struct net_context *c, int argc, const char **argv)
5089 {
5090         NET_API_STATUS status;
5091
5092         struct functable func[] = {
5093                 {
5094                         "add",
5095                         rpc_share_add,
5096                         NET_TRANSPORT_RPC,
5097                         N_("Add share"),
5098                         N_("net rpc share add\n"
5099                            "    Add share")
5100                 },
5101                 {
5102                         "delete",
5103                         rpc_share_delete,
5104                         NET_TRANSPORT_RPC,
5105                         N_("Remove share"),
5106                         N_("net rpc share delete\n"
5107                            "    Remove share")
5108                 },
5109                 {
5110                         "allowedusers",
5111                         rpc_share_allowedusers,
5112                         NET_TRANSPORT_RPC,
5113                         N_("Modify allowed users"),
5114                         N_("net rpc share allowedusers\n"
5115                            "    Modify allowed users")
5116                 },
5117                 {
5118                         "migrate",
5119                         rpc_share_migrate,
5120                         NET_TRANSPORT_RPC,
5121                         N_("Migrate share to local server"),
5122                         N_("net rpc share migrate\n"
5123                            "    Migrate share to local server")
5124                 },
5125                 {
5126                         "list",
5127                         rpc_share_list,
5128                         NET_TRANSPORT_RPC,
5129                         N_("List shares"),
5130                         N_("net rpc share list\n"
5131                            "    List shares")
5132                 },
5133                 {NULL, NULL, 0, NULL, NULL}
5134         };
5135
5136         status = libnetapi_net_init(&c->netapi_ctx);
5137         if (status != 0) {
5138                 return -1;
5139         }
5140         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5141         libnetapi_set_password(c->netapi_ctx, c->opt_password);
5142         if (c->opt_kerberos) {
5143                 libnetapi_set_use_kerberos(c->netapi_ctx);
5144         }
5145
5146         if (argc == 0) {
5147                 if (c->display_usage) {
5148                         d_printf("%s\n%s",
5149                                  _("Usage:"),
5150                                  _("net rpc share\n"
5151                                    "    List shares\n"
5152                                    "    Alias for net rpc share list\n"));
5153                         net_display_usage_from_functable(func);
5154                         return 0;
5155                 }
5156
5157                 return rpc_share_list(c, argc, argv);
5158         }
5159
5160         return net_run_function(c, argc, argv, "net rpc share", func);
5161 }
5162
5163 static NTSTATUS rpc_sh_share_list(struct net_context *c,
5164                                   TALLOC_CTX *mem_ctx,
5165                                   struct rpc_sh_ctx *ctx,
5166                                   struct rpc_pipe_client *pipe_hnd,
5167                                   int argc, const char **argv)
5168 {
5169
5170         return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
5171 }
5172
5173 static NTSTATUS rpc_sh_share_add(struct net_context *c,
5174                                  TALLOC_CTX *mem_ctx,
5175                                  struct rpc_sh_ctx *ctx,
5176                                  struct rpc_pipe_client *pipe_hnd,
5177                                  int argc, const char **argv)
5178 {
5179         NET_API_STATUS status;
5180         uint32_t parm_err = 0;
5181         struct SHARE_INFO_2 i2;
5182
5183         if ((argc < 2) || (argc > 3)) {
5184                 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
5185                           ctx->whoami);
5186                 return NT_STATUS_INVALID_PARAMETER;
5187         }
5188
5189         i2.shi2_netname         = argv[0];
5190         i2.shi2_type            = STYPE_DISKTREE;
5191         i2.shi2_remark          = (argc == 3) ? argv[2] : "";
5192         i2.shi2_permissions     = 0;
5193         i2.shi2_max_uses        = 0;
5194         i2.shi2_current_uses    = 0;
5195         i2.shi2_path            = argv[1];
5196         i2.shi2_passwd          = NULL;
5197
5198         status = NetShareAdd(pipe_hnd->desthost,
5199                              2,
5200                              (uint8_t *)&i2,
5201                              &parm_err);
5202
5203         return werror_to_ntstatus(W_ERROR(status));
5204 }
5205
5206 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
5207                                     TALLOC_CTX *mem_ctx,
5208                                     struct rpc_sh_ctx *ctx,
5209                                     struct rpc_pipe_client *pipe_hnd,
5210                                     int argc, const char **argv)
5211 {
5212         if (argc != 1) {
5213                 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5214                 return NT_STATUS_INVALID_PARAMETER;
5215         }
5216
5217         return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
5218 }
5219
5220 static NTSTATUS rpc_sh_share_info(struct net_context *c,
5221                                   TALLOC_CTX *mem_ctx,
5222                                   struct rpc_sh_ctx *ctx,
5223                                   struct rpc_pipe_client *pipe_hnd,
5224                                   int argc, const char **argv)
5225 {
5226         union srvsvc_NetShareInfo info;
5227         WERROR result;
5228         NTSTATUS status;
5229         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5230
5231         if (argc != 1) {
5232                 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5233                 return NT_STATUS_INVALID_PARAMETER;
5234         }
5235
5236         status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5237                                                pipe_hnd->desthost,
5238                                                argv[0],
5239                                                2,
5240                                                &info,
5241                                                &result);
5242         if (!NT_STATUS_IS_OK(status)) {
5243                 result = ntstatus_to_werror(status);
5244                 goto done;
5245         }
5246         if (!W_ERROR_IS_OK(result)) {
5247                 goto done;
5248         }
5249
5250         d_printf(_("Name:     %s\n"), info.info2->name);
5251         d_printf(_("Comment:  %s\n"), info.info2->comment);
5252         d_printf(_("Path:     %s\n"), info.info2->path);
5253         d_printf(_("Password: %s\n"), info.info2->password);
5254
5255  done:
5256         return werror_to_ntstatus(result);
5257 }
5258
5259 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
5260                                       struct rpc_sh_ctx *ctx)
5261 {
5262         static struct rpc_sh_cmd cmds[] = {
5263
5264         { "list", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_list,
5265           N_("List available shares") },
5266
5267         { "add", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_add,
5268           N_("Add a share") },
5269
5270         { "delete", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_delete,
5271           N_("Delete a share") },
5272
5273         { "info", NULL, &ndr_table_srvsvc.syntax_id, rpc_sh_share_info,
5274           N_("Get information about a share") },
5275
5276         { NULL, NULL, 0, NULL, NULL }
5277         };
5278
5279         return cmds;
5280 }
5281
5282 /****************************************************************************/
5283
5284 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
5285 {
5286         return net_file_usage(c, argc, argv);
5287 }
5288
5289 /**
5290  * Close a file on a remote RPC server.
5291  *
5292  * @param argc  Standard main() style argc.
5293  * @param argv  Standard main() style argv. Initial components are already
5294  *              stripped.
5295  *
5296  * @return A shell status integer (0 for success).
5297  **/
5298 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5299 {
5300         if (argc < 1 || c->display_usage) {
5301                 return rpc_file_usage(c, argc, argv);
5302         }
5303
5304         return NetFileClose(c->opt_host, atoi(argv[0]));
5305 }
5306
5307 /**
5308  * Formatted print of open file info
5309  *
5310  * @param r  struct FILE_INFO_3 contents
5311  **/
5312
5313 static void display_file_info_3(struct FILE_INFO_3 *r)
5314 {
5315         d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5316                  r->fi3_id, r->fi3_username, r->fi3_permissions,
5317                  r->fi3_num_locks, r->fi3_pathname);
5318 }
5319
5320 /**
5321  * List files for a user on a remote RPC server.
5322  *
5323  * @param argc  Standard main() style argc.
5324  * @param argv  Standard main() style argv. Initial components are already
5325  *              stripped.
5326  *
5327  * @return A shell status integer (0 for success)..
5328  **/
5329
5330 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5331 {
5332         NET_API_STATUS status;
5333         uint32 preferred_len = 0xffffffff, i;
5334         const char *username=NULL;
5335         uint32_t total_entries = 0;
5336         uint32_t entries_read = 0;
5337         uint32_t resume_handle = 0;
5338         struct FILE_INFO_3 *i3 = NULL;
5339
5340         if (c->display_usage) {
5341                 return rpc_file_usage(c, argc, argv);
5342         }
5343
5344         /* if argc > 0, must be user command */
5345         if (argc > 0) {
5346                 username = smb_xstrdup(argv[0]);
5347         }
5348
5349         status = NetFileEnum(c->opt_host,
5350                              NULL,
5351                              username,
5352                              3,
5353                              (uint8_t **)(void *)&i3,
5354                              preferred_len,
5355                              &entries_read,
5356                              &total_entries,
5357                              &resume_handle);
5358
5359         if (status != 0) {
5360                 goto done;
5361         }
5362
5363         /* Display results */
5364
5365         d_printf(_(
5366                  "\nEnumerating open files on remote server:\n\n"
5367                  "\nFileId  Opened by            Perms  Locks  Path"
5368                  "\n------  ---------            -----  -----  ---- \n"));
5369         for (i = 0; i < entries_read; i++) {
5370                 display_file_info_3(&i3[i]);
5371         }
5372  done:
5373         return status;
5374 }
5375
5376 /**
5377  * 'net rpc file' entrypoint.
5378  * @param argc  Standard main() style argc.
5379  * @param argv  Standard main() style argv. Initial components are already
5380  *              stripped.
5381  **/
5382
5383 int net_rpc_file(struct net_context *c, int argc, const char **argv)
5384 {
5385         NET_API_STATUS status;
5386
5387         struct functable func[] = {
5388                 {
5389                         "close",
5390                         rpc_file_close,
5391                         NET_TRANSPORT_RPC,
5392                         N_("Close opened file"),
5393                         N_("net rpc file close\n"
5394                            "    Close opened file")
5395                 },
5396                 {
5397                         "user",
5398                         rpc_file_user,
5399                         NET_TRANSPORT_RPC,
5400                         N_("List files opened by user"),
5401                         N_("net rpc file user\n"
5402                            "    List files opened by user")
5403                 },
5404 #if 0
5405                 {
5406                         "info",
5407                         rpc_file_info,
5408                         NET_TRANSPORT_RPC,
5409                         N_("Display information about opened file"),
5410                         N_("net rpc file info\n"
5411                            "    Display information about opened file")
5412                 },
5413 #endif
5414                 {NULL, NULL, 0, NULL, NULL}
5415         };
5416
5417         status = libnetapi_net_init(&c->netapi_ctx);
5418         if (status != 0) {
5419                 return -1;
5420         }
5421         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5422         libnetapi_set_password(c->netapi_ctx, c->opt_password);
5423         if (c->opt_kerberos) {
5424                 libnetapi_set_use_kerberos(c->netapi_ctx);
5425         }
5426
5427         if (argc == 0) {
5428                 if (c->display_usage) {
5429                         d_printf(_("Usage:\n"));
5430                         d_printf(_("net rpc file\n"
5431                                    "    List opened files\n"));
5432                         net_display_usage_from_functable(func);
5433                         return 0;
5434                 }
5435
5436                 return rpc_file_user(c, argc, argv);
5437         }
5438
5439         return net_run_function(c, argc, argv, "net rpc file", func);
5440 }
5441
5442 /**
5443  * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5444  *
5445  * All parameters are provided by the run_rpc_command function, except for
5446  * argc, argv which are passed through.
5447  *
5448  * @param c     A net_context structure.
5449  * @param domain_sid The domain sid acquired from the remote server.
5450  * @param cli A cli_state connected to the server.
5451  * @param mem_ctx Talloc context, destroyed on completion of the function.
5452  * @param argc  Standard main() style argc.
5453  * @param argv  Standard main() style argv. Initial components are already
5454  *              stripped.
5455  *
5456  * @return Normal NTSTATUS return.
5457  **/
5458
5459 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5460                                         const struct dom_sid *domain_sid,
5461                                         const char *domain_name,
5462                                         struct cli_state *cli,
5463                                         struct rpc_pipe_client *pipe_hnd,
5464                                         TALLOC_CTX *mem_ctx,
5465                                         int argc,
5466                                         const char **argv)
5467 {
5468         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5469         WERROR result;
5470         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5471
5472         status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5473         if (!NT_STATUS_IS_OK(status)) {
5474                 return status;
5475         }
5476         if (W_ERROR_IS_OK(result)) {
5477                 d_printf(_("\nShutdown successfully aborted\n"));
5478                 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5479         } else
5480                 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5481
5482         return werror_to_ntstatus(result);
5483 }
5484
5485 /**
5486  * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5487  *
5488  * All parameters are provided by the run_rpc_command function, except for
5489  * argc, argv which are passed through.
5490  *
5491  * @param c     A net_context structure.
5492  * @param domain_sid The domain sid acquired from the remote server.
5493  * @param cli A cli_state connected to the server.
5494  * @param mem_ctx Talloc context, destroyed on completion of the function.
5495  * @param argc  Standard main() style argc.
5496  * @param argv  Standard main() style argv. Initial components are already
5497  *              stripped.
5498  *
5499  * @return Normal NTSTATUS return.
5500  **/
5501
5502 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5503                                                 const struct dom_sid *domain_sid,
5504                                                 const char *domain_name,
5505                                                 struct cli_state *cli,
5506                                                 struct rpc_pipe_client *pipe_hnd,
5507                                                 TALLOC_CTX *mem_ctx,
5508                                                 int argc,
5509                                                 const char **argv)
5510 {
5511         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5512         WERROR werr;
5513         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5514
5515         result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5516
5517         if (!NT_STATUS_IS_OK(result)) {
5518                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5519                 return result;
5520         }
5521         if (W_ERROR_IS_OK(werr)) {
5522                 d_printf(_("\nShutdown successfully aborted\n"));
5523                 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5524         } else
5525                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5526
5527         return werror_to_ntstatus(werr);
5528 }
5529
5530 /**
5531  * ABORT the shutdown of a remote RPC server.
5532  *
5533  * @param argc  Standard main() style argc.
5534  * @param argv  Standard main() style argv. Initial components are already
5535  *              stripped.
5536  *
5537  * @return A shell status integer (0 for success).
5538  **/
5539
5540 static int rpc_shutdown_abort(struct net_context *c, int argc,
5541                               const char **argv)
5542 {
5543         int rc = -1;
5544
5545         if (c->display_usage) {
5546                 d_printf(  "%s\n"
5547                            "net rpc abortshutdown\n"
5548                            "    %s\n",
5549                          _("Usage:"),
5550                          _("Abort a scheduled shutdown"));
5551                 return 0;
5552         }
5553
5554         rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5555                              rpc_shutdown_abort_internals, argc, argv);
5556
5557         if (rc == 0)
5558                 return rc;
5559
5560         DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5561
5562         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5563                                rpc_reg_shutdown_abort_internals,
5564                                argc, argv);
5565 }
5566
5567 /**
5568  * Shut down a remote RPC Server via initshutdown pipe.
5569  *
5570  * All parameters are provided by the run_rpc_command function, except for
5571  * argc, argv which are passed through.
5572  *
5573  * @param c     A net_context structure.
5574  * @param domain_sid The domain sid acquired from the remote server.
5575  * @param cli A cli_state connected to the server.
5576  * @param mem_ctx Talloc context, destroyed on completion of the function.
5577  * @param argc  Standard main() style argc.
5578  * @param argv  Standard main() style argv. Initial components are already
5579  *              stripped.
5580  *
5581  * @return Normal NTSTATUS return.
5582  **/
5583
5584 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5585                                      const struct dom_sid *domain_sid,
5586                                      const char *domain_name,
5587                                      struct cli_state *cli,
5588                                      struct rpc_pipe_client *pipe_hnd,
5589                                      TALLOC_CTX *mem_ctx,
5590                                      int argc,
5591                                      const char **argv)
5592 {
5593         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5594         WERROR result;
5595         const char *msg = N_("This machine will be shutdown shortly");
5596         uint32 timeout = 20;
5597         struct lsa_StringLarge msg_string;
5598         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5599
5600         if (c->opt_comment) {
5601                 msg = c->opt_comment;
5602         }
5603         if (c->opt_timeout) {
5604                 timeout = c->opt_timeout;
5605         }
5606
5607         msg_string.string = msg;
5608
5609         /* create an entry */
5610         status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5611                         &msg_string, timeout, c->opt_force, c->opt_reboot,
5612                         &result);
5613         if (!NT_STATUS_IS_OK(status)) {
5614                 return status;
5615         }
5616         if (W_ERROR_IS_OK(result)) {
5617                 d_printf(_("\nShutdown of remote machine succeeded\n"));
5618                 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5619         } else {
5620                 DEBUG(1,("Shutdown of remote machine failed!\n"));
5621         }
5622         return werror_to_ntstatus(result);
5623 }
5624
5625 /**
5626  * Shut down a remote RPC Server via winreg pipe.
5627  *
5628  * All parameters are provided by the run_rpc_command function, except for
5629  * argc, argv which are passed through.
5630  *
5631  * @param c     A net_context structure.
5632  * @param domain_sid The domain sid acquired from the remote server.
5633  * @param cli A cli_state connected to the server.
5634  * @param mem_ctx Talloc context, destroyed on completion of the function.
5635  * @param argc  Standard main() style argc.
5636  * @param argv  Standard main() style argv. Initial components are already
5637  *              stripped.
5638  *
5639  * @return Normal NTSTATUS return.
5640  **/
5641
5642 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5643                                     const struct dom_sid *domain_sid,
5644                                     const char *domain_name,
5645                                     struct cli_state *cli,
5646                                     struct rpc_pipe_client *pipe_hnd,
5647                                     TALLOC_CTX *mem_ctx,
5648                                     int argc,
5649                                     const char **argv)
5650 {
5651         const char *msg = N_("This machine will be shutdown shortly");
5652         uint32 timeout = 20;
5653         struct lsa_StringLarge msg_string;
5654         NTSTATUS result;
5655         WERROR werr;
5656         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5657
5658         if (c->opt_comment) {
5659                 msg = c->opt_comment;
5660         }
5661         msg_string.string = msg;
5662
5663         if (c->opt_timeout) {
5664                 timeout = c->opt_timeout;
5665         }
5666
5667         /* create an entry */
5668         result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
5669                         &msg_string, timeout, c->opt_force, c->opt_reboot,
5670                         &werr);
5671         if (!NT_STATUS_IS_OK(result)) {
5672                 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5673                 return result;
5674         }
5675
5676         if (W_ERROR_IS_OK(werr)) {
5677                 d_printf(_("\nShutdown of remote machine succeeded\n"));
5678         } else {
5679                 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5680                 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5681                         d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5682                 else
5683                         d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
5684         }
5685
5686         return werror_to_ntstatus(werr);
5687 }
5688
5689 /**
5690  * Shut down a remote RPC server.
5691  *
5692  * @param argc  Standard main() style argc.
5693  * @param argv  Standard main() style argv. Initial components are already
5694  *              stripped.
5695  *
5696  * @return A shell status integer (0 for success).
5697  **/
5698
5699 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
5700 {
5701         int rc =  -1;
5702
5703         if (c->display_usage) {
5704                 d_printf(  "%s\n"
5705                            "net rpc shutdown\n"
5706                            "    %s\n",
5707                          _("Usage:"),
5708                          _("Shut down a remote RPC server"));
5709                 return 0;
5710         }
5711
5712         rc = run_rpc_command(c, NULL, &ndr_table_initshutdown.syntax_id, 0,
5713                              rpc_init_shutdown_internals, argc, argv);
5714
5715         if (rc) {
5716                 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5717                 rc = run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
5718                                      rpc_reg_shutdown_internals, argc, argv);
5719         }
5720
5721         return rc;
5722 }
5723
5724 /***************************************************************************
5725   NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5726  ***************************************************************************/
5727
5728 /**
5729  * Add interdomain trust account to the RPC server.
5730  * All parameters (except for argc and argv) are passed by run_rpc_command
5731  * function.
5732  *
5733  * @param c     A net_context structure.
5734  * @param domain_sid The domain sid acquired from the server.
5735  * @param cli A cli_state connected to the server.
5736  * @param mem_ctx Talloc context, destroyed on completion of the function.
5737  * @param argc  Standard main() style argc.
5738  * @param argv  Standard main() style argv. Initial components are already
5739  *              stripped.
5740  *
5741  * @return normal NTSTATUS return code.
5742  */
5743
5744 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
5745                                                 const struct dom_sid *domain_sid,
5746                                                 const char *domain_name,
5747                                                 struct cli_state *cli,
5748                                                 struct rpc_pipe_client *pipe_hnd,
5749                                                 TALLOC_CTX *mem_ctx,
5750                                                 int argc,
5751                                                 const char **argv)
5752 {
5753         struct policy_handle connect_pol, domain_pol, user_pol;
5754         NTSTATUS status, result;
5755         char *acct_name;
5756         struct lsa_String lsa_acct_name;
5757         uint32 acb_info;
5758         uint32 acct_flags=0;
5759         uint32 user_rid;
5760         uint32_t access_granted = 0;
5761         union samr_UserInfo info;
5762         unsigned int orig_timeout;
5763         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5764
5765         if (argc != 2) {
5766                 d_printf("%s\n%s",
5767                          _("Usage:"),
5768                          _(" net rpc trustdom add <domain_name> "
5769                            "<trust password>\n"));
5770                 return NT_STATUS_INVALID_PARAMETER;
5771         }
5772
5773         /*
5774          * Make valid trusting domain account (ie. uppercased and with '$' appended)
5775          */
5776
5777         if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5778                 return NT_STATUS_NO_MEMORY;
5779         }
5780
5781         strupper_m(acct_name);
5782
5783         init_lsa_String(&lsa_acct_name, acct_name);
5784
5785         /* Get samr policy handle */
5786         status = dcerpc_samr_Connect2(b, mem_ctx,
5787                                       pipe_hnd->desthost,
5788                                       MAXIMUM_ALLOWED_ACCESS,
5789                                       &connect_pol,
5790                                       &result);
5791         if (!NT_STATUS_IS_OK(status)) {
5792                 goto done;
5793         }
5794         if (!NT_STATUS_IS_OK(result)) {
5795                 status = result;
5796                 goto done;
5797         }
5798
5799         /* Get domain policy handle */
5800         status = dcerpc_samr_OpenDomain(b, mem_ctx,
5801                                         &connect_pol,
5802                                         MAXIMUM_ALLOWED_ACCESS,
5803                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
5804                                         &domain_pol,
5805                                         &result);
5806         if (!NT_STATUS_IS_OK(status)) {
5807                 goto done;
5808         }
5809         if (!NT_STATUS_IS_OK(result)) {
5810                 status = result;
5811                 goto done;
5812         }
5813
5814         /* This call can take a long time - allow the server to time out.
5815          * 35 seconds should do it. */
5816
5817         orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
5818
5819         /* Create trusting domain's account */
5820         acb_info = ACB_NORMAL;
5821         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5822                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5823                      SAMR_USER_ACCESS_SET_PASSWORD |
5824                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
5825                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
5826
5827         status = dcerpc_samr_CreateUser2(b, mem_ctx,
5828                                          &domain_pol,
5829                                          &lsa_acct_name,
5830                                          acb_info,
5831                                          acct_flags,
5832                                          &user_pol,
5833                                          &access_granted,
5834                                          &user_rid,
5835                                          &result);
5836         if (!NT_STATUS_IS_OK(status)) {
5837                 goto done;
5838         }
5839         /* And restore our original timeout. */
5840         rpccli_set_timeout(pipe_hnd, orig_timeout);
5841
5842         if (!NT_STATUS_IS_OK(result)) {
5843                 status = result;
5844                 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
5845                         acct_name, nt_errstr(result));
5846                 goto done;
5847         }
5848
5849         {
5850                 struct samr_CryptPassword crypt_pwd;
5851
5852                 ZERO_STRUCT(info.info23);
5853
5854                 init_samr_CryptPassword(argv[1],
5855                                         &cli->user_session_key,
5856                                         &crypt_pwd);
5857
5858                 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
5859                                                   SAMR_FIELD_NT_PASSWORD_PRESENT;
5860                 info.info23.info.acct_flags = ACB_DOMTRUST;
5861                 info.info23.password = crypt_pwd;
5862
5863                 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
5864                                                   &user_pol,
5865                                                   23,
5866                                                   &info,
5867                                                   &result);
5868                 if (!NT_STATUS_IS_OK(status)) {
5869                         goto done;
5870                 }
5871
5872                 if (!NT_STATUS_IS_OK(result)) {
5873                         status = result;
5874                         DEBUG(0,("Could not set trust account password: %s\n",
5875                                  nt_errstr(result)));
5876                         goto done;
5877                 }
5878         }
5879
5880  done:
5881         SAFE_FREE(acct_name);
5882         return status;
5883 }
5884
5885 /**
5886  * Create interdomain trust account for a remote domain.
5887  *
5888  * @param argc Standard argc.
5889  * @param argv Standard argv without initial components.
5890  *
5891  * @return Integer status (0 means success).
5892  **/
5893
5894 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
5895 {
5896         if (argc > 0 && !c->display_usage) {
5897                 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
5898                                        rpc_trustdom_add_internals, argc, argv);
5899         } else {
5900                 d_printf("%s\n%s",
5901                          _("Usage:"),
5902                          _("net rpc trustdom add <domain_name> <trust "
5903                            "password>\n"));
5904                 return -1;
5905         }
5906 }
5907
5908
5909 /**
5910  * Remove interdomain trust account from the RPC server.
5911  * All parameters (except for argc and argv) are passed by run_rpc_command
5912  * function.
5913  *
5914  * @param c     A net_context structure.
5915  * @param domain_sid The domain sid acquired from the server.
5916  * @param cli A cli_state connected to the server.
5917  * @param mem_ctx Talloc context, destroyed on completion of the function.
5918  * @param argc  Standard main() style argc.
5919  * @param argv  Standard main() style argv. Initial components are already
5920  *              stripped.
5921  *
5922  * @return normal NTSTATUS return code.
5923  */
5924
5925 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
5926                                         const struct dom_sid *domain_sid,
5927                                         const char *domain_name,
5928                                         struct cli_state *cli,
5929                                         struct rpc_pipe_client *pipe_hnd,
5930                                         TALLOC_CTX *mem_ctx,
5931                                         int argc,
5932                                         const char **argv)
5933 {
5934         struct policy_handle connect_pol, domain_pol, user_pol;
5935         NTSTATUS status, result;
5936         char *acct_name;
5937         struct dom_sid trust_acct_sid;
5938         struct samr_Ids user_rids, name_types;
5939         struct lsa_String lsa_acct_name;
5940         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5941
5942         if (argc != 1) {
5943                 d_printf("%s\n%s",
5944                          _("Usage:"),
5945                          _(" net rpc trustdom del <domain_name>\n"));
5946                 return NT_STATUS_INVALID_PARAMETER;
5947         }
5948
5949         /*
5950          * Make valid trusting domain account (ie. uppercased and with '$' appended)
5951          */
5952         acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5953
5954         if (acct_name == NULL)
5955                 return NT_STATUS_NO_MEMORY;
5956
5957         strupper_m(acct_name);
5958
5959         /* Get samr policy handle */
5960         status = dcerpc_samr_Connect2(b, mem_ctx,
5961                                       pipe_hnd->desthost,
5962                                       MAXIMUM_ALLOWED_ACCESS,
5963                                       &connect_pol,
5964                                       &result);
5965         if (!NT_STATUS_IS_OK(status)) {
5966                 goto done;
5967         }
5968         if (!NT_STATUS_IS_OK(result)) {
5969                 status = result;
5970                 goto done;
5971         }
5972
5973         /* Get domain policy handle */
5974         status = dcerpc_samr_OpenDomain(b, mem_ctx,
5975                                         &connect_pol,
5976                                         MAXIMUM_ALLOWED_ACCESS,
5977                                         CONST_DISCARD(struct dom_sid2 *, domain_sid),
5978                                         &domain_pol,
5979                                         &result);
5980         if (!NT_STATUS_IS_OK(status)) {
5981                 goto done;
5982         }
5983         if (!NT_STATUS_IS_OK(result)) {
5984                 status = result;
5985                 goto done;
5986         }
5987
5988         init_lsa_String(&lsa_acct_name, acct_name);
5989
5990         status = dcerpc_samr_LookupNames(b, mem_ctx,
5991                                          &domain_pol,
5992                                          1,
5993                                          &lsa_acct_name,
5994                                          &user_rids,
5995                                          &name_types,
5996                                          &result);
5997         if (!NT_STATUS_IS_OK(status)) {
5998                 d_printf(_("net rpc trustdom del: LookupNames on user %s "
5999                            "failed %s\n"),
6000                         acct_name, nt_errstr(status));
6001                 goto done;
6002         }
6003         if (!NT_STATUS_IS_OK(result)) {
6004                 status = result;
6005                 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6006                            "failed %s\n"),
6007                         acct_name, nt_errstr(result) );
6008                 goto done;
6009         }
6010
6011         status = dcerpc_samr_OpenUser(b, mem_ctx,
6012                                       &domain_pol,
6013                                       MAXIMUM_ALLOWED_ACCESS,
6014                                       user_rids.ids[0],
6015                                       &user_pol,
6016                                       &result);
6017         if (!NT_STATUS_IS_OK(status)) {
6018                 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6019                            "%s\n"),
6020                         acct_name, nt_errstr(status) );
6021                 goto done;
6022         }
6023
6024         if (!NT_STATUS_IS_OK(result)) {
6025                 status = result;
6026                 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6027                            "%s\n"),
6028                         acct_name, nt_errstr(result) );
6029                 goto done;
6030         }
6031
6032         /* append the rid to the domain sid */
6033         if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
6034                 goto done;
6035         }
6036
6037         /* remove the sid */
6038
6039         status = dcerpc_samr_RemoveMemberFromForeignDomain(b, mem_ctx,
6040                                                            &user_pol,
6041                                                            &trust_acct_sid,
6042                                                            &result);
6043         if (!NT_STATUS_IS_OK(status)) {
6044                 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6045                            " on user %s failed %s\n"),
6046                         acct_name, nt_errstr(status));
6047                 goto done;
6048         }
6049         if (!NT_STATUS_IS_OK(result)) {
6050                 status = result;
6051                 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6052                            " on user %s failed %s\n"),
6053                         acct_name, nt_errstr(result) );
6054                 goto done;
6055         }
6056
6057
6058         /* Delete user */
6059
6060         status = dcerpc_samr_DeleteUser(b, mem_ctx,
6061                                         &user_pol,
6062                                         &result);
6063         if (!NT_STATUS_IS_OK(status)) {
6064                 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6065                            "%s\n"),
6066                         acct_name, nt_errstr(status));
6067                 goto done;
6068         }
6069
6070         if (!NT_STATUS_IS_OK(result)) {
6071                 result = status;
6072                 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6073                            "%s\n"),
6074                         acct_name, nt_errstr(result) );
6075                 goto done;
6076         }
6077
6078         if (!NT_STATUS_IS_OK(result)) {
6079                 d_printf(_("Could not set trust account password: %s\n"),
6080                    nt_errstr(result));
6081                 goto done;
6082         }
6083
6084  done:
6085         return status;
6086 }
6087
6088 /**
6089  * Delete interdomain trust account for a remote domain.
6090  *
6091  * @param argc Standard argc.
6092  * @param argv Standard argv without initial components.
6093  *
6094  * @return Integer status (0 means success).
6095  **/
6096
6097 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
6098 {
6099         if (argc > 0 && !c->display_usage) {
6100                 return run_rpc_command(c, NULL, &ndr_table_samr.syntax_id, 0,
6101                                        rpc_trustdom_del_internals, argc, argv);
6102         } else {
6103                 d_printf("%s\n%s",
6104                          _("Usage:"),
6105                          _("net rpc trustdom del <domain>\n"));
6106                 return -1;
6107         }
6108 }
6109
6110 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
6111                                      struct cli_state *cli,
6112                                      TALLOC_CTX *mem_ctx,
6113                                      const char *domain_name)
6114 {
6115         char *dc_name = NULL;
6116         const char *buffer = NULL;
6117         struct rpc_pipe_client *netr;
6118         NTSTATUS status;
6119         WERROR result;
6120         struct dcerpc_binding_handle *b;
6121
6122         /* Use NetServerEnum2 */
6123
6124         if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
6125                 SAFE_FREE(dc_name);
6126                 return NT_STATUS_OK;
6127         }
6128
6129         DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6130                  for domain %s\n", domain_name));
6131
6132         /* Try netr_GetDcName */
6133
6134         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
6135                                           &netr);
6136         if (!NT_STATUS_IS_OK(status)) {
6137                 return status;
6138         }
6139
6140         b = netr->binding_handle;
6141
6142         status = dcerpc_netr_GetDcName(b, mem_ctx,
6143                                        cli->desthost,
6144                                        domain_name,
6145                                        &buffer,
6146                                        &result);
6147         TALLOC_FREE(netr);
6148
6149         if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
6150                 return status;
6151         }
6152
6153         DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6154                  for domain %s\n", domain_name));
6155
6156         if (!NT_STATUS_IS_OK(status)) {
6157                 return status;
6158         }
6159
6160         return werror_to_ntstatus(result);
6161 }
6162
6163 /**
6164  * Establish trust relationship to a trusting domain.
6165  * Interdomain account must already be created on remote PDC.
6166  *
6167  * @param c    A net_context structure.
6168  * @param argc Standard argc.
6169  * @param argv Standard argv without initial components.
6170  *
6171  * @return Integer status (0 means success).
6172  **/
6173
6174 static int rpc_trustdom_establish(struct net_context *c, int argc,
6175                                   const char **argv)
6176 {
6177         struct cli_state *cli = NULL;
6178         struct sockaddr_storage server_ss;
6179         struct rpc_pipe_client *pipe_hnd = NULL;
6180         struct policy_handle connect_hnd;
6181         TALLOC_CTX *mem_ctx;
6182         NTSTATUS nt_status, result;
6183         struct dom_sid *domain_sid;
6184
6185         char* domain_name;
6186         char* acct_name;
6187         fstring pdc_name;
6188         union lsa_PolicyInformation *info = NULL;
6189         struct dcerpc_binding_handle *b;
6190
6191         /*
6192          * Connect to \\server\ipc$ as 'our domain' account with password
6193          */
6194
6195         if (argc != 1 || c->display_usage) {
6196                 d_printf("%s\n%s",
6197                          _("Usage:"),
6198                          _("net rpc trustdom establish <domain_name>\n"));
6199                 return -1;
6200         }
6201
6202         domain_name = smb_xstrdup(argv[0]);
6203         strupper_m(domain_name);
6204
6205         /* account name used at first is our domain's name with '$' */
6206         if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
6207                 return -1;
6208         }
6209         strupper_m(acct_name);
6210
6211         /*
6212          * opt_workgroup will be used by connection functions further,
6213          * hence it should be set to remote domain name instead of ours
6214          */
6215         if (c->opt_workgroup) {
6216                 c->opt_workgroup = smb_xstrdup(domain_name);
6217         };
6218
6219         c->opt_user_name = acct_name;
6220
6221         /* find the domain controller */
6222         if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
6223                 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
6224                 return -1;
6225         }
6226
6227         /* connect to ipc$ as username/password */
6228         nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
6229         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
6230
6231                 /* Is it trusting domain account for sure ? */
6232                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6233                         nt_errstr(nt_status)));
6234                 return -1;
6235         }
6236
6237         /* store who we connected to */
6238
6239         saf_store( domain_name, pdc_name );
6240
6241         /*
6242          * Connect to \\server\ipc$ again (this time anonymously)
6243          */
6244
6245         nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
6246                                              (char*)pdc_name);
6247
6248         if (NT_STATUS_IS_ERR(nt_status)) {
6249                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6250                         domain_name, nt_errstr(nt_status)));
6251                 return -1;
6252         }
6253
6254         if (!(mem_ctx = talloc_init("establishing trust relationship to "
6255                                     "domain %s", domain_name))) {
6256                 DEBUG(0, ("talloc_init() failed\n"));
6257                 cli_shutdown(cli);
6258                 return -1;
6259         }
6260
6261         /* Make sure we're talking to a proper server */
6262
6263         nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
6264         if (!NT_STATUS_IS_OK(nt_status)) {
6265                 cli_shutdown(cli);
6266                 talloc_destroy(mem_ctx);
6267                 return -1;
6268         }
6269
6270         /*
6271          * Call LsaOpenPolicy and LsaQueryInfo
6272          */
6273
6274         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6275                                              &pipe_hnd);
6276         if (!NT_STATUS_IS_OK(nt_status)) {
6277                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
6278                 cli_shutdown(cli);
6279                 talloc_destroy(mem_ctx);
6280                 return -1;
6281         }
6282
6283         b = pipe_hnd->binding_handle;
6284
6285         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
6286                                          &connect_hnd);
6287         if (NT_STATUS_IS_ERR(nt_status)) {
6288                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6289                         nt_errstr(nt_status)));
6290                 cli_shutdown(cli);
6291                 talloc_destroy(mem_ctx);
6292                 return -1;
6293         }
6294
6295         /* Querying info level 5 */
6296
6297         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6298                                                &connect_hnd,
6299                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6300                                                &info,
6301                                                &result);
6302         if (NT_STATUS_IS_ERR(nt_status)) {
6303                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6304                         nt_errstr(nt_status)));
6305                 cli_shutdown(cli);
6306                 talloc_destroy(mem_ctx);
6307                 return -1;
6308         }
6309         if (NT_STATUS_IS_ERR(result)) {
6310                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6311                         nt_errstr(result)));
6312                 cli_shutdown(cli);
6313                 talloc_destroy(mem_ctx);
6314                 return -1;
6315         }
6316
6317         domain_sid = info->account_domain.sid;
6318
6319         /* There should be actually query info level 3 (following nt serv behaviour),
6320            but I still don't know if it's _really_ necessary */
6321
6322         /*
6323          * Store the password in secrets db
6324          */
6325
6326         if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
6327                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6328                 cli_shutdown(cli);
6329                 talloc_destroy(mem_ctx);
6330                 return -1;
6331         }
6332
6333         /*
6334          * Close the pipes and clean up
6335          */
6336
6337         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6338         if (NT_STATUS_IS_ERR(nt_status)) {
6339                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6340                         nt_errstr(nt_status)));
6341                 cli_shutdown(cli);
6342                 talloc_destroy(mem_ctx);
6343                 return -1;
6344         }
6345
6346         cli_shutdown(cli);
6347
6348         talloc_destroy(mem_ctx);
6349
6350         d_printf(_("Trust to domain %s established\n"), domain_name);
6351         return 0;
6352 }
6353
6354 /**
6355  * Revoke trust relationship to the remote domain.
6356  *
6357  * @param c    A net_context structure.
6358  * @param argc Standard argc.
6359  * @param argv Standard argv without initial components.
6360  *
6361  * @return Integer status (0 means success).
6362  **/
6363
6364 static int rpc_trustdom_revoke(struct net_context *c, int argc,
6365                                const char **argv)
6366 {
6367         char* domain_name;
6368         int rc = -1;
6369
6370         if (argc < 1 || c->display_usage) {
6371                 d_printf("%s\n%s",
6372                          _("Usage:"),
6373                          _("net rpc trustdom revoke <domain_name>\n"
6374                            "  Revoke trust relationship\n"
6375                            "    domain_name\tName of domain to revoke trust\n"));
6376                 return -1;
6377         }
6378
6379         /* generate upper cased domain name */
6380         domain_name = smb_xstrdup(argv[0]);
6381         strupper_m(domain_name);
6382
6383         /* delete password of the trust */
6384         if (!pdb_del_trusteddom_pw(domain_name)) {
6385                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6386                           domain_name));
6387                 goto done;
6388         };
6389
6390         rc = 0;
6391 done:
6392         SAFE_FREE(domain_name);
6393         return rc;
6394 }
6395
6396 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6397                                         const struct dom_sid *domain_sid,
6398                                         const char *domain_name,
6399                                         struct cli_state *cli,
6400                                         struct rpc_pipe_client *pipe_hnd,
6401                                         TALLOC_CTX *mem_ctx,
6402                                         int argc,
6403                                         const char **argv)
6404 {
6405         fstring str_sid;
6406         if (!sid_to_fstring(str_sid, domain_sid)) {
6407                 return NT_STATUS_UNSUCCESSFUL;
6408         }
6409         d_printf("%s\n", str_sid);
6410         return NT_STATUS_OK;
6411 }
6412
6413 static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6414 {
6415         fstring ascii_sid;
6416
6417         /* convert sid into ascii string */
6418         sid_to_fstring(ascii_sid, dom_sid);
6419
6420         d_printf("%-20s%s\n", trusted_dom_name, ascii_sid);
6421 }
6422
6423 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6424                                       TALLOC_CTX *mem_ctx,
6425                                       struct policy_handle *pol,
6426                                       struct dom_sid dom_sid,
6427                                       const char *trusted_dom_name)
6428 {
6429         NTSTATUS nt_status, result;
6430         union lsa_TrustedDomainInfo *info = NULL;
6431         char *cleartextpwd = NULL;
6432         uint8_t session_key[16];
6433         DATA_BLOB session_key_blob;
6434         DATA_BLOB data = data_blob_null;
6435         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6436
6437         nt_status = dcerpc_lsa_QueryTrustedDomainInfoBySid(b, mem_ctx,
6438                                                            pol,
6439                                                            &dom_sid,
6440                                                            LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6441                                                            &info,
6442                                                            &result);
6443         if (NT_STATUS_IS_ERR(nt_status)) {
6444                 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6445                 nt_errstr(nt_status)));
6446                 goto done;
6447         }
6448         if (NT_STATUS_IS_ERR(result)) {
6449                 nt_status = result;
6450                 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6451                 nt_errstr(result)));
6452                 goto done;
6453         }
6454
6455         data = data_blob(info->password.password->data,
6456                          info->password.password->length);
6457
6458         if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) {
6459                 DEBUG(0, ("Could not retrieve password hash\n"));
6460                 goto done;
6461         }
6462
6463         session_key_blob = data_blob_const(session_key, sizeof(session_key));
6464         cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob);
6465
6466         if (cleartextpwd == NULL) {
6467                 DEBUG(0,("retrieved NULL password\n"));
6468                 nt_status = NT_STATUS_UNSUCCESSFUL;
6469                 goto done;
6470         }
6471
6472         if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6473                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6474                 nt_status = NT_STATUS_UNSUCCESSFUL;
6475                 goto done;
6476         }
6477
6478 #ifdef DEBUG_PASSWORD
6479         DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6480                    "password: [%s]\n", trusted_dom_name,
6481                    sid_string_dbg(&dom_sid), cleartextpwd));
6482 #endif
6483
6484 done:
6485         SAFE_FREE(cleartextpwd);
6486         data_blob_free(&data);
6487
6488         return nt_status;
6489 }
6490
6491 static int rpc_trustdom_vampire(struct net_context *c, int argc,
6492                                 const char **argv)
6493 {
6494         /* common variables */
6495         TALLOC_CTX* mem_ctx;
6496         struct cli_state *cli = NULL;
6497         struct rpc_pipe_client *pipe_hnd = NULL;
6498         NTSTATUS nt_status, result;
6499         const char *domain_name = NULL;
6500         struct dom_sid *queried_dom_sid;
6501         struct policy_handle connect_hnd;
6502         union lsa_PolicyInformation *info = NULL;
6503
6504         /* trusted domains listing variables */
6505         unsigned int enum_ctx = 0;
6506         int i;
6507         struct lsa_DomainList dom_list;
6508         fstring pdc_name;
6509         struct dcerpc_binding_handle *b;
6510
6511         if (c->display_usage) {
6512                 d_printf(  "%s\n"
6513                            "net rpc trustdom vampire\n"
6514                            "  %s\n",
6515                          _("Usage:"),
6516                          _("Vampire trust relationship from remote server"));
6517                 return 0;
6518         }
6519
6520         /*
6521          * Listing trusted domains (stored in secrets.tdb, if local)
6522          */
6523
6524         mem_ctx = talloc_init("trust relationships vampire");
6525
6526         /*
6527          * set domain and pdc name to local samba server (default)
6528          * or to remote one given in command line
6529          */
6530
6531         if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6532                 domain_name = c->opt_workgroup;
6533                 c->opt_target_workgroup = c->opt_workgroup;
6534         } else {
6535                 fstrcpy(pdc_name, global_myname());
6536                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6537                 c->opt_target_workgroup = domain_name;
6538         };
6539
6540         /* open \PIPE\lsarpc and open policy handle */
6541         nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6542         if (!NT_STATUS_IS_OK(nt_status)) {
6543                 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6544                           nt_errstr(nt_status)));
6545                 talloc_destroy(mem_ctx);
6546                 return -1;
6547         };
6548
6549         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6550                                              &pipe_hnd);
6551         if (!NT_STATUS_IS_OK(nt_status)) {
6552                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6553                         nt_errstr(nt_status) ));
6554                 cli_shutdown(cli);
6555                 talloc_destroy(mem_ctx);
6556                 return -1;
6557         };
6558
6559         b = pipe_hnd->binding_handle;
6560
6561         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6562                                         &connect_hnd);
6563         if (NT_STATUS_IS_ERR(nt_status)) {
6564                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6565                         nt_errstr(nt_status)));
6566                 cli_shutdown(cli);
6567                 talloc_destroy(mem_ctx);
6568                 return -1;
6569         };
6570
6571         /* query info level 5 to obtain sid of a domain being queried */
6572         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6573                                                &connect_hnd,
6574                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6575                                                &info,
6576                                                &result);
6577
6578         if (NT_STATUS_IS_ERR(nt_status)) {
6579                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6580                         nt_errstr(nt_status)));
6581                 cli_shutdown(cli);
6582                 talloc_destroy(mem_ctx);
6583                 return -1;
6584         }
6585         if (NT_STATUS_IS_ERR(result)) {
6586                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6587                         nt_errstr(result)));
6588                 cli_shutdown(cli);
6589                 talloc_destroy(mem_ctx);
6590                 return -1;
6591         }
6592
6593         queried_dom_sid = info->account_domain.sid;
6594
6595         /*
6596          * Keep calling LsaEnumTrustdom over opened pipe until
6597          * the end of enumeration is reached
6598          */
6599
6600         d_printf(_("Vampire trusted domains:\n\n"));
6601
6602         do {
6603                 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6604                                                     &connect_hnd,
6605                                                     &enum_ctx,
6606                                                     &dom_list,
6607                                                     (uint32_t)-1,
6608                                                     &result);
6609                 if (NT_STATUS_IS_ERR(nt_status)) {
6610                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6611                                 nt_errstr(nt_status)));
6612                         cli_shutdown(cli);
6613                         talloc_destroy(mem_ctx);
6614                         return -1;
6615                 };
6616                 if (NT_STATUS_IS_ERR(result)) {
6617                         nt_status = result;
6618                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6619                                 nt_errstr(result)));
6620                         cli_shutdown(cli);
6621                         talloc_destroy(mem_ctx);
6622                         return -1;
6623                 };
6624
6625
6626                 for (i = 0; i < dom_list.count; i++) {
6627
6628                         print_trusted_domain(dom_list.domains[i].sid,
6629                                              dom_list.domains[i].name.string);
6630
6631                         nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd, 
6632                                                            *dom_list.domains[i].sid,
6633                                                            dom_list.domains[i].name.string);
6634                         if (!NT_STATUS_IS_OK(nt_status)) {
6635                                 cli_shutdown(cli);
6636                                 talloc_destroy(mem_ctx);
6637                                 return -1;
6638                         }
6639                 };
6640
6641                 /*
6642                  * in case of no trusted domains say something rather
6643                  * than just display blank line
6644                  */
6645                 if (!dom_list.count) d_printf(_("none\n"));
6646
6647         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6648
6649         /* close this connection before doing next one */
6650         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6651         if (NT_STATUS_IS_ERR(nt_status)) {
6652                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6653                         nt_errstr(nt_status)));
6654                 cli_shutdown(cli);
6655                 talloc_destroy(mem_ctx);
6656                 return -1;
6657         };
6658
6659         /* close lsarpc pipe and connection to IPC$ */
6660         cli_shutdown(cli);
6661
6662         talloc_destroy(mem_ctx);
6663         return 0;
6664 }
6665
6666 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
6667 {
6668         /* common variables */
6669         TALLOC_CTX* mem_ctx;
6670         struct cli_state *cli = NULL, *remote_cli = NULL;
6671         struct rpc_pipe_client *pipe_hnd = NULL;
6672         NTSTATUS nt_status, result;
6673         const char *domain_name = NULL;
6674         struct dom_sid *queried_dom_sid;
6675         int ascii_dom_name_len;
6676         struct policy_handle connect_hnd;
6677         union lsa_PolicyInformation *info = NULL;
6678         struct dcerpc_binding_handle *b = NULL;
6679
6680         /* trusted domains listing variables */
6681         unsigned int num_domains, enum_ctx = 0;
6682         int i;
6683         struct lsa_DomainList dom_list;
6684         fstring pdc_name;
6685         bool found_domain;
6686
6687         /* trusting domains listing variables */
6688         struct policy_handle domain_hnd;
6689         struct samr_SamArray *trusts = NULL;
6690
6691         if (c->display_usage) {
6692                 d_printf(  "%s\n"
6693                            "net rpc trustdom list\n"
6694                            "    %s\n",
6695                          _("Usage:"),
6696                          _("List incoming and outgoing trust relationships"));
6697                 return 0;
6698         }
6699
6700         /*
6701          * Listing trusted domains (stored in secrets.tdb, if local)
6702          */
6703
6704         mem_ctx = talloc_init("trust relationships listing");
6705
6706         /*
6707          * set domain and pdc name to local samba server (default)
6708          * or to remote one given in command line
6709          */
6710
6711         if (StrCaseCmp(c->opt_workgroup, lp_workgroup())) {
6712                 domain_name = c->opt_workgroup;
6713                 c->opt_target_workgroup = c->opt_workgroup;
6714         } else {
6715                 fstrcpy(pdc_name, global_myname());
6716                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6717                 c->opt_target_workgroup = domain_name;
6718         };
6719
6720         /* open \PIPE\lsarpc and open policy handle */
6721         nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6722         if (!NT_STATUS_IS_OK(nt_status)) {
6723                 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6724                           nt_errstr(nt_status)));
6725                 talloc_destroy(mem_ctx);
6726                 return -1;
6727         };
6728
6729         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6730                                              &pipe_hnd);
6731         if (!NT_STATUS_IS_OK(nt_status)) {
6732                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6733                         nt_errstr(nt_status) ));
6734                 cli_shutdown(cli);
6735                 talloc_destroy(mem_ctx);
6736                 return -1;
6737         };
6738
6739         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6740                                         &connect_hnd);
6741         if (NT_STATUS_IS_ERR(nt_status)) {
6742                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6743                         nt_errstr(nt_status)));
6744                 cli_shutdown(cli);
6745                 talloc_destroy(mem_ctx);
6746                 return -1;
6747         };
6748         
6749         /* query info level 5 to obtain sid of a domain being queried */
6750         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6751                                                &connect_hnd,
6752                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6753                                                &info,
6754                                                &result);
6755
6756         if (NT_STATUS_IS_ERR(nt_status)) {
6757                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6758                         nt_errstr(nt_status)));
6759                 cli_shutdown(cli);
6760                 talloc_destroy(mem_ctx);
6761                 return -1;
6762         }
6763         if (NT_STATUS_IS_ERR(result)) {
6764                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6765                         nt_errstr(result)));
6766                 cli_shutdown(cli);
6767                 talloc_destroy(mem_ctx);
6768                 return -1;
6769         }
6770
6771         queried_dom_sid = info->account_domain.sid;
6772
6773         /*
6774          * Keep calling LsaEnumTrustdom over opened pipe until
6775          * the end of enumeration is reached
6776          */
6777
6778         d_printf(_("Trusted domains list:\n\n"));
6779
6780         found_domain = false;
6781
6782         do {
6783                 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6784                                                     &connect_hnd,
6785                                                     &enum_ctx,
6786                                                     &dom_list,
6787                                                     (uint32_t)-1,
6788                                                     &result);
6789                 if (NT_STATUS_IS_ERR(nt_status)) {
6790                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6791                                 nt_errstr(nt_status)));
6792                         cli_shutdown(cli);
6793                         talloc_destroy(mem_ctx);
6794                         return -1;
6795                 };
6796                 if (NT_STATUS_IS_ERR(result)) {
6797                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6798                                 nt_errstr(result)));
6799                         cli_shutdown(cli);
6800                         talloc_destroy(mem_ctx);
6801                         return -1;
6802                 };
6803
6804
6805                 for (i = 0; i < dom_list.count; i++) {
6806                         print_trusted_domain(dom_list.domains[i].sid,
6807                                              dom_list.domains[i].name.string);
6808                         found_domain = true;
6809                 };
6810
6811
6812         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6813
6814         /*
6815          * in case of no trusted domains say something rather
6816          * than just display blank line
6817          */
6818         if (!found_domain) {
6819                 d_printf(_("none\n"));
6820         }
6821
6822         /* close this connection before doing next one */
6823         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6824         if (NT_STATUS_IS_ERR(nt_status)) {
6825                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6826                         nt_errstr(nt_status)));
6827                 cli_shutdown(cli);
6828                 talloc_destroy(mem_ctx);
6829                 return -1;
6830         };
6831         
6832         TALLOC_FREE(pipe_hnd);
6833
6834         /*
6835          * Listing trusting domains (stored in passdb backend, if local)
6836          */
6837         
6838         d_printf(_("\nTrusting domains list:\n\n"));
6839
6840         /*
6841          * Open \PIPE\samr and get needed policy handles
6842          */
6843         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
6844                                              &pipe_hnd);
6845         if (!NT_STATUS_IS_OK(nt_status)) {
6846                 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6847                 cli_shutdown(cli);
6848                 talloc_destroy(mem_ctx);
6849                 return -1;
6850         };
6851
6852         b = pipe_hnd->binding_handle;
6853
6854         /* SamrConnect2 */
6855         nt_status = dcerpc_samr_Connect2(b, mem_ctx,
6856                                          pipe_hnd->desthost,
6857                                          SAMR_ACCESS_LOOKUP_DOMAIN,
6858                                          &connect_hnd,
6859                                          &result);
6860         if (!NT_STATUS_IS_OK(nt_status)) {
6861                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6862                         nt_errstr(nt_status)));
6863                 cli_shutdown(cli);
6864                 talloc_destroy(mem_ctx);
6865                 return -1;
6866         };
6867         if (!NT_STATUS_IS_OK(result)) {
6868                 nt_status = result;
6869                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6870                         nt_errstr(result)));
6871                 cli_shutdown(cli);
6872                 talloc_destroy(mem_ctx);
6873                 return -1;
6874         };
6875
6876         /* SamrOpenDomain - we have to open domain policy handle in order to be
6877            able to enumerate accounts*/
6878         nt_status = dcerpc_samr_OpenDomain(b, mem_ctx,
6879                                            &connect_hnd,
6880                                            SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6881                                            queried_dom_sid,
6882                                            &domain_hnd,
6883                                            &result);
6884         if (!NT_STATUS_IS_OK(nt_status)) {
6885                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6886                         nt_errstr(nt_status)));
6887                 cli_shutdown(cli);
6888                 talloc_destroy(mem_ctx);
6889                 return -1;
6890         };
6891         if (!NT_STATUS_IS_OK(result)) {
6892                 nt_status = result;
6893                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6894                         nt_errstr(result)));
6895                 cli_shutdown(cli);
6896                 talloc_destroy(mem_ctx);
6897                 return -1;
6898         };
6899
6900         /*
6901          * perform actual enumeration
6902          */
6903
6904         found_domain = false;
6905
6906         enum_ctx = 0;   /* reset enumeration context from last enumeration */
6907         do {
6908
6909                 nt_status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
6910                                                         &domain_hnd,
6911                                                         &enum_ctx,
6912                                                         ACB_DOMTRUST,
6913                                                         &trusts,
6914                                                         0xffff,
6915                                                         &num_domains,
6916                                                         &result);
6917                 if (NT_STATUS_IS_ERR(nt_status)) {
6918                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6919                                 nt_errstr(nt_status)));
6920                         cli_shutdown(cli);
6921                         talloc_destroy(mem_ctx);
6922                         return -1;
6923                 };
6924                 if (NT_STATUS_IS_ERR(result)) {
6925                         nt_status = result;
6926                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6927                                 nt_errstr(result)));
6928                         cli_shutdown(cli);
6929                         talloc_destroy(mem_ctx);
6930                         return -1;
6931                 };
6932
6933                 for (i = 0; i < num_domains; i++) {
6934
6935                         char *str = CONST_DISCARD(char *, trusts->entries[i].name.string);
6936
6937                         found_domain = true;
6938
6939                         /*
6940                          * get each single domain's sid (do we _really_ need this ?):
6941                          *  1) connect to domain's pdc
6942                          *  2) query the pdc for domain's sid
6943                          */
6944
6945                         /* get rid of '$' tail */
6946                         ascii_dom_name_len = strlen(str);
6947                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6948                                 str[ascii_dom_name_len - 1] = '\0';
6949
6950                         /* set opt_* variables to remote domain */
6951                         strupper_m(str);
6952                         c->opt_workgroup = talloc_strdup(mem_ctx, str);
6953                         c->opt_target_workgroup = c->opt_workgroup;
6954
6955                         d_printf("%-20s", str);
6956
6957                         /* connect to remote domain controller */
6958                         nt_status = net_make_ipc_connection(c,
6959                                         NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6960                                         &remote_cli);
6961                         if (NT_STATUS_IS_OK(nt_status)) {
6962                                 /* query for domain's sid */
6963                                 if (run_rpc_command(
6964                                             c, remote_cli,
6965                                             &ndr_table_lsarpc.syntax_id, 0,
6966                                             rpc_query_domain_sid, argc,
6967                                             argv))
6968                                         d_printf(_("strange - couldn't get domain's sid\n"));
6969
6970                                 cli_shutdown(remote_cli);
6971
6972                         } else {
6973                                 d_fprintf(stderr, _("domain controller is not "
6974                                           "responding: %s\n"),
6975                                           nt_errstr(nt_status));
6976                                 d_printf(_("couldn't get domain's sid\n"));
6977                         }
6978                 }
6979
6980         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
6981
6982         if (!found_domain) {
6983                 d_printf("none\n");
6984         }
6985
6986         /* close opened samr and domain policy handles */
6987         nt_status = dcerpc_samr_Close(b, mem_ctx, &domain_hnd, &result);
6988         if (!NT_STATUS_IS_OK(nt_status)) {
6989                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
6990         };
6991
6992         nt_status = dcerpc_samr_Close(b, mem_ctx, &connect_hnd, &result);
6993         if (!NT_STATUS_IS_OK(nt_status)) {
6994                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
6995         };
6996
6997         /* close samr pipe and connection to IPC$ */
6998         cli_shutdown(cli);
6999
7000         talloc_destroy(mem_ctx);
7001         return 0;
7002 }
7003
7004 /**
7005  * Entrypoint for 'net rpc trustdom' code.
7006  *
7007  * @param argc Standard argc.
7008  * @param argv Standard argv without initial components.
7009  *
7010  * @return Integer status (0 means success).
7011  */
7012
7013 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
7014 {
7015         struct functable func[] = {
7016                 {
7017                         "add",
7018                         rpc_trustdom_add,
7019                         NET_TRANSPORT_RPC,
7020                         N_("Add trusting domain's account"),
7021                         N_("net rpc trustdom add\n"
7022                            "    Add trusting domain's account")
7023                 },
7024                 {
7025                         "del",
7026                         rpc_trustdom_del,
7027                         NET_TRANSPORT_RPC,
7028                         N_("Remove trusting domain's account"),
7029                         N_("net rpc trustdom del\n"
7030                            "    Remove trusting domain's account")
7031                 },
7032                 {
7033                         "establish",
7034                         rpc_trustdom_establish,
7035                         NET_TRANSPORT_RPC,
7036                         N_("Establish outgoing trust relationship"),
7037                         N_("net rpc trustdom establish\n"
7038                            "    Establish outgoing trust relationship")
7039                 },
7040                 {
7041                         "revoke",
7042                         rpc_trustdom_revoke,
7043                         NET_TRANSPORT_RPC,
7044                         N_("Revoke outgoing trust relationship"),
7045                         N_("net rpc trustdom revoke\n"
7046                            "    Revoke outgoing trust relationship")
7047                 },
7048                 {
7049                         "list",
7050                         rpc_trustdom_list,
7051                         NET_TRANSPORT_RPC,
7052                         N_("List in- and outgoing domain trusts"),
7053                         N_("net rpc trustdom list\n"
7054                            "    List in- and outgoing domain trusts")
7055                 },
7056                 {
7057                         "vampire",
7058                         rpc_trustdom_vampire,
7059                         NET_TRANSPORT_RPC,
7060                         N_("Vampire trusts from remote server"),
7061                         N_("net rpc trustdom vampire\n"
7062                            "    Vampire trusts from remote server")
7063                 },
7064                 {NULL, NULL, 0, NULL, NULL}
7065         };
7066
7067         return net_run_function(c, argc, argv, "net rpc trustdom", func);
7068 }
7069
7070 /**
7071  * Check if a server will take rpc commands
7072  * @param flags Type of server to connect to (PDC, DMB, localhost)
7073  *              if the host is not explicitly specified
7074  * @return  bool (true means rpc supported)
7075  */
7076 bool net_rpc_check(struct net_context *c, unsigned flags)
7077 {
7078         struct cli_state *cli;
7079         bool ret = false;
7080         struct sockaddr_storage server_ss;
7081         char *server_name = NULL;
7082         NTSTATUS status;
7083
7084         /* flags (i.e. server type) may depend on command */
7085         if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
7086                 return false;
7087
7088         if ((cli = cli_initialise()) == NULL) {
7089                 return false;
7090         }
7091
7092         status = cli_connect(cli, server_name, &server_ss);
7093         if (!NT_STATUS_IS_OK(status))
7094                 goto done;
7095         if (!attempt_netbios_session_request(&cli, global_myname(),
7096                                              server_name, &server_ss))
7097                 goto done;
7098         status = cli_negprot(cli);
7099         if (!NT_STATUS_IS_OK(status))
7100                 goto done;
7101         if (cli->protocol < PROTOCOL_NT1)
7102                 goto done;
7103
7104         ret = true;
7105  done:
7106         cli_shutdown(cli);
7107         return ret;
7108 }
7109
7110 /* dump sam database via samsync rpc calls */
7111 static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
7112         if (c->display_usage) {
7113                 d_printf(  "%s\n"
7114                            "net rpc samdump\n"
7115                            "    %s\n",
7116                          _("Usage:"),
7117                          _("Dump remote SAM database"));
7118                 return 0;
7119         }
7120
7121         return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id,
7122                                NET_FLAGS_ANONYMOUS,
7123                                rpc_samdump_internals, argc, argv);
7124 }
7125
7126 /* syncronise sam database via samsync rpc calls */
7127 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
7128 {
7129         struct functable func[] = {
7130                 {
7131                         "ldif",
7132                         rpc_vampire_ldif,
7133                         NET_TRANSPORT_RPC,
7134                         N_("Dump remote SAM database to ldif"),
7135                         N_("net rpc vampire ldif\n"
7136                            "    Dump remote SAM database to LDIF file or "
7137                            "stdout")
7138                 },
7139                 {
7140                         "keytab",
7141                         rpc_vampire_keytab,
7142                         NET_TRANSPORT_RPC,
7143                         N_("Dump remote SAM database to Kerberos Keytab"),
7144                         N_("net rpc vampire keytab\n"
7145                            "    Dump remote SAM database to Kerberos keytab "
7146                            "file")
7147                 },
7148                 {
7149                         "passdb",
7150                         rpc_vampire_passdb,
7151                         NET_TRANSPORT_RPC,
7152                         N_("Dump remote SAM database to passdb"),
7153                         N_("net rpc vampire passdb\n"
7154                            "    Dump remote SAM database to passdb")
7155                 },
7156
7157                 {NULL, NULL, 0, NULL, NULL}
7158         };
7159
7160         if (argc == 0) {
7161                 if (c->display_usage) {
7162                         d_printf(  "%s\n"
7163                                    "net rpc vampire\n"
7164                                    "    %s\n",
7165                                  _("Usage:"),
7166                                  _("Vampire remote SAM database"));
7167                         return 0;
7168                 }
7169
7170                 return rpc_vampire_passdb(c, argc, argv);
7171         }
7172
7173         return net_run_function(c, argc, argv, "net rpc vampire", func);
7174 }
7175
7176 /**
7177  * Migrate everything from a print server.
7178  *
7179  * @param c     A net_context structure.
7180  * @param argc  Standard main() style argc.
7181  * @param argv  Standard main() style argv. Initial components are already
7182  *              stripped.
7183  *
7184  * @return A shell status integer (0 for success).
7185  *
7186  * The order is important !
7187  * To successfully add drivers the print queues have to exist !
7188  * Applying ACLs should be the last step, because you're easily locked out.
7189  *
7190  **/
7191 static int rpc_printer_migrate_all(struct net_context *c, int argc,
7192                                    const char **argv)
7193 {
7194         int ret;
7195
7196         if (c->display_usage) {
7197                 d_printf(  "%s\n"
7198                            "net rpc printer migrate all\n"
7199                            "    %s\n",
7200                          _("Usage:"),
7201                          _("Migrate everything from a print server"));
7202                 return 0;
7203         }
7204
7205         if (!c->opt_host) {
7206                 d_printf(_("no server to migrate\n"));
7207                 return -1;
7208         }
7209
7210         ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7211                               rpc_printer_migrate_printers_internals, argc,
7212                               argv);
7213         if (ret)
7214                 return ret;
7215
7216         ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7217                               rpc_printer_migrate_drivers_internals, argc,
7218                               argv);
7219         if (ret)
7220                 return ret;
7221
7222         ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7223                               rpc_printer_migrate_forms_internals, argc, argv);
7224         if (ret)
7225                 return ret;
7226
7227         ret = run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7228                               rpc_printer_migrate_settings_internals, argc,
7229                               argv);
7230         if (ret)
7231                 return ret;
7232
7233         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7234                                rpc_printer_migrate_security_internals, argc,
7235                                argv);
7236
7237 }
7238
7239 /**
7240  * Migrate print drivers from a print server.
7241  *
7242  * @param c     A net_context structure.
7243  * @param argc  Standard main() style argc.
7244  * @param argv  Standard main() style argv. Initial components are already
7245  *              stripped.
7246  *
7247  * @return A shell status integer (0 for success).
7248  **/
7249 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
7250                                        const char **argv)
7251 {
7252         if (c->display_usage) {
7253                 d_printf(  "%s\n"
7254                            "net rpc printer migrate drivers\n"
7255                            "     %s\n",
7256                          _("Usage:"),
7257                          _("Migrate print-drivers from a print-server"));
7258                 return 0;
7259         }
7260
7261         if (!c->opt_host) {
7262                 d_printf(_("no server to migrate\n"));
7263                 return -1;
7264         }
7265
7266         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7267                                rpc_printer_migrate_drivers_internals,
7268                                argc, argv);
7269 }
7270
7271 /**
7272  * Migrate print-forms from a print-server.
7273  *
7274  * @param c     A net_context structure.
7275  * @param argc  Standard main() style argc.
7276  * @param argv  Standard main() style argv. Initial components are already
7277  *              stripped.
7278  *
7279  * @return A shell status integer (0 for success).
7280  **/
7281 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
7282                                      const char **argv)
7283 {
7284         if (c->display_usage) {
7285                 d_printf(  "%s\n"
7286                            "net rpc printer migrate forms\n"
7287                            "    %s\n",
7288                          _("Usage:"),
7289                          _("Migrate print-forms from a print-server"));
7290                 return 0;
7291         }
7292
7293         if (!c->opt_host) {
7294                 d_printf(_("no server to migrate\n"));
7295                 return -1;
7296         }
7297
7298         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7299                                rpc_printer_migrate_forms_internals,
7300                                argc, argv);
7301 }
7302
7303 /**
7304  * Migrate printers from a print-server.
7305  *
7306  * @param c     A net_context structure.
7307  * @param argc  Standard main() style argc.
7308  * @param argv  Standard main() style argv. Initial components are already
7309  *              stripped.
7310  *
7311  * @return A shell status integer (0 for success).
7312  **/
7313 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
7314                                         const char **argv)
7315 {
7316         if (c->display_usage) {
7317                 d_printf(  "%s\n"
7318                            "net rpc printer migrate printers\n"
7319                            "    %s\n",
7320                          _("Usage:"),
7321                          _("Migrate printers from a print-server"));
7322                 return 0;
7323         }
7324
7325         if (!c->opt_host) {
7326                 d_printf(_("no server to migrate\n"));
7327                 return -1;
7328         }
7329
7330         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7331                                rpc_printer_migrate_printers_internals,
7332                                argc, argv);
7333 }
7334
7335 /**
7336  * Migrate printer-ACLs from a print-server
7337  *
7338  * @param c     A net_context structure.
7339  * @param argc  Standard main() style argc.
7340  * @param argv  Standard main() style argv. Initial components are already
7341  *              stripped.
7342  *
7343  * @return A shell status integer (0 for success).
7344  **/
7345 static int rpc_printer_migrate_security(struct net_context *c, int argc,
7346                                         const char **argv)
7347 {
7348         if (c->display_usage) {
7349                 d_printf(  "%s\n"
7350                            "net rpc printer migrate security\n"
7351                            "    %s\n",
7352                          _("Usage:"),
7353                          _("Migrate printer-ACLs from a print-server"));
7354                 return 0;
7355         }
7356
7357         if (!c->opt_host) {
7358                 d_printf(_("no server to migrate\n"));
7359                 return -1;
7360         }
7361
7362         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7363                                rpc_printer_migrate_security_internals,
7364                                argc, argv);
7365 }
7366
7367 /**
7368  * Migrate printer-settings from a print-server.
7369  *
7370  * @param c     A net_context structure.
7371  * @param argc  Standard main() style argc.
7372  * @param argv  Standard main() style argv. Initial components are already
7373  *              stripped.
7374  *
7375  * @return A shell status integer (0 for success).
7376  **/
7377 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
7378                                         const char **argv)
7379 {
7380         if (c->display_usage) {
7381                 d_printf(  "%s\n"
7382                            "net rpc printer migrate settings\n"
7383                             "    %s\n",
7384                           _("Usage:"),
7385                           _("Migrate printer-settings from a "
7386                             "print-server"));
7387                 return 0;
7388         }
7389
7390         if (!c->opt_host) {
7391                 d_printf(_("no server to migrate\n"));
7392                 return -1;
7393         }
7394
7395         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7396                                rpc_printer_migrate_settings_internals,
7397                                argc, argv);
7398 }
7399
7400 /**
7401  * 'net rpc printer' entrypoint.
7402  *
7403  * @param c     A net_context structure.
7404  * @param argc  Standard main() style argc.
7405  * @param argv  Standard main() style argv. Initial components are already
7406  *              stripped.
7407  **/
7408
7409 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
7410 {
7411
7412         /* ouch: when addriver and setdriver are called from within
7413            rpc_printer_migrate_drivers_internals, the printer-queue already
7414            *has* to exist */
7415
7416         struct functable func[] = {
7417                 {
7418                         "all",
7419                         rpc_printer_migrate_all,
7420                         NET_TRANSPORT_RPC,
7421                         N_("Migrate all from remote to local print server"),
7422                         N_("net rpc printer migrate all\n"
7423                            "    Migrate all from remote to local print server")
7424                 },
7425                 {
7426                         "drivers",
7427                         rpc_printer_migrate_drivers,
7428                         NET_TRANSPORT_RPC,
7429                         N_("Migrate drivers to local server"),
7430                         N_("net rpc printer migrate drivers\n"
7431                            "    Migrate drivers to local server")
7432                 },
7433                 {
7434                         "forms",
7435                         rpc_printer_migrate_forms,
7436                         NET_TRANSPORT_RPC,
7437                         N_("Migrate froms to local server"),
7438                         N_("net rpc printer migrate forms\n"
7439                            "    Migrate froms to local server")
7440                 },
7441                 {
7442                         "printers",
7443                         rpc_printer_migrate_printers,
7444                         NET_TRANSPORT_RPC,
7445                         N_("Migrate printers to local server"),
7446                         N_("net rpc printer migrate printers\n"
7447                            "    Migrate printers to local server")
7448                 },
7449                 {
7450                         "security",
7451                         rpc_printer_migrate_security,
7452                         NET_TRANSPORT_RPC,
7453                         N_("Mirgate printer ACLs to local server"),
7454                         N_("net rpc printer migrate security\n"
7455                            "    Mirgate printer ACLs to local server")
7456                 },
7457                 {
7458                         "settings",
7459                         rpc_printer_migrate_settings,
7460                         NET_TRANSPORT_RPC,
7461                         N_("Migrate printer settings to local server"),
7462                         N_("net rpc printer migrate settings\n"
7463                            "    Migrate printer settings to local server")
7464                 },
7465                 {NULL, NULL, 0, NULL, NULL}
7466         };
7467
7468         return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7469 }
7470
7471
7472 /**
7473  * List printers on a remote RPC server.
7474  *
7475  * @param c     A net_context structure.
7476  * @param argc  Standard main() style argc.
7477  * @param argv  Standard main() style argv. Initial components are already
7478  *              stripped.
7479  *
7480  * @return A shell status integer (0 for success).
7481  **/
7482 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7483 {
7484         if (c->display_usage) {
7485                 d_printf(  "%s\n"
7486                            "net rpc printer list\n"
7487                            "    %s\n",
7488                          _("Usage:"),
7489                          _("List printers on a remote RPC server"));
7490                 return 0;
7491         }
7492
7493         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7494                                rpc_printer_list_internals,
7495                                argc, argv);
7496 }
7497
7498 /**
7499  * List printer-drivers on a remote RPC server.
7500  *
7501  * @param c     A net_context structure.
7502  * @param argc  Standard main() style argc.
7503  * @param argv  Standard main() style argv. Initial components are already
7504  *              stripped.
7505  *
7506  * @return A shell status integer (0 for success).
7507  **/
7508 static int rpc_printer_driver_list(struct net_context *c, int argc,
7509                                    const char **argv)
7510 {
7511         if (c->display_usage) {
7512                 d_printf(  "%s\n"
7513                            "net rpc printer driver\n"
7514                            "    %s\n",
7515                          _("Usage:"),
7516                          _("List printer-drivers on a remote RPC server"));
7517                 return 0;
7518         }
7519
7520         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7521                                rpc_printer_driver_list_internals,
7522                                argc, argv);
7523 }
7524
7525 /**
7526  * Publish printer in ADS via MSRPC.
7527  *
7528  * @param c     A net_context structure.
7529  * @param argc  Standard main() style argc.
7530  * @param argv  Standard main() style argv. Initial components are already
7531  *              stripped.
7532  *
7533  * @return A shell status integer (0 for success).
7534  **/
7535 static int rpc_printer_publish_publish(struct net_context *c, int argc,
7536                                        const char **argv)
7537 {
7538         if (c->display_usage) {
7539                 d_printf(  "%s\n"
7540                            "net rpc printer publish publish\n"
7541                            "     %s\n",
7542                          _("Usage:"),
7543                          _("Publish printer in ADS via MSRPC"));
7544                 return 0;
7545         }
7546
7547         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7548                                rpc_printer_publish_publish_internals,
7549                                argc, argv);
7550 }
7551
7552 /**
7553  * Update printer in ADS via MSRPC.
7554  *
7555  * @param c     A net_context structure.
7556  * @param argc  Standard main() style argc.
7557  * @param argv  Standard main() style argv. Initial components are already
7558  *              stripped.
7559  *
7560  * @return A shell status integer (0 for success).
7561  **/
7562 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7563 {
7564         if (c->display_usage) {
7565                 d_printf(  "%s\n"
7566                            "net rpc printer publish update\n"
7567                            "    %s\n",
7568                          _("Usage:"),
7569                          _("Update printer in ADS via MSRPC"));
7570                 return 0;
7571         }
7572
7573         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7574                                rpc_printer_publish_update_internals,
7575                                argc, argv);
7576 }
7577
7578 /**
7579  * UnPublish printer in ADS via MSRPC.
7580  *
7581  * @param c     A net_context structure.
7582  * @param argc  Standard main() style argc.
7583  * @param argv  Standard main() style argv. Initial components are already
7584  *              stripped.
7585  *
7586  * @return A shell status integer (0 for success).
7587  **/
7588 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7589                                          const char **argv)
7590 {
7591         if (c->display_usage) {
7592                 d_printf(  "%s\n"
7593                            "net rpc printer publish unpublish\n"
7594                            "    %s\n",
7595                          _("Usage:\n"),
7596                          _("UnPublish printer in ADS via MSRPC"));
7597                 return 0;
7598         }
7599
7600         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7601                                rpc_printer_publish_unpublish_internals,
7602                                argc, argv);
7603 }
7604
7605 /**
7606  * List published printers via MSRPC.
7607  *
7608  * @param c     A net_context structure.
7609  * @param argc  Standard main() style argc.
7610  * @param argv  Standard main() style argv. Initial components are already
7611  *              stripped.
7612  *
7613  * @return A shell status integer (0 for success).
7614  **/
7615 static int rpc_printer_publish_list(struct net_context *c, int argc,
7616                                     const char **argv)
7617 {
7618         if (c->display_usage) {
7619                 d_printf(  "%s\n"
7620                            "net rpc printer publish list\n"
7621                            "    %s\n",
7622                          _("Usage:"),
7623                          _("List published printers via MSRPC"));
7624                 return 0;
7625         }
7626
7627         return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7628                                rpc_printer_publish_list_internals,
7629                                argc, argv);
7630 }
7631
7632
7633 /**
7634  * Publish printer in ADS.
7635  *
7636  * @param c     A net_context structure.
7637  * @param argc  Standard main() style argc.
7638  * @param argv  Standard main() style argv. Initial components are already
7639  *              stripped.
7640  *
7641  * @return A shell status integer (0 for success).
7642  **/
7643 static int rpc_printer_publish(struct net_context *c, int argc,
7644                                const char **argv)
7645 {
7646
7647         struct functable func[] = {
7648                 {
7649                         "publish",
7650                         rpc_printer_publish_publish,
7651                         NET_TRANSPORT_RPC,
7652                         N_("Publish printer in AD"),
7653                         N_("net rpc printer publish publish\n"
7654                            "    Publish printer in AD")
7655                 },
7656                 {
7657                         "update",
7658                         rpc_printer_publish_update,
7659                         NET_TRANSPORT_RPC,
7660                         N_("Update printer in AD"),
7661                         N_("net rpc printer publish update\n"
7662                            "    Update printer in AD")
7663                 },
7664                 {
7665                         "unpublish",
7666                         rpc_printer_publish_unpublish,
7667                         NET_TRANSPORT_RPC,
7668                         N_("Unpublish printer"),
7669                         N_("net rpc printer publish unpublish\n"
7670                            "    Unpublish printer")
7671                 },
7672                 {
7673                         "list",
7674                         rpc_printer_publish_list,
7675                         NET_TRANSPORT_RPC,
7676                         N_("List published printers"),
7677                         N_("net rpc printer publish list\n"
7678                            "    List published printers")
7679                 },
7680                 {NULL, NULL, 0, NULL, NULL}
7681         };
7682
7683         if (argc == 0) {
7684                 if (c->display_usage) {
7685                         d_printf(_("Usage:\n"));
7686                         d_printf(_("net rpc printer publish\n"
7687                                    "    List published printers\n"
7688                                    "    Alias of net rpc printer publish "
7689                                    "list\n"));
7690                         net_display_usage_from_functable(func);
7691                         return 0;
7692                 }
7693                 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7694                                rpc_printer_publish_list_internals,
7695                                argc, argv);
7696         }
7697
7698         return net_run_function(c, argc, argv, "net rpc printer publish",func);
7699
7700 }
7701
7702
7703 /**
7704  * Display rpc printer help page.
7705  *
7706  * @param c     A net_context structure.
7707  * @param argc  Standard main() style argc.
7708  * @param argv  Standard main() style argv. Initial components are already
7709  *              stripped.
7710  **/
7711 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
7712 {
7713         d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
7714                    "\tlists all printers on print-server\n\n"));
7715         d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7716                    "\tlists all printer-drivers on print-server\n\n"));
7717         d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7718                    "\tpublishes printer settings in Active Directory\n"
7719                    "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
7720         d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7721                    "\n\tmigrates printers from remote to local server\n\n"));
7722         d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7723                    "\n\tmigrates printer-settings from remote to local server\n\n"));
7724         d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7725                    "\n\tmigrates printer-drivers from remote to local server\n\n"));
7726         d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7727                    "\n\tmigrates printer-forms from remote to local server\n\n"));
7728         d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7729                    "\n\tmigrates printer-ACLs from remote to local server\n\n"));
7730         d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7731                    "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7732                    "\tremote to local print-server\n\n"));
7733         net_common_methods_usage(c, argc, argv);
7734         net_common_flags_usage(c, argc, argv);
7735         d_printf(_(
7736          "\t-v or --verbose\t\t\tgive verbose output\n"
7737          "\t      --destination\t\tmigration target server (default: localhost)\n"));
7738
7739         return -1;
7740 }
7741
7742 /**
7743  * 'net rpc printer' entrypoint.
7744  *
7745  * @param c     A net_context structure.
7746  * @param argc  Standard main() style argc.
7747  * @param argv  Standard main() style argv. Initial components are already
7748  *              stripped.
7749  **/
7750 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
7751 {
7752         struct functable func[] = {
7753                 {
7754                         "list",
7755                         rpc_printer_list,
7756                         NET_TRANSPORT_RPC,
7757                         N_("List all printers on print server"),
7758                         N_("net rpc printer list\n"
7759                            "    List all printers on print server")
7760                 },
7761                 {
7762                         "migrate",
7763                         rpc_printer_migrate,
7764                         NET_TRANSPORT_RPC,
7765                         N_("Migrate printer to local server"),
7766                         N_("net rpc printer migrate\n"
7767                            "    Migrate printer to local server")
7768                 },
7769                 {
7770                         "driver",
7771                         rpc_printer_driver_list,
7772                         NET_TRANSPORT_RPC,
7773                         N_("List printer drivers"),
7774                         N_("net rpc printer driver\n"
7775                            "    List printer drivers")
7776                 },
7777                 {
7778                         "publish",
7779                         rpc_printer_publish,
7780                         NET_TRANSPORT_RPC,
7781                         N_("Publish printer in AD"),
7782                         N_("net rpc printer publish\n"
7783                            "    Publish printer in AD")
7784                 },
7785                 {NULL, NULL, 0, NULL, NULL}
7786         };
7787
7788         if (argc == 0) {
7789                 if (c->display_usage) {
7790                         d_printf(_("Usage:\n"));
7791                         d_printf(_("net rpc printer\n"
7792                                    "    List printers\n"));
7793                         net_display_usage_from_functable(func);
7794                         return 0;
7795                 }
7796                 return run_rpc_command(c, NULL, &ndr_table_spoolss.syntax_id, 0,
7797                                rpc_printer_list_internals,
7798                                argc, argv);
7799         }
7800
7801         return net_run_function(c, argc, argv, "net rpc printer", func);
7802 }
7803
7804 /**
7805  * 'net rpc' entrypoint.
7806  *
7807  * @param c     A net_context structure.
7808  * @param argc  Standard main() style argc.
7809  * @param argv  Standard main() style argv. Initial components are already
7810  *              stripped.
7811  **/
7812
7813 int net_rpc(struct net_context *c, int argc, const char **argv)
7814 {
7815         NET_API_STATUS status;
7816
7817         struct functable func[] = {
7818                 {
7819                         "audit",
7820                         net_rpc_audit,
7821                         NET_TRANSPORT_RPC,
7822                         N_("Modify global audit settings"),
7823                         N_("net rpc audit\n"
7824                            "    Modify global audit settings")
7825                 },
7826                 {
7827                         "info",
7828                         net_rpc_info,
7829                         NET_TRANSPORT_RPC,
7830                         N_("Show basic info about a domain"),
7831                         N_("net rpc info\n"
7832                            "    Show basic info about a domain")
7833                 },
7834                 {
7835                         "join",
7836                         net_rpc_join,
7837                         NET_TRANSPORT_RPC,
7838                         N_("Join a domain"),
7839                         N_("net rpc join\n"
7840                            "    Join a domain")
7841                 },
7842                 {
7843                         "oldjoin",
7844                         net_rpc_oldjoin,
7845                         NET_TRANSPORT_RPC,
7846                         N_("Join a domain created in server manager"),
7847                         N_("net rpc oldjoin\n"
7848                            "    Join a domain created in server manager")
7849                 },
7850                 {
7851                         "testjoin",
7852                         net_rpc_testjoin,
7853                         NET_TRANSPORT_RPC,
7854                         N_("Test that a join is valid"),
7855                         N_("net rpc testjoin\n"
7856                            "    Test that a join is valid")
7857                 },
7858                 {
7859                         "user",
7860                         net_rpc_user,
7861                         NET_TRANSPORT_RPC,
7862                         N_("List/modify users"),
7863                         N_("net rpc user\n"
7864                            "    List/modify users")
7865                 },
7866                 {
7867                         "password",
7868                         rpc_user_password,
7869                         NET_TRANSPORT_RPC,
7870                         N_("Change a user password"),
7871                         N_("net rpc password\n"
7872                            "    Change a user password\n"
7873                            "    Alias for net rpc user password")
7874                 },
7875                 {
7876                         "group",
7877                         net_rpc_group,
7878                         NET_TRANSPORT_RPC,
7879                         N_("List/modify groups"),
7880                         N_("net rpc group\n"
7881                            "    List/modify groups")
7882                 },
7883                 {
7884                         "share",
7885                         net_rpc_share,
7886                         NET_TRANSPORT_RPC,
7887                         N_("List/modify shares"),
7888                         N_("net rpc share\n"
7889                            "    List/modify shares")
7890                 },
7891                 {
7892                         "file",
7893                         net_rpc_file,
7894                         NET_TRANSPORT_RPC,
7895                         N_("List open files"),
7896                         N_("net rpc file\n"
7897                            "    List open files")
7898                 },
7899                 {
7900                         "printer",
7901                         net_rpc_printer,
7902                         NET_TRANSPORT_RPC,
7903                         N_("List/modify printers"),
7904                         N_("net rpc printer\n"
7905                            "    List/modify printers")
7906                 },
7907                 {
7908                         "changetrustpw",
7909                         net_rpc_changetrustpw,
7910                         NET_TRANSPORT_RPC,
7911                         N_("Change trust account password"),
7912                         N_("net rpc changetrustpw\n"
7913                            "    Change trust account password")
7914                 },
7915                 {
7916                         "trustdom",
7917                         rpc_trustdom,
7918                         NET_TRANSPORT_RPC,
7919                         N_("Modify domain trusts"),
7920                         N_("net rpc trustdom\n"
7921                            "    Modify domain trusts")
7922                 },
7923                 {
7924                         "abortshutdown",
7925                         rpc_shutdown_abort,
7926                         NET_TRANSPORT_RPC,
7927                         N_("Abort a remote shutdown"),
7928                         N_("net rpc abortshutdown\n"
7929                            "    Abort a remote shutdown")
7930                 },
7931                 {
7932                         "shutdown",
7933                         rpc_shutdown,
7934                         NET_TRANSPORT_RPC,
7935                         N_("Shutdown a remote server"),
7936                         N_("net rpc shutdown\n"
7937                            "    Shutdown a remote server")
7938                 },
7939                 {
7940                         "samdump",
7941                         rpc_samdump,
7942                         NET_TRANSPORT_RPC,
7943                         N_("Dump SAM data of remote NT PDC"),
7944                         N_("net rpc samdump\n"
7945                            "    Dump SAM data of remote NT PDC")
7946                 },
7947                 {
7948                         "vampire",
7949                         rpc_vampire,
7950                         NET_TRANSPORT_RPC,
7951                         N_("Sync a remote NT PDC's data into local passdb"),
7952                         N_("net rpc vampire\n"
7953                            "    Sync a remote NT PDC's data into local passdb")
7954                 },
7955                 {
7956                         "getsid",
7957                         net_rpc_getsid,
7958                         NET_TRANSPORT_RPC,
7959                         N_("Fetch the domain sid into local secrets.tdb"),
7960                         N_("net rpc getsid\n"
7961                            "    Fetch the domain sid into local secrets.tdb")
7962                 },
7963                 {
7964                         "rights",
7965                         net_rpc_rights,
7966                         NET_TRANSPORT_RPC,
7967                         N_("Manage privileges assigned to SID"),
7968                         N_("net rpc rights\n"
7969                            "    Manage privileges assigned to SID")
7970                 },
7971                 {
7972                         "service",
7973                         net_rpc_service,
7974                         NET_TRANSPORT_RPC,
7975                         N_("Start/stop/query remote services"),
7976                         N_("net rpc service\n"
7977                            "    Start/stop/query remote services")
7978                 },
7979                 {
7980                         "registry",
7981                         net_rpc_registry,
7982                         NET_TRANSPORT_RPC,
7983                         N_("Manage registry hives"),
7984                         N_("net rpc registry\n"
7985                            "    Manage registry hives")
7986                 },
7987                 {
7988                         "shell",
7989                         net_rpc_shell,
7990                         NET_TRANSPORT_RPC,
7991                         N_("Open interactive shell on remote server"),
7992                         N_("net rpc shell\n"
7993                            "    Open interactive shell on remote server")
7994                 },
7995                 {NULL, NULL, 0, NULL, NULL}
7996         };
7997
7998         status = libnetapi_net_init(&c->netapi_ctx);
7999         if (status != 0) {
8000                 return -1;
8001         }
8002         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
8003         libnetapi_set_password(c->netapi_ctx, c->opt_password);
8004         if (c->opt_kerberos) {
8005                 libnetapi_set_use_kerberos(c->netapi_ctx);
8006         }
8007         if (c->opt_ccache) {
8008                 libnetapi_set_use_ccache(c->netapi_ctx);
8009         }
8010
8011         return net_run_function(c, argc, argv, "net rpc", func);
8012 }