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