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