LCOV - code coverage report
Current view: top level - source3/utils - net_rpc.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 709 3275 21.6 %
Date: 2024-05-31 13:13:24 Functions: 46 142 32.4 %

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

Generated by: LCOV version 1.14