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