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

Generated by: LCOV version 1.14