LCOV - code coverage report
Current view: top level - source3/utils - net_rpc.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 663 2956 22.4 %
Date: 2021-09-23 10:06:22 Functions: 44 159 27.7 %

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

Generated by: LCOV version 1.13