ad3f448c5eb3f7bee0245ee57315fcb04fb7c802
[samba.git] / source3 / utils / net_rpc.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
5    Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
6    Copyright (C) 2004,2008 Guenther Deschner (gd@samba.org)
7    Copyright (C) 2005 Jeremy Allison (jra@samba.org)
8    Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org)
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
23 #include "includes.h"
24 #include "utils/net.h"
25 #include "rpc_client/cli_pipe.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/cli_samr.h"
29 #include "rpc_client/init_samr.h"
30 #include "../librpc/gen_ndr/ndr_lsa_c.h"
31 #include "rpc_client/cli_lsarpc.h"
32 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
33 #include "../librpc/gen_ndr/ndr_srvsvc_c.h"
34 #include "../librpc/gen_ndr/ndr_spoolss.h"
35 #include "../librpc/gen_ndr/ndr_initshutdown_c.h"
36 #include "../librpc/gen_ndr/ndr_winreg_c.h"
37 #include "secrets.h"
38 #include "lib/netapi/netapi.h"
39 #include "lib/netapi/netapi_net.h"
40 #include "rpc_client/init_lsa.h"
41 #include "../libcli/security/security.h"
42 #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,
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                 if (strlcpy(new_mask, dir, sizeof(new_mask)) >= sizeof(new_mask)) {
3769                         return NT_STATUS_NO_MEMORY;
3770                 }
3771                 if (strlcat(new_mask, "\\*", sizeof(new_mask)) >= sizeof(new_mask)) {
3772                         return NT_STATUS_NO_MEMORY;
3773                 }
3774
3775                 old_dir = local_state->cwd;
3776                 local_state->cwd = dir;
3777                 nt_status = sync_files(local_state, new_mask);
3778                 if (!NT_STATUS_IS_OK(nt_status)) {
3779                         printf(_("could not handle files\n"));
3780                 }
3781                 local_state->cwd = old_dir;
3782
3783                 return nt_status;
3784         }
3785
3786
3787         /* FILE */
3788         fstrcpy(filename, local_state->cwd);
3789         fstrcat(filename, "\\");
3790         fstrcat(filename, f->name);
3791
3792         DEBUG(3,("got file: %s\n", filename));
3793
3794         switch (net_mode_share)
3795         {
3796         case NET_MODE_SHARE_MIGRATE:
3797                 nt_status = net_copy_file(c, local_state->mem_ctx,
3798                                           local_state->cli_share_src,
3799                                           local_state->cli_share_dst,
3800                                           filename, filename,
3801                                           c->opt_acls? true : false,
3802                                           c->opt_attrs? true : false,
3803                                           c->opt_timestamps? true: false,
3804                                           true);
3805                 break;
3806         default:
3807                 d_fprintf(stderr, _("Unsupported file mode %d\n"),
3808                           net_mode_share);
3809                 return NT_STATUS_INTERNAL_ERROR;
3810         }
3811
3812         if (!NT_STATUS_IS_OK(nt_status))
3813                 printf(_("could not handle file %s: %s\n"),
3814                         filename, nt_errstr(nt_status));
3815         return nt_status;
3816 }
3817
3818 /**
3819  * sync files, can be called recursivly to list files
3820  * and then call copy_fn for each file
3821  *
3822  * @param cp_clistate   pointer to the copy_clistate we work with
3823  * @param mask          the current search mask
3824  *
3825  * @return              Boolean result
3826  **/
3827 static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask)
3828 {
3829         struct cli_state *targetcli;
3830         char *targetpath = NULL;
3831         NTSTATUS status;
3832
3833         DEBUG(3,("calling cli_list with mask: %s\n", mask));
3834
3835         status = cli_resolve_path(talloc_tos(), "", NULL,
3836                                   cp_clistate->cli_share_src,
3837                                   mask, &targetcli, &targetpath);
3838         if (!NT_STATUS_IS_OK(status)) {
3839                 d_fprintf(stderr, _("cli_resolve_path %s failed with error: "
3840                                     "%s\n"),
3841                         mask, nt_errstr(status));
3842                 return status;
3843         }
3844
3845         status = cli_list(targetcli, targetpath, cp_clistate->attribute,
3846                           copy_fn, cp_clistate);
3847         if (!NT_STATUS_IS_OK(status)) {
3848                 d_fprintf(stderr, _("listing %s failed with error: %s\n"),
3849                           mask, nt_errstr(status));
3850         }
3851
3852         return status;
3853 }
3854
3855
3856 /**
3857  * Set the top level directory permissions before we do any further copies.
3858  * Should set up ACL inheritance.
3859  **/
3860
3861 bool copy_top_level_perms(struct net_context *c,
3862                                 struct copy_clistate *cp_clistate,
3863                                 const char *sharename)
3864 {
3865         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3866
3867         switch (net_mode_share) {
3868         case NET_MODE_SHARE_MIGRATE:
3869                 DEBUG(3,("calling net_copy_fileattr for '.' directory in share %s\n", sharename));
3870                 nt_status = net_copy_fileattr(c,
3871                                                 cp_clistate->mem_ctx,
3872                                                 cp_clistate->cli_share_src,
3873                                                 cp_clistate->cli_share_dst,
3874                                                 "\\", "\\",
3875                                                 c->opt_acls? true : false,
3876                                                 c->opt_attrs? true : false,
3877                                                 c->opt_timestamps? true: false,
3878                                                 false);
3879                 break;
3880         default:
3881                 d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share);
3882                 break;
3883         }
3884
3885         if (!NT_STATUS_IS_OK(nt_status))  {
3886                 printf(_("Could handle directory attributes for top level "
3887                          "directory of share %s. Error %s\n"),
3888                         sharename, nt_errstr(nt_status));
3889                 return false;
3890         }
3891
3892         return true;
3893 }
3894
3895 /**
3896  * Sync all files inside a remote share to another share (over smb).
3897  *
3898  * All parameters are provided by the run_rpc_command function, except for
3899  * argc, argv which are passed through.
3900  *
3901  * @param domain_sid The domain sid acquired from the remote server.
3902  * @param cli A cli_state connected to the server.
3903  * @param mem_ctx Talloc context, destroyed on completion of the function.
3904  * @param argc  Standard main() style argc.
3905  * @param argv  Standard main() style argv. Initial components are already
3906  *              stripped.
3907  *
3908  * @return Normal NTSTATUS return.
3909  **/
3910
3911 static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
3912                                                 const struct dom_sid *domain_sid,
3913                                                 const char *domain_name,
3914                                                 struct cli_state *cli,
3915                                                 struct rpc_pipe_client *pipe_hnd,
3916                                                 TALLOC_CTX *mem_ctx,
3917                                                 int argc,
3918                                                 const char **argv)
3919 {
3920         WERROR result;
3921         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
3922         struct srvsvc_NetShareInfoCtr ctr_src;
3923         uint32 i;
3924         uint32 level = 502;
3925         struct copy_clistate cp_clistate;
3926         bool got_src_share = false;
3927         bool got_dst_share = false;
3928         const char *mask = "\\*";
3929         char *dst = NULL;
3930
3931         dst = SMB_STRDUP(c->opt_destination?c->opt_destination:"127.0.0.1");
3932         if (dst == NULL) {
3933                 nt_status = NT_STATUS_NO_MEMORY;
3934                 goto done;
3935         }
3936
3937         result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
3938                                 &ctr_src);
3939
3940         if (!W_ERROR_IS_OK(result))
3941                 goto done;
3942
3943         for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
3944
3945                 struct srvsvc_NetShareInfo502 info502 =
3946                         ctr_src.ctr.ctr502->array[i];
3947
3948                 if (!check_share_sanity(c, cli, info502.name, info502.type))
3949                         continue;
3950
3951                 /* one might not want to mirror whole discs :) */
3952                 if (strequal(info502.name, "print$") || info502.name[1] == '$') {
3953                         d_printf(_("skipping   [%s]: builtin/hidden share\n"),
3954                                  info502.name);
3955                         continue;
3956                 }
3957
3958                 switch (net_mode_share)
3959                 {
3960                 case NET_MODE_SHARE_MIGRATE:
3961                         printf("syncing");
3962                         break;
3963                 default:
3964                         d_fprintf(stderr, _("Unsupported mode %d\n"),
3965                                   net_mode_share);
3966                         break;
3967                 }
3968                 printf(_("    [%s] files and directories %s ACLs, %s DOS "
3969                          "Attributes %s\n"),
3970                         info502.name,
3971                         c->opt_acls ? _("including") : _("without"),
3972                         c->opt_attrs ? _("including") : _("without"),
3973                         c->opt_timestamps ? _("(preserving timestamps)") : "");
3974
3975                 cp_clistate.mem_ctx = mem_ctx;
3976                 cp_clistate.cli_share_src = NULL;
3977                 cp_clistate.cli_share_dst = NULL;
3978                 cp_clistate.cwd = NULL;
3979                 cp_clistate.attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY;
3980                 cp_clistate.c = c;
3981
3982                 /* open share source */
3983                 nt_status = connect_to_service(c, &cp_clistate.cli_share_src,
3984                                                cli_state_remote_sockaddr(cli),
3985                                                cli_state_remote_name(cli),
3986                                                info502.name, "A:");
3987                 if (!NT_STATUS_IS_OK(nt_status))
3988                         goto done;
3989
3990                 got_src_share = true;
3991
3992                 if (net_mode_share == NET_MODE_SHARE_MIGRATE) {
3993                         /* open share destination */
3994                         nt_status = connect_to_service(c, &cp_clistate.cli_share_dst,
3995                                                        NULL, dst, info502.name, "A:");
3996                         if (!NT_STATUS_IS_OK(nt_status))
3997                                 goto done;
3998
3999                         got_dst_share = true;
4000                 }
4001
4002                 if (!copy_top_level_perms(c, &cp_clistate, info502.name)) {
4003                         d_fprintf(stderr, _("Could not handle the top level "
4004                                             "directory permissions for the "
4005                                             "share: %s\n"), info502.name);
4006                         nt_status = NT_STATUS_UNSUCCESSFUL;
4007                         goto done;
4008                 }
4009
4010                 nt_status = sync_files(&cp_clistate, mask);
4011                 if (!NT_STATUS_IS_OK(nt_status)) {
4012                         d_fprintf(stderr, _("could not handle files for share: "
4013                                             "%s\n"), info502.name);
4014                         goto done;
4015                 }
4016         }
4017
4018         nt_status = NT_STATUS_OK;
4019
4020 done:
4021
4022         if (got_src_share)
4023                 cli_shutdown(cp_clistate.cli_share_src);
4024
4025         if (got_dst_share)
4026                 cli_shutdown(cp_clistate.cli_share_dst);
4027
4028         SAFE_FREE(dst);
4029         return nt_status;
4030
4031 }
4032
4033 static int rpc_share_migrate_files(struct net_context *c, int argc, const char **argv)
4034 {
4035         if (c->display_usage) {
4036                 d_printf(  "%s\n"
4037                            "net share migrate files\n"
4038                            "    %s\n",
4039                          _("Usage:"),
4040                          _("Migrate files to local server"));
4041                 return 0;
4042         }
4043
4044         if (!c->opt_host) {
4045                 d_printf(_("no server to migrate\n"));
4046                 return -1;
4047         }
4048
4049         return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4050                                rpc_share_migrate_files_internals,
4051                                argc, argv);
4052 }
4053
4054 /**
4055  * Migrate share-ACLs from a remote RPC server to the local RPC server.
4056  *
4057  * All parameters are provided by the run_rpc_command function, except for
4058  * argc, argv which are passed through.
4059  *
4060  * @param domain_sid The domain sid acquired from the remote server.
4061  * @param cli A cli_state connected to the server.
4062  * @param mem_ctx Talloc context, destroyed on completion of the function.
4063  * @param argc  Standard main() style argc.
4064  * @param argv  Standard main() style argv. Initial components are already
4065  *              stripped.
4066  *
4067  * @return Normal NTSTATUS return.
4068  **/
4069
4070 static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c,
4071                                                 const struct dom_sid *domain_sid,
4072                                                 const char *domain_name,
4073                                                 struct cli_state *cli,
4074                                                 struct rpc_pipe_client *pipe_hnd,
4075                                                 TALLOC_CTX *mem_ctx,
4076                                                 int argc,
4077                                                 const char **argv)
4078 {
4079         WERROR result;
4080         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
4081         struct srvsvc_NetShareInfoCtr ctr_src;
4082         union srvsvc_NetShareInfo info;
4083         uint32 i;
4084         struct rpc_pipe_client *srvsvc_pipe = NULL;
4085         struct cli_state *cli_dst = NULL;
4086         uint32 level = 502; /* includes secdesc */
4087         uint32_t parm_error = 0;
4088         struct dcerpc_binding_handle *b;
4089
4090         result = get_share_info(c, pipe_hnd, mem_ctx, level, argc, argv,
4091                                 &ctr_src);
4092
4093         if (!W_ERROR_IS_OK(result))
4094                 goto done;
4095
4096         /* connect destination PI_SRVSVC */
4097         nt_status = connect_dst_pipe(c, &cli_dst, &srvsvc_pipe,
4098                                      &ndr_table_srvsvc.syntax_id);
4099         if (!NT_STATUS_IS_OK(nt_status))
4100                 return nt_status;
4101
4102         b = srvsvc_pipe->binding_handle;
4103
4104         for (i = 0; i < ctr_src.ctr.ctr502->count; i++) {
4105
4106                 struct srvsvc_NetShareInfo502 info502 =
4107                         ctr_src.ctr.ctr502->array[i];
4108
4109                 /* reset error-code */
4110                 nt_status = NT_STATUS_UNSUCCESSFUL;
4111
4112                 if (!check_share_sanity(c, cli, info502.name, info502.type))
4113                         continue;
4114
4115                 printf(_("migrating: [%s], path: %s, comment: %s, including "
4116                          "share-ACLs\n"),
4117                         info502.name, info502.path, info502.comment);
4118
4119                 if (c->opt_verbose)
4120                         display_sec_desc(info502.sd_buf.sd);
4121
4122                 /* FIXME: shouldn't we be able to just set the security descriptor ? */
4123                 info.info502 = &info502;
4124
4125                 /* finally modify the share on the dst server */
4126                 nt_status = dcerpc_srvsvc_NetShareSetInfo(b, mem_ctx,
4127                                                           srvsvc_pipe->desthost,
4128                                                           info502.name,
4129                                                           level,
4130                                                           &info,
4131                                                           &parm_error,
4132                                                           &result);
4133                 if (!NT_STATUS_IS_OK(nt_status)) {
4134                         printf(_("cannot set share-acl: %s\n"),
4135                                nt_errstr(nt_status));
4136                         goto done;
4137                 }
4138                 if (!W_ERROR_IS_OK(result)) {
4139                         nt_status = werror_to_ntstatus(result);
4140                         printf(_("cannot set share-acl: %s\n"),
4141                                win_errstr(result));
4142                         goto done;
4143                 }
4144
4145         }
4146
4147         nt_status = NT_STATUS_OK;
4148
4149 done:
4150         if (cli_dst) {
4151                 cli_shutdown(cli_dst);
4152         }
4153
4154         return nt_status;
4155
4156 }
4157
4158 /**
4159  * Migrate share-acls from a RPC server to another.
4160  *
4161  * @param argc  Standard main() style argc.
4162  * @param argv  Standard main() style argv. Initial components are already
4163  *              stripped.
4164  *
4165  * @return A shell status integer (0 for success).
4166  **/
4167 static int rpc_share_migrate_security(struct net_context *c, int argc,
4168                                       const char **argv)
4169 {
4170         if (c->display_usage) {
4171                 d_printf(  "%s\n"
4172                            "net rpc share migrate security\n"
4173                            "    %s\n",
4174                          _("Usage:"),
4175                          _("Migrate share-acls to local server"));
4176                 return 0;
4177         }
4178
4179         if (!c->opt_host) {
4180                 d_printf(_("no server to migrate\n"));
4181                 return -1;
4182         }
4183
4184         return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4185                                rpc_share_migrate_security_internals,
4186                                argc, argv);
4187 }
4188
4189 /**
4190  * Migrate shares (including share-definitions, share-acls and files with acls/attrs)
4191  * from one server to another.
4192  *
4193  * @param argc  Standard main() style argc.
4194  * @param argv  Standard main() style argv. Initial components are already
4195  *              stripped.
4196  *
4197  * @return A shell status integer (0 for success).
4198  *
4199  **/
4200 static int rpc_share_migrate_all(struct net_context *c, int argc,
4201                                  const char **argv)
4202 {
4203         int ret;
4204
4205         if (c->display_usage) {
4206                 d_printf(  "%s\n"
4207                            "net rpc share migrate all\n"
4208                            "    %s\n",
4209                          _("Usage:"),
4210                          _("Migrates shares including all share settings"));
4211                 return 0;
4212         }
4213
4214         if (!c->opt_host) {
4215                 d_printf(_("no server to migrate\n"));
4216                 return -1;
4217         }
4218
4219         /* order is important. we don't want to be locked out by the share-acl
4220          * before copying files - gd */
4221
4222         ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4223                               rpc_share_migrate_shares_internals, argc, argv);
4224         if (ret)
4225                 return ret;
4226
4227         ret = run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4228                               rpc_share_migrate_files_internals, argc, argv);
4229         if (ret)
4230                 return ret;
4231
4232         return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
4233                                rpc_share_migrate_security_internals, argc,
4234                                argv);
4235 }
4236
4237
4238 /**
4239  * 'net rpc share migrate' entrypoint.
4240  * @param argc  Standard main() style argc.
4241  * @param argv  Standard main() style argv. Initial components are already
4242  *              stripped.
4243  **/
4244 static int rpc_share_migrate(struct net_context *c, int argc, const char **argv)
4245 {
4246
4247         struct functable func[] = {
4248                 {
4249                         "all",
4250                         rpc_share_migrate_all,
4251                         NET_TRANSPORT_RPC,
4252                         N_("Migrate shares from remote to local server"),
4253                         N_("net rpc share migrate all\n"
4254                            "    Migrate shares from remote to local server")
4255                 },
4256                 {
4257                         "files",
4258                         rpc_share_migrate_files,
4259                         NET_TRANSPORT_RPC,
4260                         N_("Migrate files from remote to local server"),
4261                         N_("net rpc share migrate files\n"
4262                            "    Migrate files from remote to local server")
4263                 },
4264                 {
4265                         "security",
4266                         rpc_share_migrate_security,
4267                         NET_TRANSPORT_RPC,
4268                         N_("Migrate share-ACLs from remote to local server"),
4269                         N_("net rpc share migrate security\n"
4270                            "    Migrate share-ACLs from remote to local server")
4271                 },
4272                 {
4273                         "shares",
4274                         rpc_share_migrate_shares,
4275                         NET_TRANSPORT_RPC,
4276                         N_("Migrate shares from remote to local server"),
4277                         N_("net rpc share migrate shares\n"
4278                            "    Migrate shares from remote to local server")
4279                 },
4280                 {NULL, NULL, 0, NULL, NULL}
4281         };
4282
4283         net_mode_share = NET_MODE_SHARE_MIGRATE;
4284
4285         return net_run_function(c, argc, argv, "net rpc share migrate", func);
4286 }
4287
4288 struct full_alias {
4289         struct dom_sid sid;
4290         uint32 num_members;
4291         struct dom_sid *members;
4292 };
4293
4294 static int num_server_aliases;
4295 static struct full_alias *server_aliases;
4296
4297 /*
4298  * Add an alias to the static list.
4299  */
4300 static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
4301 {
4302         if (server_aliases == NULL)
4303                 server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
4304
4305         server_aliases[num_server_aliases] = *alias;
4306         num_server_aliases += 1;
4307 }
4308
4309 /*
4310  * For a specific domain on the server, fetch all the aliases
4311  * and their members. Add all of them to the server_aliases.
4312  */
4313
4314 static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
4315                                         TALLOC_CTX *mem_ctx,
4316                                         struct policy_handle *connect_pol,
4317                                         const struct dom_sid *domain_sid)
4318 {
4319         uint32 start_idx, max_entries, num_entries, i;
4320         struct samr_SamArray *groups = NULL;
4321         NTSTATUS result, status;
4322         struct policy_handle domain_pol;
4323         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4324
4325         /* Get domain policy handle */
4326
4327         status = dcerpc_samr_OpenDomain(b, mem_ctx,
4328                                         connect_pol,
4329                                         MAXIMUM_ALLOWED_ACCESS,
4330                                         discard_const_p(struct dom_sid2, domain_sid),
4331                                         &domain_pol,
4332                                         &result);
4333         if (!NT_STATUS_IS_OK(status)) {
4334                 return status;
4335         }
4336         if (!NT_STATUS_IS_OK(result)) {
4337                 return result;
4338         }
4339
4340         start_idx = 0;
4341         max_entries = 250;
4342
4343         do {
4344                 status = dcerpc_samr_EnumDomainAliases(b, mem_ctx,
4345                                                        &domain_pol,
4346                                                        &start_idx,
4347                                                        &groups,
4348                                                        max_entries,
4349                                                        &num_entries,
4350                                                        &result);
4351                 if (!NT_STATUS_IS_OK(status)) {
4352                         goto done;
4353                 }
4354                 for (i = 0; i < num_entries; i++) {
4355
4356                         struct policy_handle alias_pol;
4357                         struct full_alias alias;
4358                         struct lsa_SidArray sid_array;
4359                         int j;
4360                         NTSTATUS _result;
4361
4362                         status = dcerpc_samr_OpenAlias(b, mem_ctx,
4363                                                        &domain_pol,
4364                                                        MAXIMUM_ALLOWED_ACCESS,
4365                                                        groups->entries[i].idx,
4366                                                        &alias_pol,
4367                                                        &_result);
4368                         if (!NT_STATUS_IS_OK(status)) {
4369                                 goto done;
4370                         }
4371                         if (!NT_STATUS_IS_OK(_result)) {
4372                                 status = _result;
4373                                 goto done;
4374                         }
4375
4376                         status = dcerpc_samr_GetMembersInAlias(b, mem_ctx,
4377                                                                &alias_pol,
4378                                                                &sid_array,
4379                                                                &_result);
4380                         if (!NT_STATUS_IS_OK(status)) {
4381                                 goto done;
4382                         }
4383                         if (!NT_STATUS_IS_OK(_result)) {
4384                                 status = _result;
4385                                 goto done;
4386                         }
4387
4388                         alias.num_members = sid_array.num_sids;
4389
4390                         status = dcerpc_samr_Close(b, mem_ctx, &alias_pol, &_result);
4391                         if (!NT_STATUS_IS_OK(status)) {
4392                                 goto done;
4393                         }
4394                         if (!NT_STATUS_IS_OK(_result)) {
4395                                 status = _result;
4396                                 goto done;
4397                         }
4398
4399                         alias.members = NULL;
4400
4401                         if (alias.num_members > 0) {
4402                                 alias.members = SMB_MALLOC_ARRAY(struct dom_sid, alias.num_members);
4403
4404                                 for (j = 0; j < alias.num_members; j++)
4405                                         sid_copy(&alias.members[j],
4406                                                  sid_array.sids[j].sid);
4407                         }
4408
4409                         sid_compose(&alias.sid, domain_sid,
4410                                     groups->entries[i].idx);
4411
4412                         push_alias(mem_ctx, &alias);
4413                 }
4414         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
4415
4416         status = NT_STATUS_OK;
4417
4418  done:
4419         dcerpc_samr_Close(b, mem_ctx, &domain_pol, &result);
4420
4421         return status;
4422 }
4423
4424 /*
4425  * Dump server_aliases as names for debugging purposes.
4426  */
4427
4428 static NTSTATUS rpc_aliaslist_dump(struct net_context *c,
4429                                 const struct dom_sid *domain_sid,
4430                                 const char *domain_name,
4431                                 struct cli_state *cli,
4432                                 struct rpc_pipe_client *pipe_hnd,
4433                                 TALLOC_CTX *mem_ctx,
4434                                 int argc,
4435                                 const char **argv)
4436 {
4437         int i;
4438         NTSTATUS result;
4439         struct policy_handle lsa_pol;
4440         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4441
4442         result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
4443                                      SEC_FLAG_MAXIMUM_ALLOWED,
4444                                      &lsa_pol);
4445         if (!NT_STATUS_IS_OK(result))
4446                 return result;
4447
4448         for (i=0; i<num_server_aliases; i++) {
4449                 char **names;
4450                 char **domains;
4451                 enum lsa_SidType *types;
4452                 int j;
4453
4454                 struct full_alias *alias = &server_aliases[i];
4455
4456                 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
4457                                              &alias->sid,
4458                                              &domains, &names, &types);
4459                 if (!NT_STATUS_IS_OK(result))
4460                         continue;
4461
4462                 DEBUG(1, ("%s\\%s %d: ", domains[0], names[0], types[0]));
4463
4464                 if (alias->num_members == 0) {
4465                         DEBUG(1, ("\n"));
4466                         continue;
4467                 }
4468
4469                 result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
4470                                              alias->num_members,
4471                                              alias->members,
4472                                              &domains, &names, &types);
4473
4474                 if (!NT_STATUS_IS_OK(result) &&
4475                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
4476                         continue;
4477
4478                 for (j=0; j<alias->num_members; j++)
4479                         DEBUG(1, ("%s\\%s (%d); ",
4480                                   domains[j] ? domains[j] : "*unknown*",
4481                                   names[j] ? names[j] : "*unknown*",types[j]));
4482                 DEBUG(1, ("\n"));
4483         }
4484
4485         dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
4486
4487         return NT_STATUS_OK;
4488 }
4489
4490 /*
4491  * Fetch a list of all server aliases and their members into
4492  * server_aliases.
4493  */
4494
4495 static NTSTATUS rpc_aliaslist_internals(struct net_context *c,
4496                                         const struct dom_sid *domain_sid,
4497                                         const char *domain_name,
4498                                         struct cli_state *cli,
4499                                         struct rpc_pipe_client *pipe_hnd,
4500                                         TALLOC_CTX *mem_ctx,
4501                                         int argc,
4502                                         const char **argv)
4503 {
4504         NTSTATUS result, status;
4505         struct policy_handle connect_pol;
4506         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4507
4508         status = dcerpc_samr_Connect2(b, mem_ctx,
4509                                       pipe_hnd->desthost,
4510                                       MAXIMUM_ALLOWED_ACCESS,
4511                                       &connect_pol,
4512                                       &result);
4513         if (!NT_STATUS_IS_OK(status)) {
4514                 goto done;
4515         }
4516         if (!NT_STATUS_IS_OK(result)) {
4517                 status = result;
4518                 goto done;
4519         }
4520
4521         status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4522                                           &global_sid_Builtin);
4523         if (!NT_STATUS_IS_OK(status)) {
4524                 goto done;
4525         }
4526
4527         status = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
4528                                           domain_sid);
4529
4530         dcerpc_samr_Close(b, mem_ctx, &connect_pol, &result);
4531  done:
4532         return status;
4533 }
4534
4535 static void init_user_token(struct security_token *token, struct dom_sid *user_sid)
4536 {
4537         token->num_sids = 4;
4538
4539         if (!(token->sids = SMB_MALLOC_ARRAY(struct dom_sid, 4))) {
4540                 d_fprintf(stderr, "malloc %s\n",_("failed"));
4541                 token->num_sids = 0;
4542                 return;
4543         }
4544
4545         token->sids[0] = *user_sid;
4546         sid_copy(&token->sids[1], &global_sid_World);
4547         sid_copy(&token->sids[2], &global_sid_Network);
4548         sid_copy(&token->sids[3], &global_sid_Authenticated_Users);
4549 }
4550
4551 static void free_user_token(struct security_token *token)
4552 {
4553         SAFE_FREE(token->sids);
4554 }
4555
4556 static void add_sid_to_token(struct security_token *token, struct dom_sid *sid)
4557 {
4558         if (security_token_has_sid(token, sid))
4559                 return;
4560
4561         token->sids = SMB_REALLOC_ARRAY(token->sids, struct dom_sid, token->num_sids+1);
4562         if (!token->sids) {
4563                 return;
4564         }
4565
4566         sid_copy(&token->sids[token->num_sids], sid);
4567
4568         token->num_sids += 1;
4569 }
4570
4571 struct user_token {
4572         fstring name;
4573         struct security_token token;
4574 };
4575
4576 static void dump_user_token(struct user_token *token)
4577 {
4578         int i;
4579
4580         d_printf("%s\n", token->name);
4581
4582         for (i=0; i<token->token.num_sids; i++) {
4583                 d_printf(" %s\n", sid_string_tos(&token->token.sids[i]));
4584         }
4585 }
4586
4587 static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias)
4588 {
4589         int i;
4590
4591         for (i=0; i<alias->num_members; i++) {
4592                 if (dom_sid_compare(sid, &alias->members[i]) == 0)
4593                         return true;
4594         }
4595
4596         return false;
4597 }
4598
4599 static void collect_sid_memberships(struct security_token *token, struct dom_sid sid)
4600 {
4601         int i;
4602
4603         for (i=0; i<num_server_aliases; i++) {
4604                 if (is_alias_member(&sid, &server_aliases[i]))
4605                         add_sid_to_token(token, &server_aliases[i].sid);
4606         }
4607 }
4608
4609 /*
4610  * We got a user token with all the SIDs we can know about without asking the
4611  * server directly. These are the user and domain group sids. All of these can
4612  * be members of aliases. So scan the list of aliases for each of the SIDs and
4613  * add them to the token.
4614  */
4615
4616 static void collect_alias_memberships(struct security_token *token)
4617 {
4618         int num_global_sids = token->num_sids;
4619         int i;
4620
4621         for (i=0; i<num_global_sids; i++) {
4622                 collect_sid_memberships(token, token->sids[i]);
4623         }
4624 }
4625
4626 static bool get_user_sids(const char *domain, const char *user, struct security_token *token)
4627 {
4628         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4629         enum wbcSidType type;
4630         fstring full_name;
4631         struct wbcDomainSid wsid;
4632         char sid_str[WBC_SID_STRING_BUFLEN];
4633         struct dom_sid user_sid;
4634         uint32_t num_groups;
4635         gid_t *groups = NULL;
4636         uint32_t i;
4637
4638         fstr_sprintf(full_name, "%s%c%s",
4639                      domain, *lp_winbind_separator(), user);
4640
4641         /* First let's find out the user sid */
4642
4643         wbc_status = wbcLookupName(domain, user, &wsid, &type);
4644
4645         if (!WBC_ERROR_IS_OK(wbc_status)) {
4646                 DEBUG(1, ("winbind could not find %s: %s\n",
4647                           full_name, wbcErrorString(wbc_status)));
4648                 return false;
4649         }
4650
4651         wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4652
4653         if (type != WBC_SID_NAME_USER) {
4654                 DEBUG(1, ("%s is not a user\n", full_name));
4655                 return false;
4656         }
4657
4658         if (!string_to_sid(&user_sid, sid_str)) {
4659                 DEBUG(1,("Could not convert sid %s from string\n", sid_str));
4660                 return false;
4661         }
4662
4663         init_user_token(token, &user_sid);
4664
4665         /* And now the groups winbind knows about */
4666
4667         wbc_status = wbcGetGroups(full_name, &num_groups, &groups);
4668         if (!WBC_ERROR_IS_OK(wbc_status)) {
4669                 DEBUG(1, ("winbind could not get groups of %s: %s\n",
4670                         full_name, wbcErrorString(wbc_status)));
4671                 return false;
4672         }
4673
4674         for (i = 0; i < num_groups; i++) {
4675                 gid_t gid = groups[i];
4676                 struct dom_sid sid;
4677
4678                 wbc_status = wbcGidToSid(gid, &wsid);
4679                 if (!WBC_ERROR_IS_OK(wbc_status)) {
4680                         DEBUG(1, ("winbind could not find SID of gid %u: %s\n",
4681                                   (unsigned int)gid, wbcErrorString(wbc_status)));
4682                         wbcFreeMemory(groups);
4683                         return false;
4684                 }
4685
4686                 wbcSidToStringBuf(&wsid, sid_str, sizeof(sid_str));
4687
4688                 DEBUG(3, (" %s\n", sid_str));
4689
4690                 string_to_sid(&sid, sid_str);
4691                 add_sid_to_token(token, &sid);
4692         }
4693         wbcFreeMemory(groups);
4694
4695         return true;
4696 }
4697
4698 /**
4699  * Get a list of all user tokens we want to look at
4700  **/
4701
4702 static bool get_user_tokens(struct net_context *c, int *num_tokens,
4703                             struct user_token **user_tokens)
4704 {
4705         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
4706         uint32_t i, num_users;
4707         const char **users;
4708         struct user_token *result;
4709         TALLOC_CTX *frame = NULL;
4710
4711         if (lp_winbind_use_default_domain() &&
4712             (c->opt_target_workgroup == NULL)) {
4713                 d_fprintf(stderr, _("winbind use default domain = yes set, "
4714                          "please specify a workgroup\n"));
4715                 return false;
4716         }
4717
4718         /* Send request to winbind daemon */
4719
4720         wbc_status = wbcListUsers(NULL, &num_users, &users);
4721         if (!WBC_ERROR_IS_OK(wbc_status)) {
4722                 DEBUG(1, (_("winbind could not list users: %s\n"),
4723                           wbcErrorString(wbc_status)));
4724                 return false;
4725         }
4726
4727         result = SMB_MALLOC_ARRAY(struct user_token, num_users);
4728
4729         if (result == NULL) {
4730                 DEBUG(1, ("Could not malloc sid array\n"));
4731                 wbcFreeMemory(users);
4732                 return false;
4733         }
4734
4735         frame = talloc_stackframe();
4736         for (i=0; i < num_users; i++) {
4737                 fstring domain, user;
4738                 char *p;
4739
4740                 fstrcpy(result[i].name, users[i]);
4741
4742                 p = strchr(users[i], *lp_winbind_separator());
4743
4744                 DEBUG(3, ("%s\n", users[i]));
4745
4746                 if (p == NULL) {
4747                         fstrcpy(domain, c->opt_target_workgroup);
4748                         fstrcpy(user, users[i]);
4749                 } else {
4750                         *p++ = '\0';
4751                         fstrcpy(domain, users[i]);
4752                         strupper_m(domain);
4753                         fstrcpy(user, p);
4754                 }
4755
4756                 get_user_sids(domain, user, &(result[i].token));
4757         }
4758         TALLOC_FREE(frame);
4759         wbcFreeMemory(users);
4760
4761         *num_tokens = num_users;
4762         *user_tokens = result;
4763
4764         return true;
4765 }
4766
4767 static bool get_user_tokens_from_file(FILE *f,
4768                                       int *num_tokens,
4769                                       struct user_token **tokens)
4770 {
4771         struct user_token *token = NULL;
4772
4773         while (!feof(f)) {
4774                 fstring line;
4775
4776                 if (fgets(line, sizeof(line)-1, f) == NULL) {
4777                         return true;
4778                 }
4779
4780                 if ((strlen(line) > 0) && (line[strlen(line)-1] == '\n')) {
4781                         line[strlen(line)-1] = '\0';
4782                 }
4783
4784                 if (line[0] == ' ') {
4785                         /* We have a SID */
4786
4787                         struct dom_sid sid;
4788                         if(!string_to_sid(&sid, &line[1])) {
4789                                 DEBUG(1,("get_user_tokens_from_file: Could "
4790                                         "not convert sid %s \n",&line[1]));
4791                                 return false;
4792                         }
4793
4794                         if (token == NULL) {
4795                                 DEBUG(0, ("File does not begin with username"));
4796                                 return false;
4797                         }
4798
4799                         add_sid_to_token(&token->token, &sid);
4800                         continue;
4801                 }
4802
4803                 /* And a new user... */
4804
4805                 *num_tokens += 1;
4806                 *tokens = SMB_REALLOC_ARRAY(*tokens, struct user_token, *num_tokens);
4807                 if (*tokens == NULL) {
4808                         DEBUG(0, ("Could not realloc tokens\n"));
4809                         return false;
4810                 }
4811
4812                 token = &((*tokens)[*num_tokens-1]);
4813
4814                 if (strlcpy(token->name, line, sizeof(token->name)) >= sizeof(token->name)) {
4815                         return false;
4816                 }
4817                 token->token.num_sids = 0;
4818                 token->token.sids = NULL;
4819                 continue;
4820         }
4821
4822         return false;
4823 }
4824
4825
4826 /*
4827  * Show the list of all users that have access to a share
4828  */
4829
4830 static void show_userlist(struct rpc_pipe_client *pipe_hnd,
4831                         TALLOC_CTX *mem_ctx,
4832                         const char *netname,
4833                         int num_tokens,
4834                         struct user_token *tokens)
4835 {
4836         uint16_t fnum;
4837         struct security_descriptor *share_sd = NULL;
4838         struct security_descriptor *root_sd = NULL;
4839         struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
4840         int i;
4841         union srvsvc_NetShareInfo info;
4842         WERROR result;
4843         NTSTATUS status;
4844         uint16 cnum;
4845         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
4846
4847         status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
4848                                                pipe_hnd->desthost,
4849                                                netname,
4850                                                502,
4851                                                &info,
4852                                                &result);
4853
4854         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
4855                 DEBUG(1, ("Coult not query secdesc for share %s\n",
4856                           netname));
4857                 return;
4858         }
4859
4860         share_sd = info.info502->sd_buf.sd;
4861         if (share_sd == NULL) {
4862                 DEBUG(1, ("Got no secdesc for share %s\n",
4863                           netname));
4864         }
4865
4866         cnum = cli_state_get_tid(cli);
4867
4868         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", "", 0))) {
4869                 return;
4870         }
4871
4872         if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
4873                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
4874                 cli_query_secdesc(cli, fnum, mem_ctx, &root_sd);
4875         }
4876
4877         for (i=0; i<num_tokens; i++) {
4878                 uint32 acc_granted;
4879
4880                 if (share_sd != NULL) {
4881                         status = se_access_check(share_sd, &tokens[i].token,
4882                                              1, &acc_granted);
4883
4884                         if (!NT_STATUS_IS_OK(status)) {
4885                                 DEBUG(1, ("Could not check share_sd for "
4886                                           "user %s\n",
4887                                           tokens[i].name));
4888                                 continue;
4889                         }
4890                 }
4891
4892                 if (root_sd == NULL) {
4893                         d_printf(" %s\n", tokens[i].name);
4894                         continue;
4895                 }
4896
4897                 status = se_access_check(root_sd, &tokens[i].token,
4898                                      1, &acc_granted);
4899                 if (!NT_STATUS_IS_OK(status)) {
4900                         DEBUG(1, ("Could not check root_sd for user %s\n",
4901                                   tokens[i].name));
4902                         continue;
4903                 }
4904                 d_printf(" %s\n", tokens[i].name);
4905         }
4906
4907         if (fnum != (uint16_t)-1)
4908                 cli_close(cli, fnum);
4909         cli_tdis(cli);
4910         cli_state_set_tid(cli, cnum);
4911
4912         return;
4913 }
4914
4915 struct share_list {
4916         int num_shares;
4917         char **shares;
4918 };
4919
4920 static void collect_share(const char *name, uint32 m,
4921                           const char *comment, void *state)
4922 {
4923         struct share_list *share_list = (struct share_list *)state;
4924
4925         if (m != STYPE_DISKTREE)
4926                 return;
4927
4928         share_list->num_shares += 1;
4929         share_list->shares = SMB_REALLOC_ARRAY(share_list->shares, char *, share_list->num_shares);
4930         if (!share_list->shares) {
4931                 share_list->num_shares = 0;
4932                 return;
4933         }
4934         share_list->shares[share_list->num_shares-1] = SMB_STRDUP(name);
4935 }
4936
4937 /**
4938  * List shares on a remote RPC server, including the security descriptors.
4939  *
4940  * All parameters are provided by the run_rpc_command function, except for
4941  * argc, argv which are passed through.
4942  *
4943  * @param domain_sid The domain sid acquired from the remote server.
4944  * @param cli A cli_state connected to the server.
4945  * @param mem_ctx Talloc context, destroyed on completion of the function.
4946  * @param argc  Standard main() style argc.
4947  * @param argv  Standard main() style argv. Initial components are already
4948  *              stripped.
4949  *
4950  * @return Normal NTSTATUS return.
4951  **/
4952
4953 static NTSTATUS rpc_share_allowedusers_internals(struct net_context *c,
4954                                                 const struct dom_sid *domain_sid,
4955                                                 const char *domain_name,
4956                                                 struct cli_state *cli,
4957                                                 struct rpc_pipe_client *pipe_hnd,
4958                                                 TALLOC_CTX *mem_ctx,
4959                                                 int argc,
4960                                                 const char **argv)
4961 {
4962         int ret;
4963         bool r;
4964         uint32 i;
4965         FILE *f;
4966
4967         struct user_token *tokens = NULL;
4968         int num_tokens = 0;
4969
4970         struct share_list share_list;
4971
4972         if (argc == 0) {
4973                 f = stdin;
4974         } else {
4975                 f = fopen(argv[0], "r");
4976         }
4977
4978         if (f == NULL) {
4979                 DEBUG(0, ("Could not open userlist: %s\n", strerror(errno)));
4980                 return NT_STATUS_UNSUCCESSFUL;
4981         }
4982
4983         r = get_user_tokens_from_file(f, &num_tokens, &tokens);
4984
4985         if (f != stdin)
4986                 fclose(f);
4987
4988         if (!r) {
4989                 DEBUG(0, ("Could not read users from file\n"));
4990                 return NT_STATUS_UNSUCCESSFUL;
4991         }
4992
4993         for (i=0; i<num_tokens; i++)
4994                 collect_alias_memberships(&tokens[i].token);
4995
4996         share_list.num_shares = 0;
4997         share_list.shares = NULL;
4998
4999         ret = cli_RNetShareEnum(cli, collect_share, &share_list);
5000
5001         if (ret == -1) {
5002                 DEBUG(0, ("Error returning browse list: %s\n",
5003                           cli_errstr(cli)));
5004                 goto done;
5005         }
5006
5007         for (i = 0; i < share_list.num_shares; i++) {
5008                 char *netname = share_list.shares[i];
5009
5010                 if (netname[strlen(netname)-1] == '$')
5011                         continue;
5012
5013                 d_printf("%s\n", netname);
5014
5015                 show_userlist(pipe_hnd, mem_ctx, netname,
5016                               num_tokens, tokens);
5017         }
5018  done:
5019         for (i=0; i<num_tokens; i++) {
5020                 free_user_token(&tokens[i].token);
5021         }
5022         SAFE_FREE(tokens);
5023         SAFE_FREE(share_list.shares);
5024
5025         return NT_STATUS_OK;
5026 }
5027
5028 static int rpc_share_allowedusers(struct net_context *c, int argc,
5029                                   const char **argv)
5030 {
5031         int result;
5032
5033         if (c->display_usage) {
5034                 d_printf(  "%s\n"
5035                            "net rpc share allowedusers\n"
5036                             "    %s\n",
5037                           _("Usage:"),
5038                           _("List allowed users"));
5039                 return 0;
5040         }
5041
5042         result = run_rpc_command(c, NULL, &ndr_table_samr, 0,
5043                                  rpc_aliaslist_internals,
5044                                  argc, argv);
5045         if (result != 0)
5046                 return result;
5047
5048         result = run_rpc_command(c, NULL, &ndr_table_lsarpc, 0,
5049                                  rpc_aliaslist_dump,
5050                                  argc, argv);
5051         if (result != 0)
5052                 return result;
5053
5054         return run_rpc_command(c, NULL, &ndr_table_srvsvc, 0,
5055                                rpc_share_allowedusers_internals,
5056                                argc, argv);
5057 }
5058
5059 int net_usersidlist(struct net_context *c, int argc, const char **argv)
5060 {
5061         int num_tokens = 0;
5062         struct user_token *tokens = NULL;
5063         int i;
5064
5065         if (argc != 0) {
5066                 net_usersidlist_usage(c, argc, argv);
5067                 return 0;
5068         }
5069
5070         if (!get_user_tokens(c, &num_tokens, &tokens)) {
5071                 DEBUG(0, ("Could not get the user/sid list\n"));
5072                 return -1;
5073         }
5074
5075         for (i=0; i<num_tokens; i++) {
5076                 dump_user_token(&tokens[i]);
5077                 free_user_token(&tokens[i].token);
5078         }
5079
5080         SAFE_FREE(tokens);
5081         return 0;
5082 }
5083
5084 int net_usersidlist_usage(struct net_context *c, int argc, const char **argv)
5085 {
5086         d_printf(_("net usersidlist\n"
5087                    "\tprints out a list of all users the running winbind knows\n"
5088                    "\tabout, together with all their SIDs. This is used as\n"
5089                    "\tinput to the 'net rpc share allowedusers' command.\n\n"));
5090
5091         net_common_flags_usage(c, argc, argv);
5092         return -1;
5093 }
5094
5095 /**
5096  * 'net rpc share' entrypoint.
5097  * @param argc  Standard main() style argc.
5098  * @param argv  Standard main() style argv. Initial components are already
5099  *              stripped.
5100  **/
5101
5102 int net_rpc_share(struct net_context *c, int argc, const char **argv)
5103 {
5104         NET_API_STATUS status;
5105
5106         struct functable func[] = {
5107                 {
5108                         "add",
5109                         rpc_share_add,
5110                         NET_TRANSPORT_RPC,
5111                         N_("Add share"),
5112                         N_("net rpc share add\n"
5113                            "    Add share")
5114                 },
5115                 {
5116                         "delete",
5117                         rpc_share_delete,
5118                         NET_TRANSPORT_RPC,
5119                         N_("Remove share"),
5120                         N_("net rpc share delete\n"
5121                            "    Remove share")
5122                 },
5123                 {
5124                         "allowedusers",
5125                         rpc_share_allowedusers,
5126                         NET_TRANSPORT_RPC,
5127                         N_("Modify allowed users"),
5128                         N_("net rpc share allowedusers\n"
5129                            "    Modify allowed users")
5130                 },
5131                 {
5132                         "migrate",
5133                         rpc_share_migrate,
5134                         NET_TRANSPORT_RPC,
5135                         N_("Migrate share to local server"),
5136                         N_("net rpc share migrate\n"
5137                            "    Migrate share to local server")
5138                 },
5139                 {
5140                         "list",
5141                         rpc_share_list,
5142                         NET_TRANSPORT_RPC,
5143                         N_("List shares"),
5144                         N_("net rpc share list\n"
5145                            "    List shares")
5146                 },
5147                 {NULL, NULL, 0, NULL, NULL}
5148         };
5149
5150         status = libnetapi_net_init(&c->netapi_ctx);
5151         if (status != 0) {
5152                 return -1;
5153         }
5154         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5155         libnetapi_set_password(c->netapi_ctx, c->opt_password);
5156         if (c->opt_kerberos) {
5157                 libnetapi_set_use_kerberos(c->netapi_ctx);
5158         }
5159
5160         if (argc == 0) {
5161                 if (c->display_usage) {
5162                         d_printf("%s\n%s",
5163                                  _("Usage:"),
5164                                  _("net rpc share\n"
5165                                    "    List shares\n"
5166                                    "    Alias for net rpc share list\n"));
5167                         net_display_usage_from_functable(func);
5168                         return 0;
5169                 }
5170
5171                 return rpc_share_list(c, argc, argv);
5172         }
5173
5174         return net_run_function(c, argc, argv, "net rpc share", func);
5175 }
5176
5177 static NTSTATUS rpc_sh_share_list(struct net_context *c,
5178                                   TALLOC_CTX *mem_ctx,
5179                                   struct rpc_sh_ctx *ctx,
5180                                   struct rpc_pipe_client *pipe_hnd,
5181                                   int argc, const char **argv)
5182 {
5183
5184         return werror_to_ntstatus(W_ERROR(rpc_share_list(c, argc, argv)));
5185 }
5186
5187 static NTSTATUS rpc_sh_share_add(struct net_context *c,
5188                                  TALLOC_CTX *mem_ctx,
5189                                  struct rpc_sh_ctx *ctx,
5190                                  struct rpc_pipe_client *pipe_hnd,
5191                                  int argc, const char **argv)
5192 {
5193         NET_API_STATUS status;
5194         uint32_t parm_err = 0;
5195         struct SHARE_INFO_2 i2;
5196
5197         if ((argc < 2) || (argc > 3)) {
5198                 d_fprintf(stderr, _("Usage: %s <share> <path> [comment]\n"),
5199                           ctx->whoami);
5200                 return NT_STATUS_INVALID_PARAMETER;
5201         }
5202
5203         i2.shi2_netname         = argv[0];
5204         i2.shi2_type            = STYPE_DISKTREE;
5205         i2.shi2_remark          = (argc == 3) ? argv[2] : "";
5206         i2.shi2_permissions     = 0;
5207         i2.shi2_max_uses        = 0;
5208         i2.shi2_current_uses    = 0;
5209         i2.shi2_path            = argv[1];
5210         i2.shi2_passwd          = NULL;
5211
5212         status = NetShareAdd(pipe_hnd->desthost,
5213                              2,
5214                              (uint8_t *)&i2,
5215                              &parm_err);
5216
5217         return werror_to_ntstatus(W_ERROR(status));
5218 }
5219
5220 static NTSTATUS rpc_sh_share_delete(struct net_context *c,
5221                                     TALLOC_CTX *mem_ctx,
5222                                     struct rpc_sh_ctx *ctx,
5223                                     struct rpc_pipe_client *pipe_hnd,
5224                                     int argc, const char **argv)
5225 {
5226         if (argc != 1) {
5227                 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5228                 return NT_STATUS_INVALID_PARAMETER;
5229         }
5230
5231         return werror_to_ntstatus(W_ERROR(NetShareDel(pipe_hnd->desthost, argv[0], 0)));
5232 }
5233
5234 static NTSTATUS rpc_sh_share_info(struct net_context *c,
5235                                   TALLOC_CTX *mem_ctx,
5236                                   struct rpc_sh_ctx *ctx,
5237                                   struct rpc_pipe_client *pipe_hnd,
5238                                   int argc, const char **argv)
5239 {
5240         union srvsvc_NetShareInfo info;
5241         WERROR result;
5242         NTSTATUS status;
5243         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5244
5245         if (argc != 1) {
5246                 d_fprintf(stderr, "%s %s <share>\n", _("Usage:"), ctx->whoami);
5247                 return NT_STATUS_INVALID_PARAMETER;
5248         }
5249
5250         status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
5251                                                pipe_hnd->desthost,
5252                                                argv[0],
5253                                                2,
5254                                                &info,
5255                                                &result);
5256         if (!NT_STATUS_IS_OK(status)) {
5257                 result = ntstatus_to_werror(status);
5258                 goto done;
5259         }
5260         if (!W_ERROR_IS_OK(result)) {
5261                 goto done;
5262         }
5263
5264         d_printf(_("Name:     %s\n"), info.info2->name);
5265         d_printf(_("Comment:  %s\n"), info.info2->comment);
5266         d_printf(_("Path:     %s\n"), info.info2->path);
5267         d_printf(_("Password: %s\n"), info.info2->password);
5268
5269  done:
5270         return werror_to_ntstatus(result);
5271 }
5272
5273 struct rpc_sh_cmd *net_rpc_share_cmds(struct net_context *c, TALLOC_CTX *mem_ctx,
5274                                       struct rpc_sh_ctx *ctx)
5275 {
5276         static struct rpc_sh_cmd cmds[] = {
5277
5278         { "list", NULL, &ndr_table_srvsvc, rpc_sh_share_list,
5279           N_("List available shares") },
5280
5281         { "add", NULL, &ndr_table_srvsvc, rpc_sh_share_add,
5282           N_("Add a share") },
5283
5284         { "delete", NULL, &ndr_table_srvsvc, rpc_sh_share_delete,
5285           N_("Delete a share") },
5286
5287         { "info", NULL, &ndr_table_srvsvc, rpc_sh_share_info,
5288           N_("Get information about a share") },
5289
5290         { NULL, NULL, 0, NULL, NULL }
5291         };
5292
5293         return cmds;
5294 }
5295
5296 /****************************************************************************/
5297
5298 static int rpc_file_usage(struct net_context *c, int argc, const char **argv)
5299 {
5300         return net_file_usage(c, argc, argv);
5301 }
5302
5303 /**
5304  * Close a file on a remote RPC server.
5305  *
5306  * @param argc  Standard main() style argc.
5307  * @param argv  Standard main() style argv. Initial components are already
5308  *              stripped.
5309  *
5310  * @return A shell status integer (0 for success).
5311  **/
5312 static int rpc_file_close(struct net_context *c, int argc, const char **argv)
5313 {
5314         if (argc < 1 || c->display_usage) {
5315                 return rpc_file_usage(c, argc, argv);
5316         }
5317
5318         return NetFileClose(c->opt_host, atoi(argv[0]));
5319 }
5320
5321 /**
5322  * Formatted print of open file info
5323  *
5324  * @param r  struct FILE_INFO_3 contents
5325  **/
5326
5327 static void display_file_info_3(struct FILE_INFO_3 *r)
5328 {
5329         d_printf("%-7.1d %-20.20s 0x%-4.2x %-6.1d %s\n",
5330                  r->fi3_id, r->fi3_username, r->fi3_permissions,
5331                  r->fi3_num_locks, r->fi3_pathname);
5332 }
5333
5334 /**
5335  * List files for a user on a remote RPC server.
5336  *
5337  * @param argc  Standard main() style argc.
5338  * @param argv  Standard main() style argv. Initial components are already
5339  *              stripped.
5340  *
5341  * @return A shell status integer (0 for success)..
5342  **/
5343
5344 static int rpc_file_user(struct net_context *c, int argc, const char **argv)
5345 {
5346         NET_API_STATUS status;
5347         uint32 preferred_len = 0xffffffff, i;
5348         const char *username=NULL;
5349         uint32_t total_entries = 0;
5350         uint32_t entries_read = 0;
5351         uint32_t resume_handle = 0;
5352         struct FILE_INFO_3 *i3 = NULL;
5353
5354         if (c->display_usage) {
5355                 return rpc_file_usage(c, argc, argv);
5356         }
5357
5358         /* if argc > 0, must be user command */
5359         if (argc > 0) {
5360                 username = smb_xstrdup(argv[0]);
5361         }
5362
5363         status = NetFileEnum(c->opt_host,
5364                              NULL,
5365                              username,
5366                              3,
5367                              (uint8_t **)(void *)&i3,
5368                              preferred_len,
5369                              &entries_read,
5370                              &total_entries,
5371                              &resume_handle);
5372
5373         if (status != 0) {
5374                 goto done;
5375         }
5376
5377         /* Display results */
5378
5379         d_printf(_(
5380                  "\nEnumerating open files on remote server:\n\n"
5381                  "\nFileId  Opened by            Perms  Locks  Path"
5382                  "\n------  ---------            -----  -----  ---- \n"));
5383         for (i = 0; i < entries_read; i++) {
5384                 display_file_info_3(&i3[i]);
5385         }
5386  done:
5387         return status;
5388 }
5389
5390 /**
5391  * 'net rpc file' entrypoint.
5392  * @param argc  Standard main() style argc.
5393  * @param argv  Standard main() style argv. Initial components are already
5394  *              stripped.
5395  **/
5396
5397 int net_rpc_file(struct net_context *c, int argc, const char **argv)
5398 {
5399         NET_API_STATUS status;
5400
5401         struct functable func[] = {
5402                 {
5403                         "close",
5404                         rpc_file_close,
5405                         NET_TRANSPORT_RPC,
5406                         N_("Close opened file"),
5407                         N_("net rpc file close\n"
5408                            "    Close opened file")
5409                 },
5410                 {
5411                         "user",
5412                         rpc_file_user,
5413                         NET_TRANSPORT_RPC,
5414                         N_("List files opened by user"),
5415                         N_("net rpc file user\n"
5416                            "    List files opened by user")
5417                 },
5418 #if 0
5419                 {
5420                         "info",
5421                         rpc_file_info,
5422                         NET_TRANSPORT_RPC,
5423                         N_("Display information about opened file"),
5424                         N_("net rpc file info\n"
5425                            "    Display information about opened file")
5426                 },
5427 #endif
5428                 {NULL, NULL, 0, NULL, NULL}
5429         };
5430
5431         status = libnetapi_net_init(&c->netapi_ctx);
5432         if (status != 0) {
5433                 return -1;
5434         }
5435         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
5436         libnetapi_set_password(c->netapi_ctx, c->opt_password);
5437         if (c->opt_kerberos) {
5438                 libnetapi_set_use_kerberos(c->netapi_ctx);
5439         }
5440
5441         if (argc == 0) {
5442                 if (c->display_usage) {
5443                         d_printf(_("Usage:\n"));
5444                         d_printf(_("net rpc file\n"
5445                                    "    List opened files\n"));
5446                         net_display_usage_from_functable(func);
5447                         return 0;
5448                 }
5449
5450                 return rpc_file_user(c, argc, argv);
5451         }
5452
5453         return net_run_function(c, argc, argv, "net rpc file", func);
5454 }
5455
5456 /**
5457  * ABORT the shutdown of a remote RPC Server, over initshutdown pipe.
5458  *
5459  * All parameters are provided by the run_rpc_command function, except for
5460  * argc, argv which are passed through.
5461  *
5462  * @param c     A net_context structure.
5463  * @param domain_sid The domain sid acquired from the remote server.
5464  * @param cli A cli_state connected to the server.
5465  * @param mem_ctx Talloc context, destroyed on completion of the function.
5466  * @param argc  Standard main() style argc.
5467  * @param argv  Standard main() style argv. Initial components are already
5468  *              stripped.
5469  *
5470  * @return Normal NTSTATUS return.
5471  **/
5472
5473 static NTSTATUS rpc_shutdown_abort_internals(struct net_context *c,
5474                                         const struct dom_sid *domain_sid,
5475                                         const char *domain_name,
5476                                         struct cli_state *cli,
5477                                         struct rpc_pipe_client *pipe_hnd,
5478                                         TALLOC_CTX *mem_ctx,
5479                                         int argc,
5480                                         const char **argv)
5481 {
5482         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5483         WERROR result;
5484         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5485
5486         status = dcerpc_initshutdown_Abort(b, mem_ctx, NULL, &result);
5487         if (!NT_STATUS_IS_OK(status)) {
5488                 return status;
5489         }
5490         if (W_ERROR_IS_OK(result)) {
5491                 d_printf(_("\nShutdown successfully aborted\n"));
5492                 DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
5493         } else
5494                 DEBUG(5,("cmd_shutdown_abort: query failed\n"));
5495
5496         return werror_to_ntstatus(result);
5497 }
5498
5499 /**
5500  * ABORT the shutdown of a remote RPC Server, over winreg pipe.
5501  *
5502  * All parameters are provided by the run_rpc_command function, except for
5503  * argc, argv which are passed through.
5504  *
5505  * @param c     A net_context structure.
5506  * @param domain_sid The domain sid acquired from the remote server.
5507  * @param cli A cli_state connected to the server.
5508  * @param mem_ctx Talloc context, destroyed on completion of the function.
5509  * @param argc  Standard main() style argc.
5510  * @param argv  Standard main() style argv. Initial components are already
5511  *              stripped.
5512  *
5513  * @return Normal NTSTATUS return.
5514  **/
5515
5516 static NTSTATUS rpc_reg_shutdown_abort_internals(struct net_context *c,
5517                                                 const struct dom_sid *domain_sid,
5518                                                 const char *domain_name,
5519                                                 struct cli_state *cli,
5520                                                 struct rpc_pipe_client *pipe_hnd,
5521                                                 TALLOC_CTX *mem_ctx,
5522                                                 int argc,
5523                                                 const char **argv)
5524 {
5525         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
5526         WERROR werr;
5527         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5528
5529         result = dcerpc_winreg_AbortSystemShutdown(b, mem_ctx, NULL, &werr);
5530
5531         if (!NT_STATUS_IS_OK(result)) {
5532                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5533                 return result;
5534         }
5535         if (W_ERROR_IS_OK(werr)) {
5536                 d_printf(_("\nShutdown successfully aborted\n"));
5537                 DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
5538         } else
5539                 DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
5540
5541         return werror_to_ntstatus(werr);
5542 }
5543
5544 /**
5545  * ABORT the shutdown of a remote RPC server.
5546  *
5547  * @param argc  Standard main() style argc.
5548  * @param argv  Standard main() style argv. Initial components are already
5549  *              stripped.
5550  *
5551  * @return A shell status integer (0 for success).
5552  **/
5553
5554 static int rpc_shutdown_abort(struct net_context *c, int argc,
5555                               const char **argv)
5556 {
5557         int rc = -1;
5558
5559         if (c->display_usage) {
5560                 d_printf(  "%s\n"
5561                            "net rpc abortshutdown\n"
5562                            "    %s\n",
5563                          _("Usage:"),
5564                          _("Abort a scheduled shutdown"));
5565                 return 0;
5566         }
5567
5568         rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
5569                              rpc_shutdown_abort_internals, argc, argv);
5570
5571         if (rc == 0)
5572                 return rc;
5573
5574         DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
5575
5576         return run_rpc_command(c, NULL, &ndr_table_winreg, 0,
5577                                rpc_reg_shutdown_abort_internals,
5578                                argc, argv);
5579 }
5580
5581 /**
5582  * Shut down a remote RPC Server via initshutdown pipe.
5583  *
5584  * All parameters are provided by the run_rpc_command function, except for
5585  * argc, argv which are passed through.
5586  *
5587  * @param c     A net_context structure.
5588  * @param domain_sid The domain sid acquired from the remote server.
5589  * @param cli A cli_state connected to the server.
5590  * @param mem_ctx Talloc context, destroyed on completion of the function.
5591  * @param argc  Standard main() style argc.
5592  * @param argv  Standard main() style argv. Initial components are already
5593  *              stripped.
5594  *
5595  * @return Normal NTSTATUS return.
5596  **/
5597
5598 NTSTATUS rpc_init_shutdown_internals(struct net_context *c,
5599                                      const struct dom_sid *domain_sid,
5600                                      const char *domain_name,
5601                                      struct cli_state *cli,
5602                                      struct rpc_pipe_client *pipe_hnd,
5603                                      TALLOC_CTX *mem_ctx,
5604                                      int argc,
5605                                      const char **argv)
5606 {
5607         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
5608         WERROR result;
5609         const char *msg = N_("This machine will be shutdown shortly");
5610         uint32 timeout = 20;
5611         struct lsa_StringLarge msg_string;
5612         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5613
5614         if (c->opt_comment) {
5615                 msg = c->opt_comment;
5616         }
5617         if (c->opt_timeout) {
5618                 timeout = c->opt_timeout;
5619         }
5620
5621         msg_string.string = msg;
5622
5623         /* create an entry */
5624         status = dcerpc_initshutdown_Init(b, mem_ctx, NULL,
5625                         &msg_string, timeout, c->opt_force, c->opt_reboot,
5626                         &result);
5627         if (!NT_STATUS_IS_OK(status)) {
5628                 return status;
5629         }
5630         if (W_ERROR_IS_OK(result)) {
5631                 d_printf(_("\nShutdown of remote machine succeeded\n"));
5632                 DEBUG(5,("Shutdown of remote machine succeeded\n"));
5633         } else {
5634                 DEBUG(1,("Shutdown of remote machine failed!\n"));
5635         }
5636         return werror_to_ntstatus(result);
5637 }
5638
5639 /**
5640  * Shut down a remote RPC Server via winreg pipe.
5641  *
5642  * All parameters are provided by the run_rpc_command function, except for
5643  * argc, argv which are passed through.
5644  *
5645  * @param c     A net_context structure.
5646  * @param domain_sid The domain sid acquired from the remote server.
5647  * @param cli A cli_state connected to the server.
5648  * @param mem_ctx Talloc context, destroyed on completion of the function.
5649  * @param argc  Standard main() style argc.
5650  * @param argv  Standard main() style argv. Initial components are already
5651  *              stripped.
5652  *
5653  * @return Normal NTSTATUS return.
5654  **/
5655
5656 NTSTATUS rpc_reg_shutdown_internals(struct net_context *c,
5657                                     const struct dom_sid *domain_sid,
5658                                     const char *domain_name,
5659                                     struct cli_state *cli,
5660                                     struct rpc_pipe_client *pipe_hnd,
5661                                     TALLOC_CTX *mem_ctx,
5662                                     int argc,
5663                                     const char **argv)
5664 {
5665         const char *msg = N_("This machine will be shutdown shortly");
5666         uint32 timeout = 20;
5667         struct lsa_StringLarge msg_string;
5668         NTSTATUS result;
5669         WERROR werr;
5670         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5671
5672         if (c->opt_comment) {
5673                 msg = c->opt_comment;
5674         }
5675         msg_string.string = msg;
5676
5677         if (c->opt_timeout) {
5678                 timeout = c->opt_timeout;
5679         }
5680
5681         /* create an entry */
5682         result = dcerpc_winreg_InitiateSystemShutdown(b, mem_ctx, NULL,
5683                         &msg_string, timeout, c->opt_force, c->opt_reboot,
5684                         &werr);
5685         if (!NT_STATUS_IS_OK(result)) {
5686                 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5687                 return result;
5688         }
5689
5690         if (W_ERROR_IS_OK(werr)) {
5691                 d_printf(_("\nShutdown of remote machine succeeded\n"));
5692         } else {
5693                 d_fprintf(stderr, "\nShutdown of remote machine failed\n");
5694                 if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) )
5695                         d_fprintf(stderr, "\nMachine locked, use -f switch to force\n");
5696                 else
5697                         d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr));
5698         }
5699
5700         return werror_to_ntstatus(werr);
5701 }
5702
5703 /**
5704  * Shut down a remote RPC server.
5705  *
5706  * @param argc  Standard main() style argc.
5707  * @param argv  Standard main() style argv. Initial components are already
5708  *              stripped.
5709  *
5710  * @return A shell status integer (0 for success).
5711  **/
5712
5713 static int rpc_shutdown(struct net_context *c, int argc, const char **argv)
5714 {
5715         int rc =  -1;
5716
5717         if (c->display_usage) {
5718                 d_printf(  "%s\n"
5719                            "net rpc shutdown\n"
5720                            "    %s\n",
5721                          _("Usage:"),
5722                          _("Shut down a remote RPC server"));
5723                 return 0;
5724         }
5725
5726         rc = run_rpc_command(c, NULL, &ndr_table_initshutdown, 0,
5727                              rpc_init_shutdown_internals, argc, argv);
5728
5729         if (rc) {
5730                 DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n"));
5731                 rc = run_rpc_command(c, NULL, &ndr_table_winreg, 0,
5732                                      rpc_reg_shutdown_internals, argc, argv);
5733         }
5734
5735         return rc;
5736 }
5737
5738 /***************************************************************************
5739   NT Domain trusts code (i.e. 'net rpc trustdom' functionality)
5740  ***************************************************************************/
5741
5742 /**
5743  * Add interdomain trust account to the RPC server.
5744  * All parameters (except for argc and argv) are passed by run_rpc_command
5745  * function.
5746  *
5747  * @param c     A net_context structure.
5748  * @param domain_sid The domain sid acquired from the server.
5749  * @param cli A cli_state connected to the server.
5750  * @param mem_ctx Talloc context, destroyed on completion of the function.
5751  * @param argc  Standard main() style argc.
5752  * @param argv  Standard main() style argv. Initial components are already
5753  *              stripped.
5754  *
5755  * @return normal NTSTATUS return code.
5756  */
5757
5758 static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
5759                                                 const struct dom_sid *domain_sid,
5760                                                 const char *domain_name,
5761                                                 struct cli_state *cli,
5762                                                 struct rpc_pipe_client *pipe_hnd,
5763                                                 TALLOC_CTX *mem_ctx,
5764                                                 int argc,
5765                                                 const char **argv)
5766 {
5767         struct policy_handle connect_pol, domain_pol, user_pol;
5768         NTSTATUS status, result;
5769         char *acct_name;
5770         struct lsa_String lsa_acct_name;
5771         uint32 acb_info;
5772         uint32 acct_flags=0;
5773         uint32 user_rid;
5774         uint32_t access_granted = 0;
5775         union samr_UserInfo info;
5776         unsigned int orig_timeout;
5777         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5778
5779         if (argc != 2) {
5780                 d_printf("%s\n%s",
5781                          _("Usage:"),
5782                          _(" net rpc trustdom add <domain_name> "
5783                            "<trust password>\n"));
5784                 return NT_STATUS_INVALID_PARAMETER;
5785         }
5786
5787         /*
5788          * Make valid trusting domain account (ie. uppercased and with '$' appended)
5789          */
5790
5791         if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
5792                 return NT_STATUS_NO_MEMORY;
5793         }
5794
5795         strupper_m(acct_name);
5796
5797         init_lsa_String(&lsa_acct_name, acct_name);
5798
5799         /* Get samr policy handle */
5800         status = dcerpc_samr_Connect2(b, mem_ctx,
5801                                       pipe_hnd->desthost,
5802                                       MAXIMUM_ALLOWED_ACCESS,
5803                                       &connect_pol,
5804                                       &result);
5805         if (!NT_STATUS_IS_OK(status)) {
5806                 goto done;
5807         }
5808         if (!NT_STATUS_IS_OK(result)) {
5809                 status = result;
5810                 goto done;
5811         }
5812
5813         /* Get domain policy handle */
5814         status = dcerpc_samr_OpenDomain(b, mem_ctx,
5815                                         &connect_pol,
5816                                         MAXIMUM_ALLOWED_ACCESS,
5817                                         discard_const_p(struct dom_sid2, domain_sid),
5818                                         &domain_pol,
5819                                         &result);
5820         if (!NT_STATUS_IS_OK(status)) {
5821                 goto done;
5822         }
5823         if (!NT_STATUS_IS_OK(result)) {
5824                 status = result;
5825                 goto done;
5826         }
5827
5828         /* This call can take a long time - allow the server to time out.
5829          * 35 seconds should do it. */
5830
5831         orig_timeout = rpccli_set_timeout(pipe_hnd, 35000);
5832
5833         /* Create trusting domain's account */
5834         acb_info = ACB_NORMAL;
5835         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
5836                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
5837                      SAMR_USER_ACCESS_SET_PASSWORD |
5838                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
5839                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
5840
5841         status = dcerpc_samr_CreateUser2(b, mem_ctx,
5842                                          &domain_pol,
5843                                          &lsa_acct_name,
5844                                          acb_info,
5845                                          acct_flags,
5846                                          &user_pol,
5847                                          &access_granted,
5848                                          &user_rid,
5849                                          &result);
5850         if (!NT_STATUS_IS_OK(status)) {
5851                 goto done;
5852         }
5853         /* And restore our original timeout. */
5854         rpccli_set_timeout(pipe_hnd, orig_timeout);
5855
5856         if (!NT_STATUS_IS_OK(result)) {
5857                 status = result;
5858                 d_printf(_("net rpc trustdom add: create user %s failed %s\n"),
5859                         acct_name, nt_errstr(result));
5860                 goto done;
5861         }
5862
5863         {
5864                 struct samr_CryptPassword crypt_pwd;
5865
5866                 ZERO_STRUCT(info.info23);
5867
5868                 init_samr_CryptPassword(argv[1],
5869                                         &cli->user_session_key,
5870                                         &crypt_pwd);
5871
5872                 info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS |
5873                                                   SAMR_FIELD_NT_PASSWORD_PRESENT;
5874                 info.info23.info.acct_flags = ACB_DOMTRUST;
5875                 info.info23.password = crypt_pwd;
5876
5877                 status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
5878                                                   &user_pol,
5879                                                   23,
5880                                                   &info,
5881                                                   &result);
5882                 if (!NT_STATUS_IS_OK(status)) {
5883                         goto done;
5884                 }
5885
5886                 if (!NT_STATUS_IS_OK(result)) {
5887                         status = result;
5888                         DEBUG(0,("Could not set trust account password: %s\n",
5889                                  nt_errstr(result)));
5890                         goto done;
5891                 }
5892         }
5893
5894  done:
5895         SAFE_FREE(acct_name);
5896         return status;
5897 }
5898
5899 /**
5900  * Create interdomain trust account for a remote domain.
5901  *
5902  * @param argc Standard argc.
5903  * @param argv Standard argv without initial components.
5904  *
5905  * @return Integer status (0 means success).
5906  **/
5907
5908 static int rpc_trustdom_add(struct net_context *c, int argc, const char **argv)
5909 {
5910         if (argc > 0 && !c->display_usage) {
5911                 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
5912                                        rpc_trustdom_add_internals, argc, argv);
5913         } else {
5914                 d_printf("%s\n%s",
5915                          _("Usage:"),
5916                          _("net rpc trustdom add <domain_name> <trust "
5917                            "password>\n"));
5918                 return -1;
5919         }
5920 }
5921
5922
5923 /**
5924  * Remove interdomain trust account from the RPC server.
5925  * All parameters (except for argc and argv) are passed by run_rpc_command
5926  * function.
5927  *
5928  * @param c     A net_context structure.
5929  * @param domain_sid The domain sid acquired from the server.
5930  * @param cli A cli_state connected to the server.
5931  * @param mem_ctx Talloc context, destroyed on completion of the function.
5932  * @param argc  Standard main() style argc.
5933  * @param argv  Standard main() style argv. Initial components are already
5934  *              stripped.
5935  *
5936  * @return normal NTSTATUS return code.
5937  */
5938
5939 static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
5940                                         const struct dom_sid *domain_sid,
5941                                         const char *domain_name,
5942                                         struct cli_state *cli,
5943                                         struct rpc_pipe_client *pipe_hnd,
5944                                         TALLOC_CTX *mem_ctx,
5945                                         int argc,
5946                                         const char **argv)
5947 {
5948         struct policy_handle connect_pol, domain_pol, user_pol;
5949         NTSTATUS status, result;
5950         char *acct_name;
5951         struct dom_sid trust_acct_sid;
5952         struct samr_Ids user_rids, name_types;
5953         struct lsa_String lsa_acct_name;
5954         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
5955
5956         if (argc != 1) {
5957                 d_printf("%s\n%s",
5958                          _("Usage:"),
5959                          _(" net rpc trustdom del <domain_name>\n"));
5960                 return NT_STATUS_INVALID_PARAMETER;
5961         }
5962
5963         /*
5964          * Make valid trusting domain account (ie. uppercased and with '$' appended)
5965          */
5966         acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
5967
5968         if (acct_name == NULL)
5969                 return NT_STATUS_NO_MEMORY;
5970
5971         strupper_m(acct_name);
5972
5973         /* Get samr policy handle */
5974         status = dcerpc_samr_Connect2(b, mem_ctx,
5975                                       pipe_hnd->desthost,
5976                                       MAXIMUM_ALLOWED_ACCESS,
5977                                       &connect_pol,
5978                                       &result);
5979         if (!NT_STATUS_IS_OK(status)) {
5980                 goto done;
5981         }
5982         if (!NT_STATUS_IS_OK(result)) {
5983                 status = result;
5984                 goto done;
5985         }
5986
5987         /* Get domain policy handle */
5988         status = dcerpc_samr_OpenDomain(b, mem_ctx,
5989                                         &connect_pol,
5990                                         MAXIMUM_ALLOWED_ACCESS,
5991                                         discard_const_p(struct dom_sid2, domain_sid),
5992                                         &domain_pol,
5993                                         &result);
5994         if (!NT_STATUS_IS_OK(status)) {
5995                 goto done;
5996         }
5997         if (!NT_STATUS_IS_OK(result)) {
5998                 status = result;
5999                 goto done;
6000         }
6001
6002         init_lsa_String(&lsa_acct_name, acct_name);
6003
6004         status = dcerpc_samr_LookupNames(b, mem_ctx,
6005                                          &domain_pol,
6006                                          1,
6007                                          &lsa_acct_name,
6008                                          &user_rids,
6009                                          &name_types,
6010                                          &result);
6011         if (!NT_STATUS_IS_OK(status)) {
6012                 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6013                            "failed %s\n"),
6014                         acct_name, nt_errstr(status));
6015                 goto done;
6016         }
6017         if (!NT_STATUS_IS_OK(result)) {
6018                 status = result;
6019                 d_printf(_("net rpc trustdom del: LookupNames on user %s "
6020                            "failed %s\n"),
6021                         acct_name, nt_errstr(result) );
6022                 goto done;
6023         }
6024
6025         status = dcerpc_samr_OpenUser(b, mem_ctx,
6026                                       &domain_pol,
6027                                       MAXIMUM_ALLOWED_ACCESS,
6028                                       user_rids.ids[0],
6029                                       &user_pol,
6030                                       &result);
6031         if (!NT_STATUS_IS_OK(status)) {
6032                 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6033                            "%s\n"),
6034                         acct_name, nt_errstr(status) );
6035                 goto done;
6036         }
6037
6038         if (!NT_STATUS_IS_OK(result)) {
6039                 status = result;
6040                 d_printf(_("net rpc trustdom del: OpenUser on user %s failed "
6041                            "%s\n"),
6042                         acct_name, nt_errstr(result) );
6043                 goto done;
6044         }
6045
6046         /* append the rid to the domain sid */
6047         if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
6048                 goto done;
6049         }
6050
6051         /* remove the sid */
6052
6053         status = dcerpc_samr_RemoveMemberFromForeignDomain(b, mem_ctx,
6054                                                            &user_pol,
6055                                                            &trust_acct_sid,
6056                                                            &result);
6057         if (!NT_STATUS_IS_OK(status)) {
6058                 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6059                            " on user %s failed %s\n"),
6060                         acct_name, nt_errstr(status));
6061                 goto done;
6062         }
6063         if (!NT_STATUS_IS_OK(result)) {
6064                 status = result;
6065                 d_printf(_("net rpc trustdom del: RemoveMemberFromForeignDomain"
6066                            " on user %s failed %s\n"),
6067                         acct_name, nt_errstr(result) );
6068                 goto done;
6069         }
6070
6071
6072         /* Delete user */
6073
6074         status = dcerpc_samr_DeleteUser(b, mem_ctx,
6075                                         &user_pol,
6076                                         &result);
6077         if (!NT_STATUS_IS_OK(status)) {
6078                 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6079                            "%s\n"),
6080                         acct_name, nt_errstr(status));
6081                 goto done;
6082         }
6083
6084         if (!NT_STATUS_IS_OK(result)) {
6085                 result = status;
6086                 d_printf(_("net rpc trustdom del: DeleteUser on user %s failed "
6087                            "%s\n"),
6088                         acct_name, nt_errstr(result) );
6089                 goto done;
6090         }
6091
6092         if (!NT_STATUS_IS_OK(result)) {
6093                 d_printf(_("Could not set trust account password: %s\n"),
6094                    nt_errstr(result));
6095                 goto done;
6096         }
6097
6098  done:
6099         return status;
6100 }
6101
6102 /**
6103  * Delete interdomain trust account for a remote domain.
6104  *
6105  * @param argc Standard argc.
6106  * @param argv Standard argv without initial components.
6107  *
6108  * @return Integer status (0 means success).
6109  **/
6110
6111 static int rpc_trustdom_del(struct net_context *c, int argc, const char **argv)
6112 {
6113         if (argc > 0 && !c->display_usage) {
6114                 return run_rpc_command(c, NULL, &ndr_table_samr, 0,
6115                                        rpc_trustdom_del_internals, argc, argv);
6116         } else {
6117                 d_printf("%s\n%s",
6118                          _("Usage:"),
6119                          _("net rpc trustdom del <domain>\n"));
6120                 return -1;
6121         }
6122 }
6123
6124 static NTSTATUS rpc_trustdom_get_pdc(struct net_context *c,
6125                                      struct cli_state *cli,
6126                                      TALLOC_CTX *mem_ctx,
6127                                      const char *domain_name)
6128 {
6129         char *dc_name = NULL;
6130         const char *buffer = NULL;
6131         struct rpc_pipe_client *netr;
6132         NTSTATUS status;
6133         WERROR result;
6134         struct dcerpc_binding_handle *b;
6135
6136         /* Use NetServerEnum2 */
6137
6138         if (cli_get_pdc_name(cli, domain_name, &dc_name)) {
6139                 SAFE_FREE(dc_name);
6140                 return NT_STATUS_OK;
6141         }
6142
6143         DEBUG(1,("NetServerEnum2 error: Couldn't find primary domain controller\
6144                  for domain %s\n", domain_name));
6145
6146         /* Try netr_GetDcName */
6147
6148         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
6149                                           &netr);
6150         if (!NT_STATUS_IS_OK(status)) {
6151                 return status;
6152         }
6153
6154         b = netr->binding_handle;
6155
6156         status = dcerpc_netr_GetDcName(b, mem_ctx,
6157                                        netr->desthost,
6158                                        domain_name,
6159                                        &buffer,
6160                                        &result);
6161         TALLOC_FREE(netr);
6162
6163         if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
6164                 return status;
6165         }
6166
6167         DEBUG(1,("netr_GetDcName error: Couldn't find primary domain controller\
6168                  for domain %s\n", domain_name));
6169
6170         if (!NT_STATUS_IS_OK(status)) {
6171                 return status;
6172         }
6173
6174         return werror_to_ntstatus(result);
6175 }
6176
6177 /**
6178  * Establish trust relationship to a trusting domain.
6179  * Interdomain account must already be created on remote PDC.
6180  *
6181  * @param c    A net_context structure.
6182  * @param argc Standard argc.
6183  * @param argv Standard argv without initial components.
6184  *
6185  * @return Integer status (0 means success).
6186  **/
6187
6188 static int rpc_trustdom_establish(struct net_context *c, int argc,
6189                                   const char **argv)
6190 {
6191         struct cli_state *cli = NULL;
6192         struct sockaddr_storage server_ss;
6193         struct rpc_pipe_client *pipe_hnd = NULL;
6194         struct policy_handle connect_hnd;
6195         TALLOC_CTX *mem_ctx;
6196         NTSTATUS nt_status, result;
6197         struct dom_sid *domain_sid;
6198
6199         char* domain_name;
6200         char* acct_name;
6201         fstring pdc_name;
6202         union lsa_PolicyInformation *info = NULL;
6203         struct dcerpc_binding_handle *b;
6204
6205         /*
6206          * Connect to \\server\ipc$ as 'our domain' account with password
6207          */
6208
6209         if (argc != 1 || c->display_usage) {
6210                 d_printf("%s\n%s",
6211                          _("Usage:"),
6212                          _("net rpc trustdom establish <domain_name>\n"));
6213                 return -1;
6214         }
6215
6216         domain_name = smb_xstrdup(argv[0]);
6217         strupper_m(domain_name);
6218
6219         /* account name used at first is our domain's name with '$' */
6220         if (asprintf(&acct_name, "%s$", lp_workgroup()) == -1) {
6221                 return -1;
6222         }
6223         strupper_m(acct_name);
6224
6225         /*
6226          * opt_workgroup will be used by connection functions further,
6227          * hence it should be set to remote domain name instead of ours
6228          */
6229         if (c->opt_workgroup) {
6230                 c->opt_workgroup = smb_xstrdup(domain_name);
6231         };
6232
6233         c->opt_user_name = acct_name;
6234
6235         /* find the domain controller */
6236         if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
6237                 DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
6238                 return -1;
6239         }
6240
6241         /* connect to ipc$ as username/password */
6242         nt_status = connect_to_ipc(c, &cli, &server_ss, pdc_name);
6243         if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT)) {
6244
6245                 /* Is it trusting domain account for sure ? */
6246                 DEBUG(0, ("Couldn't verify trusting domain account. Error was %s\n",
6247                         nt_errstr(nt_status)));
6248                 return -1;
6249         }
6250
6251         /* store who we connected to */
6252
6253         saf_store( domain_name, pdc_name );
6254
6255         /*
6256          * Connect to \\server\ipc$ again (this time anonymously)
6257          */
6258
6259         nt_status = connect_to_ipc_anonymous(c, &cli, &server_ss,
6260                                              (char*)pdc_name);
6261
6262         if (NT_STATUS_IS_ERR(nt_status)) {
6263                 DEBUG(0, ("Couldn't connect to domain %s controller. Error was %s.\n",
6264                         domain_name, nt_errstr(nt_status)));
6265                 return -1;
6266         }
6267
6268         if (!(mem_ctx = talloc_init("establishing trust relationship to "
6269                                     "domain %s", domain_name))) {
6270                 DEBUG(0, ("talloc_init() failed\n"));
6271                 cli_shutdown(cli);
6272                 return -1;
6273         }
6274
6275         /* Make sure we're talking to a proper server */
6276
6277         nt_status = rpc_trustdom_get_pdc(c, cli, mem_ctx, domain_name);
6278         if (!NT_STATUS_IS_OK(nt_status)) {
6279                 cli_shutdown(cli);
6280                 talloc_destroy(mem_ctx);
6281                 return -1;
6282         }
6283
6284         /*
6285          * Call LsaOpenPolicy and LsaQueryInfo
6286          */
6287
6288         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6289                                              &pipe_hnd);
6290         if (!NT_STATUS_IS_OK(nt_status)) {
6291                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
6292                 cli_shutdown(cli);
6293                 talloc_destroy(mem_ctx);
6294                 return -1;
6295         }
6296
6297         b = pipe_hnd->binding_handle;
6298
6299         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, true, KEY_QUERY_VALUE,
6300                                          &connect_hnd);
6301         if (NT_STATUS_IS_ERR(nt_status)) {
6302                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6303                         nt_errstr(nt_status)));
6304                 cli_shutdown(cli);
6305                 talloc_destroy(mem_ctx);
6306                 return -1;
6307         }
6308
6309         /* Querying info level 5 */
6310
6311         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6312                                                &connect_hnd,
6313                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6314                                                &info,
6315                                                &result);
6316         if (NT_STATUS_IS_ERR(nt_status)) {
6317                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6318                         nt_errstr(nt_status)));
6319                 cli_shutdown(cli);
6320                 talloc_destroy(mem_ctx);
6321                 return -1;
6322         }
6323         if (NT_STATUS_IS_ERR(result)) {
6324                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6325                         nt_errstr(result)));
6326                 cli_shutdown(cli);
6327                 talloc_destroy(mem_ctx);
6328                 return -1;
6329         }
6330
6331         domain_sid = info->account_domain.sid;
6332
6333         /* There should be actually query info level 3 (following nt serv behaviour),
6334            but I still don't know if it's _really_ necessary */
6335
6336         /*
6337          * Store the password in secrets db
6338          */
6339
6340         if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
6341                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6342                 cli_shutdown(cli);
6343                 talloc_destroy(mem_ctx);
6344                 return -1;
6345         }
6346
6347         /*
6348          * Close the pipes and clean up
6349          */
6350
6351         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6352         if (NT_STATUS_IS_ERR(nt_status)) {
6353                 DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
6354                         nt_errstr(nt_status)));
6355                 cli_shutdown(cli);
6356                 talloc_destroy(mem_ctx);
6357                 return -1;
6358         }
6359
6360         cli_shutdown(cli);
6361
6362         talloc_destroy(mem_ctx);
6363
6364         d_printf(_("Trust to domain %s established\n"), domain_name);
6365         return 0;
6366 }
6367
6368 /**
6369  * Revoke trust relationship to the remote domain.
6370  *
6371  * @param c    A net_context structure.
6372  * @param argc Standard argc.
6373  * @param argv Standard argv without initial components.
6374  *
6375  * @return Integer status (0 means success).
6376  **/
6377
6378 static int rpc_trustdom_revoke(struct net_context *c, int argc,
6379                                const char **argv)
6380 {
6381         char* domain_name;
6382         int rc = -1;
6383
6384         if (argc < 1 || c->display_usage) {
6385                 d_printf("%s\n%s",
6386                          _("Usage:"),
6387                          _("net rpc trustdom revoke <domain_name>\n"
6388                            "  Revoke trust relationship\n"
6389                            "    domain_name\tName of domain to revoke trust\n"));
6390                 return -1;
6391         }
6392
6393         /* generate upper cased domain name */
6394         domain_name = smb_xstrdup(argv[0]);
6395         strupper_m(domain_name);
6396
6397         /* delete password of the trust */
6398         if (!pdb_del_trusteddom_pw(domain_name)) {
6399                 DEBUG(0, ("Failed to revoke relationship to the trusted domain %s\n",
6400                           domain_name));
6401                 goto done;
6402         };
6403
6404         rc = 0;
6405 done:
6406         SAFE_FREE(domain_name);
6407         return rc;
6408 }
6409
6410 static NTSTATUS rpc_query_domain_sid(struct net_context *c,
6411                                         const struct dom_sid *domain_sid,
6412                                         const char *domain_name,
6413                                         struct cli_state *cli,
6414                                         struct rpc_pipe_client *pipe_hnd,
6415                                         TALLOC_CTX *mem_ctx,
6416                                         int argc,
6417                                         const char **argv)
6418 {
6419         fstring str_sid;
6420         if (!sid_to_fstring(str_sid, domain_sid)) {
6421                 return NT_STATUS_UNSUCCESSFUL;
6422         }
6423         d_printf("%s\n", str_sid);
6424         return NT_STATUS_OK;
6425 }
6426
6427 static void print_trusted_domain(struct dom_sid *dom_sid, const char *trusted_dom_name)
6428 {
6429         fstring ascii_sid;
6430
6431         /* convert sid into ascii string */
6432         sid_to_fstring(ascii_sid, dom_sid);
6433
6434         d_printf("%-20s%s\n", trusted_dom_name, ascii_sid);
6435 }
6436
6437 static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
6438                                       TALLOC_CTX *mem_ctx,
6439                                       struct policy_handle *pol,
6440                                       struct dom_sid dom_sid,
6441                                       const char *trusted_dom_name)
6442 {
6443         NTSTATUS nt_status, result;
6444         union lsa_TrustedDomainInfo *info = NULL;
6445         char *cleartextpwd = NULL;
6446         DATA_BLOB session_key;
6447         DATA_BLOB data = data_blob_null;
6448         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
6449
6450         nt_status = dcerpc_lsa_QueryTrustedDomainInfoBySid(b, mem_ctx,
6451                                                            pol,
6452                                                            &dom_sid,
6453                                                            LSA_TRUSTED_DOMAIN_INFO_PASSWORD,
6454                                                            &info,
6455                                                            &result);
6456         if (NT_STATUS_IS_ERR(nt_status)) {
6457                 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6458                 nt_errstr(nt_status)));
6459                 goto done;
6460         }
6461         if (NT_STATUS_IS_ERR(result)) {
6462                 nt_status = result;
6463                 DEBUG(0,("Could not query trusted domain info. Error was %s\n",
6464                 nt_errstr(result)));
6465                 goto done;
6466         }
6467
6468         data = data_blob(info->password.password->data,
6469                          info->password.password->length);
6470
6471         nt_status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
6472         if (!NT_STATUS_IS_OK(nt_status)) {
6473                 DEBUG(0, ("Could not retrieve session key: %s\n", nt_errstr(nt_status)));
6474                 goto done;
6475         }
6476
6477         cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key);
6478         data_blob_free(&session_key);
6479
6480         if (cleartextpwd == NULL) {
6481                 DEBUG(0,("retrieved NULL password\n"));
6482                 nt_status = NT_STATUS_UNSUCCESSFUL;
6483                 goto done;
6484         }
6485
6486         if (!pdb_set_trusteddom_pw(trusted_dom_name, cleartextpwd, &dom_sid)) {
6487                 DEBUG(0, ("Storing password for trusted domain failed.\n"));
6488                 nt_status = NT_STATUS_UNSUCCESSFUL;
6489                 goto done;
6490         }
6491
6492 #ifdef DEBUG_PASSWORD
6493         DEBUG(100,("successfully vampired trusted domain [%s], sid: [%s], "
6494                    "password: [%s]\n", trusted_dom_name,
6495                    sid_string_dbg(&dom_sid), cleartextpwd));
6496 #endif
6497
6498 done:
6499         SAFE_FREE(cleartextpwd);
6500         data_blob_free(&data);
6501
6502         return nt_status;
6503 }
6504
6505 static int rpc_trustdom_vampire(struct net_context *c, int argc,
6506                                 const char **argv)
6507 {
6508         /* common variables */
6509         TALLOC_CTX* mem_ctx;
6510         struct cli_state *cli = NULL;
6511         struct rpc_pipe_client *pipe_hnd = NULL;
6512         NTSTATUS nt_status, result;
6513         const char *domain_name = NULL;
6514         struct policy_handle connect_hnd;
6515         union lsa_PolicyInformation *info = NULL;
6516
6517         /* trusted domains listing variables */
6518         unsigned int enum_ctx = 0;
6519         int i;
6520         struct lsa_DomainList dom_list;
6521         fstring pdc_name;
6522         struct dcerpc_binding_handle *b;
6523
6524         if (c->display_usage) {
6525                 d_printf(  "%s\n"
6526                            "net rpc trustdom vampire\n"
6527                            "  %s\n",
6528                          _("Usage:"),
6529                          _("Vampire trust relationship from remote server"));
6530                 return 0;
6531         }
6532
6533         /*
6534          * Listing trusted domains (stored in secrets.tdb, if local)
6535          */
6536
6537         mem_ctx = talloc_init("trust relationships vampire");
6538
6539         /*
6540          * set domain and pdc name to local samba server (default)
6541          * or to remote one given in command line
6542          */
6543
6544         if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
6545                 domain_name = c->opt_workgroup;
6546                 c->opt_target_workgroup = c->opt_workgroup;
6547         } else {
6548                 fstrcpy(pdc_name, lp_netbios_name());
6549                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6550                 c->opt_target_workgroup = domain_name;
6551         };
6552
6553         /* open \PIPE\lsarpc and open policy handle */
6554         nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6555         if (!NT_STATUS_IS_OK(nt_status)) {
6556                 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6557                           nt_errstr(nt_status)));
6558                 talloc_destroy(mem_ctx);
6559                 return -1;
6560         };
6561
6562         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6563                                              &pipe_hnd);
6564         if (!NT_STATUS_IS_OK(nt_status)) {
6565                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6566                         nt_errstr(nt_status) ));
6567                 cli_shutdown(cli);
6568                 talloc_destroy(mem_ctx);
6569                 return -1;
6570         };
6571
6572         b = pipe_hnd->binding_handle;
6573
6574         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6575                                         &connect_hnd);
6576         if (NT_STATUS_IS_ERR(nt_status)) {
6577                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6578                         nt_errstr(nt_status)));
6579                 cli_shutdown(cli);
6580                 talloc_destroy(mem_ctx);
6581                 return -1;
6582         };
6583
6584         /* query info level 5 to obtain sid of a domain being queried */
6585         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6586                                                &connect_hnd,
6587                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6588                                                &info,
6589                                                &result);
6590
6591         if (NT_STATUS_IS_ERR(nt_status)) {
6592                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6593                         nt_errstr(nt_status)));
6594                 cli_shutdown(cli);
6595                 talloc_destroy(mem_ctx);
6596                 return -1;
6597         }
6598         if (NT_STATUS_IS_ERR(result)) {
6599                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6600                         nt_errstr(result)));
6601                 cli_shutdown(cli);
6602                 talloc_destroy(mem_ctx);
6603                 return -1;
6604         }
6605
6606         /*
6607          * Keep calling LsaEnumTrustdom over opened pipe until
6608          * the end of enumeration is reached
6609          */
6610
6611         d_printf(_("Vampire trusted domains:\n\n"));
6612
6613         do {
6614                 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6615                                                     &connect_hnd,
6616                                                     &enum_ctx,
6617                                                     &dom_list,
6618                                                     (uint32_t)-1,
6619                                                     &result);
6620                 if (NT_STATUS_IS_ERR(nt_status)) {
6621                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6622                                 nt_errstr(nt_status)));
6623                         cli_shutdown(cli);
6624                         talloc_destroy(mem_ctx);
6625                         return -1;
6626                 };
6627                 if (NT_STATUS_IS_ERR(result)) {
6628                         nt_status = result;
6629                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6630                                 nt_errstr(result)));
6631                         cli_shutdown(cli);
6632                         talloc_destroy(mem_ctx);
6633                         return -1;
6634                 };
6635
6636
6637                 for (i = 0; i < dom_list.count; i++) {
6638
6639                         print_trusted_domain(dom_list.domains[i].sid,
6640                                              dom_list.domains[i].name.string);
6641
6642                         nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
6643                                                            *dom_list.domains[i].sid,
6644                                                            dom_list.domains[i].name.string);
6645                         if (!NT_STATUS_IS_OK(nt_status)) {
6646                                 cli_shutdown(cli);
6647                                 talloc_destroy(mem_ctx);
6648                                 return -1;
6649                         }
6650                 };
6651
6652                 /*
6653                  * in case of no trusted domains say something rather
6654                  * than just display blank line
6655                  */
6656                 if (!dom_list.count) d_printf(_("none\n"));
6657
6658         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6659
6660         /* close this connection before doing next one */
6661         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6662         if (NT_STATUS_IS_ERR(nt_status)) {
6663                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6664                         nt_errstr(nt_status)));
6665                 cli_shutdown(cli);
6666                 talloc_destroy(mem_ctx);
6667                 return -1;
6668         };
6669
6670         /* close lsarpc pipe and connection to IPC$ */
6671         cli_shutdown(cli);
6672
6673         talloc_destroy(mem_ctx);
6674         return 0;
6675 }
6676
6677 static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
6678 {
6679         /* common variables */
6680         TALLOC_CTX* mem_ctx;
6681         struct cli_state *cli = NULL, *remote_cli = NULL;
6682         struct rpc_pipe_client *pipe_hnd = NULL;
6683         NTSTATUS nt_status, result;
6684         const char *domain_name = NULL;
6685         struct dom_sid *queried_dom_sid;
6686         int ascii_dom_name_len;
6687         struct policy_handle connect_hnd;
6688         union lsa_PolicyInformation *info = NULL;
6689         struct dcerpc_binding_handle *b = NULL;
6690
6691         /* trusted domains listing variables */
6692         unsigned int num_domains, enum_ctx = 0;
6693         int i;
6694         struct lsa_DomainList dom_list;
6695         fstring pdc_name;
6696         bool found_domain;
6697
6698         /* trusting domains listing variables */
6699         struct policy_handle domain_hnd;
6700         struct samr_SamArray *trusts = NULL;
6701
6702         if (c->display_usage) {
6703                 d_printf(  "%s\n"
6704                            "net rpc trustdom list\n"
6705                            "    %s\n",
6706                          _("Usage:"),
6707                          _("List incoming and outgoing trust relationships"));
6708                 return 0;
6709         }
6710
6711         /*
6712          * Listing trusted domains (stored in secrets.tdb, if local)
6713          */
6714
6715         mem_ctx = talloc_init("trust relationships listing");
6716
6717         /*
6718          * set domain and pdc name to local samba server (default)
6719          * or to remote one given in command line
6720          */
6721
6722         if (strcasecmp_m(c->opt_workgroup, lp_workgroup())) {
6723                 domain_name = c->opt_workgroup;
6724                 c->opt_target_workgroup = c->opt_workgroup;
6725         } else {
6726                 fstrcpy(pdc_name, lp_netbios_name());
6727                 domain_name = talloc_strdup(mem_ctx, lp_workgroup());
6728                 c->opt_target_workgroup = domain_name;
6729         };
6730
6731         /* open \PIPE\lsarpc and open policy handle */
6732         nt_status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
6733         if (!NT_STATUS_IS_OK(nt_status)) {
6734                 DEBUG(0, ("Couldn't connect to domain controller: %s\n",
6735                           nt_errstr(nt_status)));
6736                 talloc_destroy(mem_ctx);
6737                 return -1;
6738         };
6739
6740         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
6741                                              &pipe_hnd);
6742         if (!NT_STATUS_IS_OK(nt_status)) {
6743                 DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
6744                         nt_errstr(nt_status) ));
6745                 cli_shutdown(cli);
6746                 talloc_destroy(mem_ctx);
6747                 return -1;
6748         };
6749
6750         b = pipe_hnd->binding_handle;
6751
6752         nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, false, KEY_QUERY_VALUE,
6753                                         &connect_hnd);
6754         if (NT_STATUS_IS_ERR(nt_status)) {
6755                 DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
6756                         nt_errstr(nt_status)));
6757                 cli_shutdown(cli);
6758                 talloc_destroy(mem_ctx);
6759                 return -1;
6760         };
6761
6762         /* query info level 5 to obtain sid of a domain being queried */
6763         nt_status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
6764                                                &connect_hnd,
6765                                                LSA_POLICY_INFO_ACCOUNT_DOMAIN,
6766                                                &info,
6767                                                &result);
6768
6769         if (NT_STATUS_IS_ERR(nt_status)) {
6770                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6771                         nt_errstr(nt_status)));
6772                 cli_shutdown(cli);
6773                 talloc_destroy(mem_ctx);
6774                 return -1;
6775         }
6776         if (NT_STATUS_IS_ERR(result)) {
6777                 DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
6778                         nt_errstr(result)));
6779                 cli_shutdown(cli);
6780                 talloc_destroy(mem_ctx);
6781                 return -1;
6782         }
6783
6784         queried_dom_sid = info->account_domain.sid;
6785
6786         /*
6787          * Keep calling LsaEnumTrustdom over opened pipe until
6788          * the end of enumeration is reached
6789          */
6790
6791         d_printf(_("Trusted domains list:\n\n"));
6792
6793         found_domain = false;
6794
6795         do {
6796                 nt_status = dcerpc_lsa_EnumTrustDom(b, mem_ctx,
6797                                                     &connect_hnd,
6798                                                     &enum_ctx,
6799                                                     &dom_list,
6800                                                     (uint32_t)-1,
6801                                                     &result);
6802                 if (NT_STATUS_IS_ERR(nt_status)) {
6803                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6804                                 nt_errstr(nt_status)));
6805                         cli_shutdown(cli);
6806                         talloc_destroy(mem_ctx);
6807                         return -1;
6808                 };
6809                 if (NT_STATUS_IS_ERR(result)) {
6810                         DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
6811                                 nt_errstr(result)));
6812                         cli_shutdown(cli);
6813                         talloc_destroy(mem_ctx);
6814                         return -1;
6815                 };
6816
6817
6818                 for (i = 0; i < dom_list.count; i++) {
6819                         print_trusted_domain(dom_list.domains[i].sid,
6820                                              dom_list.domains[i].name.string);
6821                         found_domain = true;
6822                 };
6823
6824
6825         } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
6826
6827         /*
6828          * in case of no trusted domains say something rather
6829          * than just display blank line
6830          */
6831         if (!found_domain) {
6832                 d_printf(_("none\n"));
6833         }
6834
6835         /* close this connection before doing next one */
6836         nt_status = dcerpc_lsa_Close(b, mem_ctx, &connect_hnd, &result);
6837         if (NT_STATUS_IS_ERR(nt_status)) {
6838                 DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
6839                         nt_errstr(nt_status)));
6840                 cli_shutdown(cli);
6841                 talloc_destroy(mem_ctx);
6842                 return -1;
6843         };
6844
6845         TALLOC_FREE(pipe_hnd);
6846
6847         /*
6848          * Listing trusting domains (stored in passdb backend, if local)
6849          */
6850
6851         d_printf(_("\nTrusting domains list:\n\n"));
6852
6853         /*
6854          * Open \PIPE\samr and get needed policy handles
6855          */
6856         nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
6857                                              &pipe_hnd);
6858         if (!NT_STATUS_IS_OK(nt_status)) {
6859                 DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
6860                 cli_shutdown(cli);
6861                 talloc_destroy(mem_ctx);
6862                 return -1;
6863         };
6864
6865         b = pipe_hnd->binding_handle;
6866
6867         /* SamrConnect2 */
6868         nt_status = dcerpc_samr_Connect2(b, mem_ctx,
6869                                          pipe_hnd->desthost,
6870                                          SAMR_ACCESS_LOOKUP_DOMAIN,
6871                                          &connect_hnd,
6872                                          &result);
6873         if (!NT_STATUS_IS_OK(nt_status)) {
6874                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6875                         nt_errstr(nt_status)));
6876                 cli_shutdown(cli);
6877                 talloc_destroy(mem_ctx);
6878                 return -1;
6879         };
6880         if (!NT_STATUS_IS_OK(result)) {
6881                 nt_status = result;
6882                 DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
6883                         nt_errstr(result)));
6884                 cli_shutdown(cli);
6885                 talloc_destroy(mem_ctx);
6886                 return -1;
6887         };
6888
6889         /* SamrOpenDomain - we have to open domain policy handle in order to be
6890            able to enumerate accounts*/
6891         nt_status = dcerpc_samr_OpenDomain(b, mem_ctx,
6892                                            &connect_hnd,
6893                                            SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
6894                                            queried_dom_sid,
6895                                            &domain_hnd,
6896                                            &result);
6897         if (!NT_STATUS_IS_OK(nt_status)) {
6898                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6899                         nt_errstr(nt_status)));
6900                 cli_shutdown(cli);
6901                 talloc_destroy(mem_ctx);
6902                 return -1;
6903         };
6904         if (!NT_STATUS_IS_OK(result)) {
6905                 nt_status = result;
6906                 DEBUG(0, ("Couldn't open domain object. Error was %s\n",
6907                         nt_errstr(result)));
6908                 cli_shutdown(cli);
6909                 talloc_destroy(mem_ctx);
6910                 return -1;
6911         };
6912
6913         /*
6914          * perform actual enumeration
6915          */
6916
6917         found_domain = false;
6918
6919         enum_ctx = 0;   /* reset enumeration context from last enumeration */
6920         do {
6921
6922                 nt_status = dcerpc_samr_EnumDomainUsers(b, mem_ctx,
6923                                                         &domain_hnd,
6924                                                         &enum_ctx,
6925                                                         ACB_DOMTRUST,
6926                                                         &trusts,
6927                                                         0xffff,
6928                                                         &num_domains,
6929                                                         &result);
6930                 if (NT_STATUS_IS_ERR(nt_status)) {
6931                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6932                                 nt_errstr(nt_status)));
6933                         cli_shutdown(cli);
6934                         talloc_destroy(mem_ctx);
6935                         return -1;
6936                 };
6937                 if (NT_STATUS_IS_ERR(result)) {
6938                         nt_status = result;
6939                         DEBUG(0, ("Couldn't enumerate accounts. Error was: %s\n",
6940                                 nt_errstr(result)));
6941                         cli_shutdown(cli);
6942                         talloc_destroy(mem_ctx);
6943                         return -1;
6944                 };
6945
6946                 for (i = 0; i < num_domains; i++) {
6947
6948                         char *str = discard_const_p(char, trusts->entries[i].name.string);
6949
6950                         found_domain = true;
6951
6952                         /*
6953                          * get each single domain's sid (do we _really_ need this ?):
6954                          *  1) connect to domain's pdc
6955                          *  2) query the pdc for domain's sid
6956                          */
6957
6958                         /* get rid of '$' tail */
6959                         ascii_dom_name_len = strlen(str);
6960                         if (ascii_dom_name_len && ascii_dom_name_len < FSTRING_LEN)
6961                                 str[ascii_dom_name_len - 1] = '\0';
6962
6963                         /* set opt_* variables to remote domain */
6964                         strupper_m(str);
6965                         c->opt_workgroup = talloc_strdup(mem_ctx, str);
6966                         c->opt_target_workgroup = c->opt_workgroup;
6967
6968                         d_printf("%-20s", str);
6969
6970                         /* connect to remote domain controller */
6971                         nt_status = net_make_ipc_connection(c,
6972                                         NET_FLAGS_PDC | NET_FLAGS_ANONYMOUS,
6973                                         &remote_cli);
6974                         if (NT_STATUS_IS_OK(nt_status)) {
6975                                 /* query for domain's sid */
6976                                 if (run_rpc_command(
6977                                             c, remote_cli,
6978                                             &ndr_table_lsarpc, 0,
6979                                             rpc_query_domain_sid, argc,
6980                                             argv))
6981                                         d_printf(_("strange - couldn't get domain's sid\n"));
6982
6983                                 cli_shutdown(remote_cli);
6984
6985                         } else {
6986                                 d_fprintf(stderr, _("domain controller is not "
6987                                           "responding: %s\n"),
6988                                           nt_errstr(nt_status));
6989                                 d_printf(_("couldn't get domain's sid\n"));
6990                         }
6991                 }
6992
6993         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
6994
6995         if (!found_domain) {
6996                 d_printf("none\n");
6997         }
6998
6999         /* close opened samr and domain policy handles */
7000         nt_status = dcerpc_samr_Close(b, mem_ctx, &domain_hnd, &result);
7001         if (!NT_STATUS_IS_OK(nt_status)) {
7002                 DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
7003         };
7004
7005         nt_status = dcerpc_samr_Close(b, mem_ctx, &connect_hnd, &result);
7006         if (!NT_STATUS_IS_OK(nt_status)) {
7007                 DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
7008         };
7009
7010         /* close samr pipe and connection to IPC$ */
7011         cli_shutdown(cli);
7012
7013         talloc_destroy(mem_ctx);
7014         return 0;
7015 }
7016
7017 /**
7018  * Entrypoint for 'net rpc trustdom' code.
7019  *
7020  * @param argc Standard argc.
7021  * @param argv Standard argv without initial components.
7022  *
7023  * @return Integer status (0 means success).
7024  */
7025
7026 static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
7027 {
7028         struct functable func[] = {
7029                 {
7030                         "add",
7031                         rpc_trustdom_add,
7032                         NET_TRANSPORT_RPC,
7033                         N_("Add trusting domain's account"),
7034                         N_("net rpc trustdom add\n"
7035                            "    Add trusting domain's account")
7036                 },
7037                 {
7038                         "del",
7039                         rpc_trustdom_del,
7040                         NET_TRANSPORT_RPC,
7041                         N_("Remove trusting domain's account"),
7042                         N_("net rpc trustdom del\n"
7043                            "    Remove trusting domain's account")
7044                 },
7045                 {
7046                         "establish",
7047                         rpc_trustdom_establish,
7048                         NET_TRANSPORT_RPC,
7049                         N_("Establish outgoing trust relationship"),
7050                         N_("net rpc trustdom establish\n"
7051                            "    Establish outgoing trust relationship")
7052                 },
7053                 {
7054                         "revoke",
7055                         rpc_trustdom_revoke,
7056                         NET_TRANSPORT_RPC,
7057                         N_("Revoke outgoing trust relationship"),
7058                         N_("net rpc trustdom revoke\n"
7059                            "    Revoke outgoing trust relationship")
7060                 },
7061                 {
7062                         "list",
7063                         rpc_trustdom_list,
7064                         NET_TRANSPORT_RPC,
7065                         N_("List in- and outgoing domain trusts"),
7066                         N_("net rpc trustdom list\n"
7067                            "    List in- and outgoing domain trusts")
7068                 },
7069                 {
7070                         "vampire",
7071                         rpc_trustdom_vampire,
7072                         NET_TRANSPORT_RPC,
7073                         N_("Vampire trusts from remote server"),
7074                         N_("net rpc trustdom vampire\n"
7075                            "    Vampire trusts from remote server")
7076                 },
7077                 {NULL, NULL, 0, NULL, NULL}
7078         };
7079
7080         return net_run_function(c, argc, argv, "net rpc trustdom", func);
7081 }
7082
7083 /**
7084  * Check if a server will take rpc commands
7085  * @param flags Type of server to connect to (PDC, DMB, localhost)
7086  *              if the host is not explicitly specified
7087  * @return  bool (true means rpc supported)
7088  */
7089 bool net_rpc_check(struct net_context *c, unsigned flags)
7090 {
7091         struct cli_state *cli;
7092         bool ret = false;
7093         struct sockaddr_storage server_ss;
7094         char *server_name = NULL;
7095         NTSTATUS status;
7096
7097         /* flags (i.e. server type) may depend on command */
7098         if (!net_find_server(c, NULL, flags, &server_ss, &server_name))
7099                 return false;
7100
7101         status = cli_connect_nb(server_name, &server_ss, 0, 0x20,
7102                                 lp_netbios_name(), SMB_SIGNING_DEFAULT,
7103                                 0, &cli);
7104         if (!NT_STATUS_IS_OK(status)) {
7105                 return false;
7106         }
7107         status = cli_negprot(cli, PROTOCOL_NT1);
7108         if (!NT_STATUS_IS_OK(status))
7109                 goto done;
7110         if (cli_state_protocol(cli) < PROTOCOL_NT1)
7111                 goto done;
7112
7113         ret = true;
7114  done:
7115         cli_shutdown(cli);
7116         return ret;
7117 }
7118
7119 /* dump sam database via samsync rpc calls */
7120 static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
7121         if (c->display_usage) {
7122                 d_printf(  "%s\n"
7123                            "net rpc samdump\n"
7124                            "    %s\n",
7125                          _("Usage:"),
7126                          _("Dump remote SAM database"));
7127                 return 0;
7128         }
7129
7130         return run_rpc_command(c, NULL, &ndr_table_netlogon,
7131                                NET_FLAGS_ANONYMOUS,
7132                                rpc_samdump_internals, argc, argv);
7133 }
7134
7135 /* syncronise sam database via samsync rpc calls */
7136 static int rpc_vampire(struct net_context *c, int argc, const char **argv)
7137 {
7138         struct functable func[] = {
7139                 {
7140                         "ldif",
7141                         rpc_vampire_ldif,
7142                         NET_TRANSPORT_RPC,
7143                         N_("Dump remote SAM database to ldif"),
7144                         N_("net rpc vampire ldif\n"
7145                            "    Dump remote SAM database to LDIF file or "
7146                            "stdout")
7147                 },
7148                 {
7149                         "keytab",
7150                         rpc_vampire_keytab,
7151                         NET_TRANSPORT_RPC,
7152                         N_("Dump remote SAM database to Kerberos Keytab"),
7153                         N_("net rpc vampire keytab\n"
7154                            "    Dump remote SAM database to Kerberos keytab "
7155                            "file")
7156                 },
7157                 {
7158                         "passdb",
7159                         rpc_vampire_passdb,
7160                         NET_TRANSPORT_RPC,
7161                         N_("Dump remote SAM database to passdb"),
7162                         N_("net rpc vampire passdb\n"
7163                            "    Dump remote SAM database to passdb")
7164                 },
7165
7166                 {NULL, NULL, 0, NULL, NULL}
7167         };
7168
7169         if (argc == 0) {
7170                 if (c->display_usage) {
7171                         d_printf(  "%s\n"
7172                                    "net rpc vampire\n"
7173                                    "    %s\n",
7174                                  _("Usage:"),
7175                                  _("Vampire remote SAM database"));
7176                         return 0;
7177                 }
7178
7179                 return rpc_vampire_passdb(c, argc, argv);
7180         }
7181
7182         return net_run_function(c, argc, argv, "net rpc vampire", func);
7183 }
7184
7185 /**
7186  * Migrate everything from a print server.
7187  *
7188  * @param c     A net_context structure.
7189  * @param argc  Standard main() style argc.
7190  * @param argv  Standard main() style argv. Initial components are already
7191  *              stripped.
7192  *
7193  * @return A shell status integer (0 for success).
7194  *
7195  * The order is important !
7196  * To successfully add drivers the print queues have to exist !
7197  * Applying ACLs should be the last step, because you're easily locked out.
7198  *
7199  **/
7200 static int rpc_printer_migrate_all(struct net_context *c, int argc,
7201                                    const char **argv)
7202 {
7203         int ret;
7204
7205         if (c->display_usage) {
7206                 d_printf(  "%s\n"
7207                            "net rpc printer migrate all\n"
7208                            "    %s\n",
7209                          _("Usage:"),
7210                          _("Migrate everything from a print server"));
7211                 return 0;
7212         }
7213
7214         if (!c->opt_host) {
7215                 d_printf(_("no server to migrate\n"));
7216                 return -1;
7217         }
7218
7219         ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7220                               rpc_printer_migrate_printers_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_drivers_internals, argc,
7227                               argv);
7228         if (ret)
7229                 return ret;
7230
7231         ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7232                               rpc_printer_migrate_forms_internals, argc, argv);
7233         if (ret)
7234                 return ret;
7235
7236         ret = run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7237                               rpc_printer_migrate_settings_internals, argc,
7238                               argv);
7239         if (ret)
7240                 return ret;
7241
7242         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7243                                rpc_printer_migrate_security_internals, argc,
7244                                argv);
7245
7246 }
7247
7248 /**
7249  * Migrate print drivers from a print server.
7250  *
7251  * @param c     A net_context structure.
7252  * @param argc  Standard main() style argc.
7253  * @param argv  Standard main() style argv. Initial components are already
7254  *              stripped.
7255  *
7256  * @return A shell status integer (0 for success).
7257  **/
7258 static int rpc_printer_migrate_drivers(struct net_context *c, int argc,
7259                                        const char **argv)
7260 {
7261         if (c->display_usage) {
7262                 d_printf(  "%s\n"
7263                            "net rpc printer migrate drivers\n"
7264                            "     %s\n",
7265                          _("Usage:"),
7266                          _("Migrate print-drivers from a print-server"));
7267                 return 0;
7268         }
7269
7270         if (!c->opt_host) {
7271                 d_printf(_("no server to migrate\n"));
7272                 return -1;
7273         }
7274
7275         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7276                                rpc_printer_migrate_drivers_internals,
7277                                argc, argv);
7278 }
7279
7280 /**
7281  * Migrate print-forms from a print-server.
7282  *
7283  * @param c     A net_context structure.
7284  * @param argc  Standard main() style argc.
7285  * @param argv  Standard main() style argv. Initial components are already
7286  *              stripped.
7287  *
7288  * @return A shell status integer (0 for success).
7289  **/
7290 static int rpc_printer_migrate_forms(struct net_context *c, int argc,
7291                                      const char **argv)
7292 {
7293         if (c->display_usage) {
7294                 d_printf(  "%s\n"
7295                            "net rpc printer migrate forms\n"
7296                            "    %s\n",
7297                          _("Usage:"),
7298                          _("Migrate print-forms from a print-server"));
7299                 return 0;
7300         }
7301
7302         if (!c->opt_host) {
7303                 d_printf(_("no server to migrate\n"));
7304                 return -1;
7305         }
7306
7307         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7308                                rpc_printer_migrate_forms_internals,
7309                                argc, argv);
7310 }
7311
7312 /**
7313  * Migrate printers from a print-server.
7314  *
7315  * @param c     A net_context structure.
7316  * @param argc  Standard main() style argc.
7317  * @param argv  Standard main() style argv. Initial components are already
7318  *              stripped.
7319  *
7320  * @return A shell status integer (0 for success).
7321  **/
7322 static int rpc_printer_migrate_printers(struct net_context *c, int argc,
7323                                         const char **argv)
7324 {
7325         if (c->display_usage) {
7326                 d_printf(  "%s\n"
7327                            "net rpc printer migrate printers\n"
7328                            "    %s\n",
7329                          _("Usage:"),
7330                          _("Migrate printers from a print-server"));
7331                 return 0;
7332         }
7333
7334         if (!c->opt_host) {
7335                 d_printf(_("no server to migrate\n"));
7336                 return -1;
7337         }
7338
7339         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7340                                rpc_printer_migrate_printers_internals,
7341                                argc, argv);
7342 }
7343
7344 /**
7345  * Migrate printer-ACLs from a print-server
7346  *
7347  * @param c     A net_context structure.
7348  * @param argc  Standard main() style argc.
7349  * @param argv  Standard main() style argv. Initial components are already
7350  *              stripped.
7351  *
7352  * @return A shell status integer (0 for success).
7353  **/
7354 static int rpc_printer_migrate_security(struct net_context *c, int argc,
7355                                         const char **argv)
7356 {
7357         if (c->display_usage) {
7358                 d_printf(  "%s\n"
7359                            "net rpc printer migrate security\n"
7360                            "    %s\n",
7361                          _("Usage:"),
7362                          _("Migrate printer-ACLs from a print-server"));
7363                 return 0;
7364         }
7365
7366         if (!c->opt_host) {
7367                 d_printf(_("no server to migrate\n"));
7368                 return -1;
7369         }
7370
7371         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7372                                rpc_printer_migrate_security_internals,
7373                                argc, argv);
7374 }
7375
7376 /**
7377  * Migrate printer-settings from a print-server.
7378  *
7379  * @param c     A net_context structure.
7380  * @param argc  Standard main() style argc.
7381  * @param argv  Standard main() style argv. Initial components are already
7382  *              stripped.
7383  *
7384  * @return A shell status integer (0 for success).
7385  **/
7386 static int rpc_printer_migrate_settings(struct net_context *c, int argc,
7387                                         const char **argv)
7388 {
7389         if (c->display_usage) {
7390                 d_printf(  "%s\n"
7391                            "net rpc printer migrate settings\n"
7392                             "    %s\n",
7393                           _("Usage:"),
7394                           _("Migrate printer-settings from a "
7395                             "print-server"));
7396                 return 0;
7397         }
7398
7399         if (!c->opt_host) {
7400                 d_printf(_("no server to migrate\n"));
7401                 return -1;
7402         }
7403
7404         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7405                                rpc_printer_migrate_settings_internals,
7406                                argc, argv);
7407 }
7408
7409 /**
7410  * 'net rpc printer' entrypoint.
7411  *
7412  * @param c     A net_context structure.
7413  * @param argc  Standard main() style argc.
7414  * @param argv  Standard main() style argv. Initial components are already
7415  *              stripped.
7416  **/
7417
7418 int rpc_printer_migrate(struct net_context *c, int argc, const char **argv)
7419 {
7420
7421         /* ouch: when addriver and setdriver are called from within
7422            rpc_printer_migrate_drivers_internals, the printer-queue already
7423            *has* to exist */
7424
7425         struct functable func[] = {
7426                 {
7427                         "all",
7428                         rpc_printer_migrate_all,
7429                         NET_TRANSPORT_RPC,
7430                         N_("Migrate all from remote to local print server"),
7431                         N_("net rpc printer migrate all\n"
7432                            "    Migrate all from remote to local print server")
7433                 },
7434                 {
7435                         "drivers",
7436                         rpc_printer_migrate_drivers,
7437                         NET_TRANSPORT_RPC,
7438                         N_("Migrate drivers to local server"),
7439                         N_("net rpc printer migrate drivers\n"
7440                            "    Migrate drivers to local server")
7441                 },
7442                 {
7443                         "forms",
7444                         rpc_printer_migrate_forms,
7445                         NET_TRANSPORT_RPC,
7446                         N_("Migrate froms to local server"),
7447                         N_("net rpc printer migrate forms\n"
7448                            "    Migrate froms to local server")
7449                 },
7450                 {
7451                         "printers",
7452                         rpc_printer_migrate_printers,
7453                         NET_TRANSPORT_RPC,
7454                         N_("Migrate printers to local server"),
7455                         N_("net rpc printer migrate printers\n"
7456                            "    Migrate printers to local server")
7457                 },
7458                 {
7459                         "security",
7460                         rpc_printer_migrate_security,
7461                         NET_TRANSPORT_RPC,
7462                         N_("Mirgate printer ACLs to local server"),
7463                         N_("net rpc printer migrate security\n"
7464                            "    Mirgate printer ACLs to local server")
7465                 },
7466                 {
7467                         "settings",
7468                         rpc_printer_migrate_settings,
7469                         NET_TRANSPORT_RPC,
7470                         N_("Migrate printer settings to local server"),
7471                         N_("net rpc printer migrate settings\n"
7472                            "    Migrate printer settings to local server")
7473                 },
7474                 {NULL, NULL, 0, NULL, NULL}
7475         };
7476
7477         return net_run_function(c, argc, argv, "net rpc printer migrate",func);
7478 }
7479
7480
7481 /**
7482  * List printers on a remote RPC server.
7483  *
7484  * @param c     A net_context structure.
7485  * @param argc  Standard main() style argc.
7486  * @param argv  Standard main() style argv. Initial components are already
7487  *              stripped.
7488  *
7489  * @return A shell status integer (0 for success).
7490  **/
7491 static int rpc_printer_list(struct net_context *c, int argc, const char **argv)
7492 {
7493         if (c->display_usage) {
7494                 d_printf(  "%s\n"
7495                            "net rpc printer list\n"
7496                            "    %s\n",
7497                          _("Usage:"),
7498                          _("List printers on a remote RPC server"));
7499                 return 0;
7500         }
7501
7502         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7503                                rpc_printer_list_internals,
7504                                argc, argv);
7505 }
7506
7507 /**
7508  * List printer-drivers on a remote RPC server.
7509  *
7510  * @param c     A net_context structure.
7511  * @param argc  Standard main() style argc.
7512  * @param argv  Standard main() style argv. Initial components are already
7513  *              stripped.
7514  *
7515  * @return A shell status integer (0 for success).
7516  **/
7517 static int rpc_printer_driver_list(struct net_context *c, int argc,
7518                                    const char **argv)
7519 {
7520         if (c->display_usage) {
7521                 d_printf(  "%s\n"
7522                            "net rpc printer driver\n"
7523                            "    %s\n",
7524                          _("Usage:"),
7525                          _("List printer-drivers on a remote RPC server"));
7526                 return 0;
7527         }
7528
7529         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7530                                rpc_printer_driver_list_internals,
7531                                argc, argv);
7532 }
7533
7534 /**
7535  * Publish printer in ADS via MSRPC.
7536  *
7537  * @param c     A net_context structure.
7538  * @param argc  Standard main() style argc.
7539  * @param argv  Standard main() style argv. Initial components are already
7540  *              stripped.
7541  *
7542  * @return A shell status integer (0 for success).
7543  **/
7544 static int rpc_printer_publish_publish(struct net_context *c, int argc,
7545                                        const char **argv)
7546 {
7547         if (c->display_usage) {
7548                 d_printf(  "%s\n"
7549                            "net rpc printer publish publish\n"
7550                            "     %s\n",
7551                          _("Usage:"),
7552                          _("Publish printer in ADS via MSRPC"));
7553                 return 0;
7554         }
7555
7556         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7557                                rpc_printer_publish_publish_internals,
7558                                argc, argv);
7559 }
7560
7561 /**
7562  * Update printer in ADS via MSRPC.
7563  *
7564  * @param c     A net_context structure.
7565  * @param argc  Standard main() style argc.
7566  * @param argv  Standard main() style argv. Initial components are already
7567  *              stripped.
7568  *
7569  * @return A shell status integer (0 for success).
7570  **/
7571 static int rpc_printer_publish_update(struct net_context *c, int argc, const char **argv)
7572 {
7573         if (c->display_usage) {
7574                 d_printf(  "%s\n"
7575                            "net rpc printer publish update\n"
7576                            "    %s\n",
7577                          _("Usage:"),
7578                          _("Update printer in ADS via MSRPC"));
7579                 return 0;
7580         }
7581
7582         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7583                                rpc_printer_publish_update_internals,
7584                                argc, argv);
7585 }
7586
7587 /**
7588  * UnPublish printer in ADS via MSRPC.
7589  *
7590  * @param c     A net_context structure.
7591  * @param argc  Standard main() style argc.
7592  * @param argv  Standard main() style argv. Initial components are already
7593  *              stripped.
7594  *
7595  * @return A shell status integer (0 for success).
7596  **/
7597 static int rpc_printer_publish_unpublish(struct net_context *c, int argc,
7598                                          const char **argv)
7599 {
7600         if (c->display_usage) {
7601                 d_printf(  "%s\n"
7602                            "net rpc printer publish unpublish\n"
7603                            "    %s\n",
7604                          _("Usage:\n"),
7605                          _("UnPublish printer in ADS via MSRPC"));
7606                 return 0;
7607         }
7608
7609         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7610                                rpc_printer_publish_unpublish_internals,
7611                                argc, argv);
7612 }
7613
7614 /**
7615  * List published printers via MSRPC.
7616  *
7617  * @param c     A net_context structure.
7618  * @param argc  Standard main() style argc.
7619  * @param argv  Standard main() style argv. Initial components are already
7620  *              stripped.
7621  *
7622  * @return A shell status integer (0 for success).
7623  **/
7624 static int rpc_printer_publish_list(struct net_context *c, int argc,
7625                                     const char **argv)
7626 {
7627         if (c->display_usage) {
7628                 d_printf(  "%s\n"
7629                            "net rpc printer publish list\n"
7630                            "    %s\n",
7631                          _("Usage:"),
7632                          _("List published printers via MSRPC"));
7633                 return 0;
7634         }
7635
7636         return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7637                                rpc_printer_publish_list_internals,
7638                                argc, argv);
7639 }
7640
7641
7642 /**
7643  * Publish printer in ADS.
7644  *
7645  * @param c     A net_context structure.
7646  * @param argc  Standard main() style argc.
7647  * @param argv  Standard main() style argv. Initial components are already
7648  *              stripped.
7649  *
7650  * @return A shell status integer (0 for success).
7651  **/
7652 static int rpc_printer_publish(struct net_context *c, int argc,
7653                                const char **argv)
7654 {
7655
7656         struct functable func[] = {
7657                 {
7658                         "publish",
7659                         rpc_printer_publish_publish,
7660                         NET_TRANSPORT_RPC,
7661                         N_("Publish printer in AD"),
7662                         N_("net rpc printer publish publish\n"
7663                            "    Publish printer in AD")
7664                 },
7665                 {
7666                         "update",
7667                         rpc_printer_publish_update,
7668                         NET_TRANSPORT_RPC,
7669                         N_("Update printer in AD"),
7670                         N_("net rpc printer publish update\n"
7671                            "    Update printer in AD")
7672                 },
7673                 {
7674                         "unpublish",
7675                         rpc_printer_publish_unpublish,
7676                         NET_TRANSPORT_RPC,
7677                         N_("Unpublish printer"),
7678                         N_("net rpc printer publish unpublish\n"
7679                            "    Unpublish printer")
7680                 },
7681                 {
7682                         "list",
7683                         rpc_printer_publish_list,
7684                         NET_TRANSPORT_RPC,
7685                         N_("List published printers"),
7686                         N_("net rpc printer publish list\n"
7687                            "    List published printers")
7688                 },
7689                 {NULL, NULL, 0, NULL, NULL}
7690         };
7691
7692         if (argc == 0) {
7693                 if (c->display_usage) {
7694                         d_printf(_("Usage:\n"));
7695                         d_printf(_("net rpc printer publish\n"
7696                                    "    List published printers\n"
7697                                    "    Alias of net rpc printer publish "
7698                                    "list\n"));
7699                         net_display_usage_from_functable(func);
7700                         return 0;
7701                 }
7702                 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7703                                rpc_printer_publish_list_internals,
7704                                argc, argv);
7705         }
7706
7707         return net_run_function(c, argc, argv, "net rpc printer publish",func);
7708
7709 }
7710
7711
7712 /**
7713  * Display rpc printer help page.
7714  *
7715  * @param c     A net_context structure.
7716  * @param argc  Standard main() style argc.
7717  * @param argv  Standard main() style argv. Initial components are already
7718  *              stripped.
7719  **/
7720 int rpc_printer_usage(struct net_context *c, int argc, const char **argv)
7721 {
7722         d_printf(_("net rpc printer LIST [printer] [misc. options] [targets]\n"
7723                    "\tlists all printers on print-server\n\n"));
7724         d_printf(_("net rpc printer DRIVER [printer] [misc. options] [targets]\n"
7725                    "\tlists all printer-drivers on print-server\n\n"));
7726         d_printf(_("net rpc printer PUBLISH action [printer] [misc. options] [targets]\n"
7727                    "\tpublishes printer settings in Active Directory\n"
7728                    "\taction can be one of PUBLISH, UPDATE, UNPUBLISH or LIST\n\n"));
7729         d_printf(_("net rpc printer MIGRATE PRINTERS [printer] [misc. options] [targets]"
7730                    "\n\tmigrates printers from remote to local server\n\n"));
7731         d_printf(_("net rpc printer MIGRATE SETTINGS [printer] [misc. options] [targets]"
7732                    "\n\tmigrates printer-settings from remote to local server\n\n"));
7733         d_printf(_("net rpc printer MIGRATE DRIVERS [printer] [misc. options] [targets]"
7734                    "\n\tmigrates printer-drivers from remote to local server\n\n"));
7735         d_printf(_("net rpc printer MIGRATE FORMS [printer] [misc. options] [targets]"
7736                    "\n\tmigrates printer-forms from remote to local server\n\n"));
7737         d_printf(_("net rpc printer MIGRATE SECURITY [printer] [misc. options] [targets]"
7738                    "\n\tmigrates printer-ACLs from remote to local server\n\n"));
7739         d_printf(_("net rpc printer MIGRATE ALL [printer] [misc. options] [targets]"
7740                    "\n\tmigrates drivers, forms, queues, settings and acls from\n"
7741                    "\tremote to local print-server\n\n"));
7742         net_common_methods_usage(c, argc, argv);
7743         net_common_flags_usage(c, argc, argv);
7744         d_printf(_(
7745          "\t-v or --verbose\t\t\tgive verbose output\n"
7746          "\t      --destination\t\tmigration target server (default: localhost)\n"));
7747
7748         return -1;
7749 }
7750
7751 /**
7752  * 'net rpc printer' entrypoint.
7753  *
7754  * @param c     A net_context structure.
7755  * @param argc  Standard main() style argc.
7756  * @param argv  Standard main() style argv. Initial components are already
7757  *              stripped.
7758  **/
7759 int net_rpc_printer(struct net_context *c, int argc, const char **argv)
7760 {
7761         struct functable func[] = {
7762                 {
7763                         "list",
7764                         rpc_printer_list,
7765                         NET_TRANSPORT_RPC,
7766                         N_("List all printers on print server"),
7767                         N_("net rpc printer list\n"
7768                            "    List all printers on print server")
7769                 },
7770                 {
7771                         "migrate",
7772                         rpc_printer_migrate,
7773                         NET_TRANSPORT_RPC,
7774                         N_("Migrate printer to local server"),
7775                         N_("net rpc printer migrate\n"
7776                            "    Migrate printer to local server")
7777                 },
7778                 {
7779                         "driver",
7780                         rpc_printer_driver_list,
7781                         NET_TRANSPORT_RPC,
7782                         N_("List printer drivers"),
7783                         N_("net rpc printer driver\n"
7784                            "    List printer drivers")
7785                 },
7786                 {
7787                         "publish",
7788                         rpc_printer_publish,
7789                         NET_TRANSPORT_RPC,
7790                         N_("Publish printer in AD"),
7791                         N_("net rpc printer publish\n"
7792                            "    Publish printer in AD")
7793                 },
7794                 {NULL, NULL, 0, NULL, NULL}
7795         };
7796
7797         if (argc == 0) {
7798                 if (c->display_usage) {
7799                         d_printf(_("Usage:\n"));
7800                         d_printf(_("net rpc printer\n"
7801                                    "    List printers\n"));
7802                         net_display_usage_from_functable(func);
7803                         return 0;
7804                 }
7805                 return run_rpc_command(c, NULL, &ndr_table_spoolss, 0,
7806                                rpc_printer_list_internals,
7807                                argc, argv);
7808         }
7809
7810         return net_run_function(c, argc, argv, "net rpc printer", func);
7811 }
7812
7813 /**
7814  * 'net rpc' entrypoint.
7815  *
7816  * @param c     A net_context structure.
7817  * @param argc  Standard main() style argc.
7818  * @param argv  Standard main() style argv. Initial components are already
7819  *              stripped.
7820  **/
7821
7822 int net_rpc(struct net_context *c, int argc, const char **argv)
7823 {
7824         NET_API_STATUS status;
7825
7826         struct functable func[] = {
7827                 {
7828                         "audit",
7829                         net_rpc_audit,
7830                         NET_TRANSPORT_RPC,
7831                         N_("Modify global audit settings"),
7832                         N_("net rpc audit\n"
7833                            "    Modify global audit settings")
7834                 },
7835                 {
7836                         "info",
7837                         net_rpc_info,
7838                         NET_TRANSPORT_RPC,
7839                         N_("Show basic info about a domain"),
7840                         N_("net rpc info\n"
7841                            "    Show basic info about a domain")
7842                 },
7843                 {
7844                         "join",
7845                         net_rpc_join,
7846                         NET_TRANSPORT_RPC,
7847                         N_("Join a domain"),
7848                         N_("net rpc join\n"
7849                            "    Join a domain")
7850                 },
7851                 {
7852                         "oldjoin",
7853                         net_rpc_oldjoin,
7854                         NET_TRANSPORT_RPC,
7855                         N_("Join a domain created in server manager"),
7856                         N_("net rpc oldjoin\n"
7857                            "    Join a domain created in server manager")
7858                 },
7859                 {
7860                         "testjoin",
7861                         net_rpc_testjoin,
7862                         NET_TRANSPORT_RPC,
7863                         N_("Test that a join is valid"),
7864                         N_("net rpc testjoin\n"
7865                            "    Test that a join is valid")
7866                 },
7867                 {
7868                         "user",
7869                         net_rpc_user,
7870                         NET_TRANSPORT_RPC,
7871                         N_("List/modify users"),
7872                         N_("net rpc user\n"
7873                            "    List/modify users")
7874                 },
7875                 {
7876                         "password",
7877                         rpc_user_password,
7878                         NET_TRANSPORT_RPC,
7879                         N_("Change a user password"),
7880                         N_("net rpc password\n"
7881                            "    Change a user password\n"
7882                            "    Alias for net rpc user password")
7883                 },
7884                 {
7885                         "group",
7886                         net_rpc_group,
7887                         NET_TRANSPORT_RPC,
7888                         N_("List/modify groups"),
7889                         N_("net rpc group\n"
7890                            "    List/modify groups")
7891                 },
7892                 {
7893                         "share",
7894                         net_rpc_share,
7895                         NET_TRANSPORT_RPC,
7896                         N_("List/modify shares"),
7897                         N_("net rpc share\n"
7898                            "    List/modify shares")
7899                 },
7900                 {
7901                         "file",
7902                         net_rpc_file,
7903                         NET_TRANSPORT_RPC,
7904                         N_("List open files"),
7905                         N_("net rpc file\n"
7906                            "    List open files")
7907                 },
7908                 {
7909                         "printer",
7910                         net_rpc_printer,
7911                         NET_TRANSPORT_RPC,
7912                         N_("List/modify printers"),
7913                         N_("net rpc printer\n"
7914                            "    List/modify printers")
7915                 },
7916                 {
7917                         "changetrustpw",
7918                         net_rpc_changetrustpw,
7919                         NET_TRANSPORT_RPC,
7920                         N_("Change trust account password"),
7921                         N_("net rpc changetrustpw\n"
7922                            "    Change trust account password")
7923                 },
7924                 {
7925                         "trustdom",
7926                         rpc_trustdom,
7927                         NET_TRANSPORT_RPC,
7928                         N_("Modify domain trusts"),
7929                         N_("net rpc trustdom\n"
7930                            "    Modify domain trusts")
7931                 },
7932                 {
7933                         "abortshutdown",
7934                         rpc_shutdown_abort,
7935                         NET_TRANSPORT_RPC,
7936                         N_("Abort a remote shutdown"),
7937                         N_("net rpc abortshutdown\n"
7938                            "    Abort a remote shutdown")
7939                 },
7940                 {
7941                         "shutdown",
7942                         rpc_shutdown,
7943                         NET_TRANSPORT_RPC,
7944                         N_("Shutdown a remote server"),
7945                         N_("net rpc shutdown\n"
7946                            "    Shutdown a remote server")
7947                 },
7948                 {
7949                         "samdump",
7950                         rpc_samdump,
7951                         NET_TRANSPORT_RPC,
7952                         N_("Dump SAM data of remote NT PDC"),
7953                         N_("net rpc samdump\n"
7954                            "    Dump SAM data of remote NT PDC")
7955                 },
7956                 {
7957                         "vampire",
7958                         rpc_vampire,
7959                         NET_TRANSPORT_RPC,
7960                         N_("Sync a remote NT PDC's data into local passdb"),
7961                         N_("net rpc vampire\n"
7962                            "    Sync a remote NT PDC's data into local passdb")
7963                 },
7964                 {
7965                         "getsid",
7966                         net_rpc_getsid,
7967                         NET_TRANSPORT_RPC,
7968                         N_("Fetch the domain sid into local secrets.tdb"),
7969                         N_("net rpc getsid\n"
7970                            "    Fetch the domain sid into local secrets.tdb")
7971                 },
7972                 {
7973                         "rights",
7974                         net_rpc_rights,
7975                         NET_TRANSPORT_RPC,
7976                         N_("Manage privileges assigned to SID"),
7977                         N_("net rpc rights\n"
7978                            "    Manage privileges assigned to SID")
7979                 },
7980                 {
7981                         "service",
7982                         net_rpc_service,
7983                         NET_TRANSPORT_RPC,
7984                         N_("Start/stop/query remote services"),
7985                         N_("net rpc service\n"
7986                            "    Start/stop/query remote services")
7987                 },
7988                 {
7989                         "registry",
7990                         net_rpc_registry,
7991                         NET_TRANSPORT_RPC,
7992                         N_("Manage registry hives"),
7993                         N_("net rpc registry\n"
7994                            "    Manage registry hives")
7995                 },
7996                 {
7997                         "shell",
7998                         net_rpc_shell,
7999                         NET_TRANSPORT_RPC,
8000                         N_("Open interactive shell on remote server"),
8001                         N_("net rpc shell\n"
8002                            "    Open interactive shell on remote server")
8003                 },
8004                 {
8005                         "trust",
8006                         net_rpc_trust,
8007                         NET_TRANSPORT_RPC,
8008                         N_("Manage trusts"),
8009                         N_("net rpc trust\n"
8010                            "    Manage trusts")
8011                 },
8012                 {
8013                         "conf",
8014                         net_rpc_conf,
8015                         NET_TRANSPORT_RPC,
8016                         N_("Configure a remote samba server"),
8017                         N_("net rpc conf\n"
8018                            "    Configure a remote samba server")
8019                 },
8020                 {NULL, NULL, 0, NULL, NULL}
8021         };
8022
8023         status = libnetapi_net_init(&c->netapi_ctx);
8024         if (status != 0) {
8025                 return -1;
8026         }
8027         libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
8028         libnetapi_set_password(c->netapi_ctx, c->opt_password);
8029         if (c->opt_kerberos) {
8030                 libnetapi_set_use_kerberos(c->netapi_ctx);
8031         }
8032         if (c->opt_ccache) {
8033                 libnetapi_set_use_ccache(c->netapi_ctx);
8034         }
8035
8036         return net_run_function(c, argc, argv, "net rpc", func);
8037 }