LCOV - code coverage report
Current view: top level - source3/rpcclient - rpcclient.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 272 512 53.1 %
Date: 2024-06-13 04:01:37 Functions: 13 25 52.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    RPC pipe client
       4             : 
       5             :    Copyright (C) Tim Potter 2000-2001
       6             :    Copyright (C) Martin Pool 2003
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "../libcli/auth/netlogon_creds_cli.h"
      24             : #include "rpcclient.h"
      25             : #include "../libcli/auth/libcli_auth.h"
      26             : #include "../librpc/gen_ndr/ndr_lsa_c.h"
      27             : #include "rpc_client/cli_lsarpc.h"
      28             : #include "../librpc/gen_ndr/ndr_netlogon.h"
      29             : #include "rpc_client/cli_netlogon.h"
      30             : #include "../libcli/smbreadline/smbreadline.h"
      31             : #include "../libcli/security/security.h"
      32             : #include "passdb.h"
      33             : #include "libsmb/libsmb.h"
      34             : #include "auth/gensec/gensec.h"
      35             : #include "../libcli/smb/smbXcli_base.h"
      36             : #include "messages.h"
      37             : #include "cmdline_contexts.h"
      38             : #include "../librpc/gen_ndr/ndr_samr.h"
      39             : #include "lib/cmdline/cmdline.h"
      40             : 
      41             : enum pipe_auth_type_spnego {
      42             :         PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
      43             :         PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
      44             :         PIPE_AUTH_TYPE_SPNEGO_KRB5
      45             : };
      46             : 
      47             : static unsigned int timeout = 10000;
      48             : 
      49             : struct messaging_context *rpcclient_msg_ctx;
      50             : struct netlogon_creds_cli_context *rpcclient_netlogon_creds;
      51             : static const char *rpcclient_netlogon_domain;
      52             : 
      53             : /* List to hold groups of commands.
      54             :  *
      55             :  * Commands are defined in a list of arrays: arrays are easy to
      56             :  * statically declare, and lists are easier to dynamically extend.
      57             :  */
      58             : 
      59             : static struct cmd_list {
      60             :         struct cmd_list *prev, *next;
      61             :         struct cmd_set *cmd_set;
      62             : } *cmd_list;
      63             : 
      64             : /****************************************************************************
      65             : handle completion of commands for readline
      66             : ****************************************************************************/
      67           0 : static char **completion_fn(const char *text, int start, int end)
      68             : {
      69             : #define MAX_COMPLETIONS 1000
      70             :         char **matches;
      71           0 :         size_t i, count=0;
      72           0 :         struct cmd_list *commands = cmd_list;
      73             : 
      74             : #if 0   /* JERRY */
      75             :         /* FIXME!!!  -- what to do when completing argument? */
      76             :         /* for words not at the start of the line fallback
      77             :            to filename completion */
      78             :         if (start)
      79             :                 return NULL;
      80             : #endif
      81             : 
      82             :         /* make sure we have a list of valid commands */
      83           0 :         if (!commands) {
      84           0 :                 return NULL;
      85             :         }
      86             : 
      87           0 :         matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
      88           0 :         if (!matches) {
      89           0 :                 return NULL;
      90             :         }
      91             : 
      92           0 :         matches[count++] = SMB_STRDUP(text);
      93           0 :         if (!matches[0]) {
      94           0 :                 SAFE_FREE(matches);
      95           0 :                 return NULL;
      96             :         }
      97             : 
      98           0 :         while (commands && count < MAX_COMPLETIONS-1) {
      99           0 :                 if (!commands->cmd_set) {
     100           0 :                         break;
     101             :                 }
     102             : 
     103           0 :                 for (i=0; commands->cmd_set[i].name; i++) {
     104           0 :                         if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
     105           0 :                                 (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
     106           0 :                         commands->cmd_set[i].ntfn ) ||
     107           0 :                       ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
     108           0 :                         commands->cmd_set[i].wfn))) {
     109           0 :                                 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
     110           0 :                                 if (!matches[count]) {
     111           0 :                                         for (i = 0; i < count; i++) {
     112           0 :                                                 SAFE_FREE(matches[count]);
     113             :                                         }
     114           0 :                                         SAFE_FREE(matches);
     115           0 :                                         return NULL;
     116             :                                 }
     117           0 :                                 count++;
     118             :                         }
     119             :                 }
     120           0 :                 commands = commands->next;
     121             :         }
     122             : 
     123           0 :         if (count == 2) {
     124           0 :                 SAFE_FREE(matches[0]);
     125           0 :                 matches[0] = SMB_STRDUP(matches[1]);
     126             :         }
     127           0 :         matches[count] = NULL;
     128           0 :         return matches;
     129             : }
     130             : 
     131         442 : static char *next_command (char **cmdstr)
     132             : {
     133             :         char *command;
     134             :         char                    *p;
     135             : 
     136         442 :         if (!cmdstr || !(*cmdstr))
     137         210 :                 return NULL;
     138             : 
     139         232 :         p = strchr_m(*cmdstr, ';');
     140         232 :         if (p)
     141          22 :                 *p = '\0';
     142         232 :         command = SMB_STRDUP(*cmdstr);
     143         232 :         if (p)
     144          22 :                 *cmdstr = p + 1;
     145             :         else
     146         210 :                 *cmdstr = NULL;
     147             : 
     148         232 :         return command;
     149             : }
     150             : 
     151         206 : static void binding_get_auth_info(
     152             :         const struct dcerpc_binding *b,
     153             :         enum dcerpc_AuthType *_auth_type,
     154             :         enum dcerpc_AuthLevel *_auth_level,
     155             :         enum credentials_use_kerberos *_krb5_state)
     156             : {
     157         206 :         uint32_t bflags = dcerpc_binding_get_flags(b);
     158         206 :         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
     159         206 :         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
     160         206 :         enum credentials_use_kerberos krb5_state = CRED_USE_KERBEROS_DESIRED;
     161             : 
     162         206 :         if (_krb5_state != NULL) {
     163         194 :                 krb5_state = *_krb5_state;
     164             :         }
     165             : 
     166         206 :         if (bflags & DCERPC_CONNECT) {
     167           4 :                 auth_level = DCERPC_AUTH_LEVEL_CONNECT;
     168             :         }
     169         206 :         if (bflags & DCERPC_PACKET) {
     170           4 :                 auth_level = DCERPC_AUTH_LEVEL_PACKET;
     171             :         }
     172         206 :         if (bflags & DCERPC_SIGN) {
     173          16 :                 auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
     174             :         }
     175         206 :         if (bflags & DCERPC_SEAL) {
     176          16 :                 auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
     177             :         }
     178             : 
     179         206 :         if (bflags & DCERPC_SCHANNEL) {
     180          28 :                 auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
     181             :         }
     182             : 
     183         206 :         if ((auth_level != DCERPC_AUTH_LEVEL_NONE) &&
     184             :             (auth_type == DCERPC_AUTH_TYPE_NONE)) {
     185          16 :                 auth_type = (krb5_state == CRED_USE_KERBEROS_REQUIRED) ?
     186          16 :                         DCERPC_AUTH_TYPE_KRB5 : DCERPC_AUTH_TYPE_NTLMSSP;
     187             :         }
     188             : 
     189         206 :         if (bflags & DCERPC_AUTH_SPNEGO) {
     190          10 :                 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
     191             : 
     192          10 :                 if (bflags & DCERPC_AUTH_NTLM) {
     193           0 :                         krb5_state = CRED_USE_KERBEROS_DISABLED;
     194             :                 }
     195          10 :                 if (bflags & DCERPC_AUTH_KRB5) {
     196          10 :                         krb5_state = CRED_USE_KERBEROS_REQUIRED;
     197             :                 }
     198             :         }
     199             : 
     200         206 :         if (auth_type != DCERPC_AUTH_TYPE_NONE) {
     201             :                 /* If nothing is requested then default to integrity */
     202          46 :                 if (auth_level == DCERPC_AUTH_LEVEL_NONE) {
     203           6 :                         auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
     204             :                 }
     205             :         }
     206             : 
     207         206 :         if (_auth_type != NULL) {
     208         206 :                 *_auth_type = auth_type;
     209             :         }
     210         206 :         if (_auth_level != NULL) {
     211         206 :                 *_auth_level = auth_level;
     212             :         }
     213         206 :         if (_krb5_state != NULL) {
     214         194 :                 *_krb5_state = krb5_state;
     215             :         }
     216         206 : }
     217             : 
     218             : /* List the available commands on a given pipe */
     219             : 
     220           0 : static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     221             :                                  int argc, const char **argv)
     222             : {
     223             :         struct cmd_list *tmp;
     224             :         struct cmd_set *tmp_set;
     225             :         int i;
     226             : 
     227             :         /* Usage */
     228             : 
     229           0 :         if (argc != 2) {
     230           0 :                 printf("Usage: %s <pipe>\n", argv[0]);
     231           0 :                 return NT_STATUS_OK;
     232             :         }
     233             : 
     234             :         /* Help on one command */
     235             : 
     236           0 :         for (tmp = cmd_list; tmp; tmp = tmp->next)
     237             :         {
     238           0 :                 tmp_set = tmp->cmd_set;
     239             : 
     240           0 :                 if (!strcasecmp_m(argv[1], tmp_set->name))
     241             :                 {
     242           0 :                         printf("Available commands on the %s pipe:\n\n", tmp_set->name);
     243             : 
     244           0 :                         i = 0;
     245           0 :                         tmp_set++;
     246           0 :                         while(tmp_set->name) {
     247           0 :                                 printf("%30s", tmp_set->name);
     248           0 :                                 tmp_set++;
     249           0 :                                 i++;
     250           0 :                                 if (i%3 == 0)
     251           0 :                                         printf("\n");
     252             :                         }
     253             : 
     254             :                         /* drop out of the loop */
     255           0 :                         break;
     256             :                 }
     257             :         }
     258           0 :         printf("\n\n");
     259             : 
     260           0 :         return NT_STATUS_OK;
     261             : }
     262             : 
     263             : /* Display help on commands */
     264             : 
     265           0 : static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     266             :                          int argc, const char **argv)
     267             : {
     268             :         struct cmd_list *tmp;
     269             :         struct cmd_set *tmp_set;
     270             : 
     271             :         /* Usage */
     272             : 
     273           0 :         if (argc > 2) {
     274           0 :                 printf("Usage: %s [command]\n", argv[0]);
     275           0 :                 return NT_STATUS_OK;
     276             :         }
     277             : 
     278             :         /* Help on one command */
     279             : 
     280           0 :         if (argc == 2) {
     281           0 :                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
     282             : 
     283           0 :                         tmp_set = tmp->cmd_set;
     284             : 
     285           0 :                         while(tmp_set->name) {
     286           0 :                                 if (strequal(argv[1], tmp_set->name)) {
     287           0 :                                         if (tmp_set->usage &&
     288           0 :                                             tmp_set->usage[0])
     289           0 :                                                 printf("%s\n", tmp_set->usage);
     290             :                                         else
     291           0 :                                                 printf("No help for %s\n", tmp_set->name);
     292             : 
     293           0 :                                         return NT_STATUS_OK;
     294             :                                 }
     295             : 
     296           0 :                                 tmp_set++;
     297             :                         }
     298             :                 }
     299             : 
     300           0 :                 printf("No such command: %s\n", argv[1]);
     301           0 :                 return NT_STATUS_OK;
     302             :         }
     303             : 
     304             :         /* List all commands */
     305             : 
     306           0 :         for (tmp = cmd_list; tmp; tmp = tmp->next) {
     307             : 
     308           0 :                 tmp_set = tmp->cmd_set;
     309             : 
     310           0 :                 while(tmp_set->name) {
     311             : 
     312           0 :                         printf("%15s\t\t%s\n", tmp_set->name,
     313           0 :                                tmp_set->description ? tmp_set->description:
     314             :                                "");
     315             : 
     316           0 :                         tmp_set++;
     317             :                 }
     318             :         }
     319             : 
     320           0 :         return NT_STATUS_OK;
     321             : }
     322             : 
     323             : /* Change the debug level */
     324             : 
     325           0 : static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     326             :                                int argc, const char **argv)
     327             : {
     328           0 :         if (argc > 2) {
     329           0 :                 printf("Usage: %s [debuglevel]\n", argv[0]);
     330           0 :                 return NT_STATUS_OK;
     331             :         }
     332             : 
     333           0 :         if (argc == 2) {
     334           0 :                 lp_set_cmdline("log level", argv[1]);
     335             :         }
     336             : 
     337           0 :         printf("debuglevel is %d\n", DEBUGLEVEL);
     338             : 
     339           0 :         return NT_STATUS_OK;
     340             : }
     341             : 
     342           0 : static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     343             :                          int argc, const char **argv)
     344             : {
     345           0 :         exit(0);
     346             :         return NT_STATUS_OK; /* NOTREACHED */
     347             : }
     348             : 
     349          12 : static NTSTATUS cmd_set_ss_level(struct dcerpc_binding *binding)
     350             : {
     351             :         struct cmd_list *tmp;
     352             :         enum dcerpc_AuthType auth_type;
     353             :         enum dcerpc_AuthLevel auth_level;
     354             : 
     355             :         /* Close any existing connections not at this level. */
     356             : 
     357          12 :         binding_get_auth_info(binding, &auth_type, &auth_level, NULL);
     358             : 
     359         540 :         for (tmp = cmd_list; tmp; tmp = tmp->next) {
     360             :                 struct cmd_set *tmp_set;
     361             : 
     362        3828 :                 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
     363        3300 :                         if (tmp_set->rpc_pipe == NULL) {
     364        3300 :                                 continue;
     365             :                         }
     366             : 
     367           0 :                         if ((tmp_set->rpc_pipe->auth->auth_type
     368           0 :                              != auth_type)
     369           0 :                             || (tmp_set->rpc_pipe->auth->auth_level
     370           0 :                                 != auth_level)) {
     371           0 :                                 TALLOC_FREE(tmp_set->rpc_pipe);
     372           0 :                                 tmp_set->rpc_pipe = NULL;
     373             :                         }
     374             :                 }
     375             :         }
     376          12 :         return NT_STATUS_OK;
     377             : }
     378             : 
     379           0 : static NTSTATUS cmd_set_transport(struct dcerpc_binding *b)
     380             : {
     381           0 :         enum dcerpc_transport_t t = dcerpc_binding_get_transport(b);
     382             :         struct cmd_list *tmp;
     383             : 
     384             :         /* Close any existing connections not at this level. */
     385             : 
     386           0 :         for (tmp = cmd_list; tmp; tmp = tmp->next) {
     387             :                 struct cmd_set *tmp_set;
     388             : 
     389           0 :                 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
     390           0 :                         if (tmp_set->rpc_pipe == NULL) {
     391           0 :                                 continue;
     392             :                         }
     393             : 
     394           0 :                         if (tmp_set->rpc_pipe->transport->transport != t) {
     395           0 :                                 TALLOC_FREE(tmp_set->rpc_pipe);
     396           0 :                                 tmp_set->rpc_pipe = NULL;
     397             :                         }
     398             :                 }
     399             :         }
     400           0 :         return NT_STATUS_OK;
     401             : }
     402             : 
     403          12 : static NTSTATUS binding_reset_auth(struct dcerpc_binding *b)
     404             : {
     405          12 :         NTSTATUS status = dcerpc_binding_set_flags(
     406             :                 b,
     407             :                 0,
     408             :                 DCERPC_PACKET|
     409             :                 DCERPC_CONNECT|
     410             :                 DCERPC_SIGN|
     411             :                 DCERPC_SEAL|
     412             :                 DCERPC_SCHANNEL|
     413             :                 DCERPC_AUTH_SPNEGO|
     414             :                 DCERPC_AUTH_KRB5|
     415             :                 DCERPC_AUTH_NTLM);
     416          12 :         return status;
     417             : }
     418             : 
     419          12 : static NTSTATUS binding_set_auth(
     420             :         struct dcerpc_binding *b, const char *level, const char *type)
     421             : {
     422             :         NTSTATUS status;
     423             : 
     424          12 :         status = binding_reset_auth(b);
     425          12 :         if (!NT_STATUS_IS_OK(status)) {
     426           0 :                 return status;
     427             :         }
     428             : 
     429          12 :         if (level != NULL) {
     430          12 :                 status = dcerpc_binding_set_string_option(b, level, level);
     431          12 :                 if (!NT_STATUS_IS_OK(status)) {
     432           0 :                         return status;
     433             :                 }
     434             :         }
     435             : 
     436          12 :         if (strequal(type, "SPNEGO")) {
     437           0 :                 status = dcerpc_binding_set_string_option(
     438             :                         b, "spnego", "spnego");
     439           0 :                 return status;
     440             :         }
     441          12 :         if (strequal(type, "NTLMSSP")) {
     442           0 :                 status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
     443           0 :                 return status;
     444             :         }
     445          12 :         if (strequal(type, "NTLMSSP_SPNEGO")) {
     446           0 :                 status = dcerpc_binding_set_string_option(
     447             :                         b, "spnego", "spnego");
     448           0 :                 if (!NT_STATUS_IS_OK(status)) {
     449           0 :                         return status;
     450             :                 }
     451           0 :                 status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
     452           0 :                 return status;
     453             :         }
     454          12 :         if (strequal(type, "KRB5")) {
     455           0 :                 status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
     456           0 :                 return status;
     457             :         }
     458          12 :         if (strequal(type, "KRB5_SPNEGO")) {
     459           0 :                 status = dcerpc_binding_set_string_option(
     460             :                         b, "spnego", "spnego");
     461           0 :                 if (!NT_STATUS_IS_OK(status)) {
     462           0 :                         return status;
     463             :                 }
     464           0 :                 status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
     465           0 :                 return status;
     466             :         }
     467          12 :         if (strequal(type, "SCHANNEL")) {
     468          12 :                 status = dcerpc_binding_set_string_option(
     469             :                         b, "schannel", "schannel");
     470          12 :                 return status;
     471             :         }
     472             : 
     473           0 :         return NT_STATUS_INVALID_PARAMETER;
     474             : }
     475             : 
     476          12 : static NTSTATUS cmd_set_auth(
     477             :         struct dcerpc_binding *binding,
     478             :         const char *level,
     479             :         const char *display,
     480             :         int argc,
     481             :         const char **argv)
     482             : {
     483          12 :         const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
     484          12 :         const char *type = "NTLMSSP";
     485             :         NTSTATUS status;
     486             : 
     487          12 :         if (argc > 2) {
     488           0 :                 printf("Usage: %s %s\n", argv[0], p);
     489           0 :                 return NT_STATUS_OK;
     490             :         }
     491             : 
     492          12 :         if (argc == 2) {
     493          12 :                 type = argv[1];
     494             :         }
     495             : 
     496          12 :         status = binding_set_auth(binding, level, type);
     497          12 :         if (!NT_STATUS_IS_OK(status)) {
     498           0 :                 printf("Usage: %s %s\n", argv[0], p);
     499           0 :                 return status;
     500             :         }
     501             : 
     502          12 :         d_printf("Setting %s - %s: %s\n", type, display, nt_errstr(status));
     503             : 
     504          12 :         status = cmd_set_ss_level(binding);
     505          12 :         return status;
     506             : }
     507             : 
     508           0 : static NTSTATUS cmd_sign(
     509             :         struct dcerpc_binding *binding,
     510             :         TALLOC_CTX *mem_ctx,
     511             :         int argc,
     512             :         const char **argv)
     513             : {
     514           0 :         NTSTATUS status = cmd_set_auth(binding, "sign", "sign", argc, argv);
     515           0 :         return status;
     516             : }
     517             : 
     518           0 : static NTSTATUS cmd_seal(
     519             :         struct dcerpc_binding *binding,
     520             :         TALLOC_CTX *mem_ctx,
     521             :         int argc,
     522             :         const char **argv)
     523             : {
     524           0 :         NTSTATUS status = cmd_set_auth(
     525             :                 binding, "seal", "sign and seal", argc, argv);
     526           0 :         return status;
     527             : }
     528             : 
     529           0 : static NTSTATUS cmd_packet(
     530             :         struct dcerpc_binding *binding,
     531             :         TALLOC_CTX *mem_ctx,
     532             :         int argc,
     533             :         const char **argv)
     534             : {
     535           0 :         NTSTATUS status = cmd_set_auth(
     536             :                 binding, "packet", "packet", argc, argv);
     537           0 :         return status;
     538             : }
     539             : 
     540           0 : static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     541             :                             int argc, const char **argv)
     542             : {
     543           0 :         if (argc > 2) {
     544           0 :                 printf("Usage: %s timeout\n", argv[0]);
     545           0 :                 return NT_STATUS_OK;
     546             :         }
     547             : 
     548           0 :         if (argc == 2) {
     549           0 :                 timeout = atoi(argv[1]);
     550             :         }
     551             : 
     552           0 :         printf("timeout is %d\n", timeout);
     553             : 
     554           0 :         return NT_STATUS_OK;
     555             : }
     556             : 
     557             : 
     558           0 : static NTSTATUS cmd_none(
     559             :         struct dcerpc_binding *binding,
     560             :         TALLOC_CTX *mem_ctx,
     561             :         int argc,
     562             :         const char **argv)
     563             : {
     564           0 :         NTSTATUS status = binding_reset_auth(binding);
     565           0 :         if (!NT_STATUS_IS_OK(status)) {
     566           0 :                 return status;
     567             :         }
     568           0 :         status = cmd_set_ss_level(binding);
     569           0 :         return status;
     570             : }
     571             : 
     572           6 : static NTSTATUS cmd_schannel(
     573             :         struct dcerpc_binding *binding,
     574             :         TALLOC_CTX *mem_ctx,
     575             :         int argc,
     576             :         const char **_argv)
     577             : {
     578           6 :         const char *argv[] = { "schannel", "SCHANNEL" };
     579           6 :         NTSTATUS status = cmd_set_auth(
     580             :                 binding, "seal", "sign and seal", 2, argv);
     581           6 :         return status;
     582             : }
     583             : 
     584           6 : static NTSTATUS cmd_schannel_sign(
     585             :         struct dcerpc_binding *binding,
     586             :         TALLOC_CTX *mem_ctx,
     587             :         int argc,
     588             :         const char **_argv)
     589             : {
     590           6 :         const char *argv[] = { "schannel_sign", "SCHANNEL" };
     591           6 :         NTSTATUS status = cmd_set_auth(binding, "sign", "sign only", 2, argv);
     592           6 :         return status;
     593             : }
     594             : 
     595           0 : static NTSTATUS cmd_choose_transport(
     596             :         struct dcerpc_binding *binding,
     597             :         TALLOC_CTX *mem_ctx,
     598             :         int argc,
     599             :         const char **argv)
     600             : {
     601             :         NTSTATUS status;
     602             :         enum dcerpc_transport_t transport;
     603             : 
     604           0 :         if (argc != 2) {
     605           0 :                 printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
     606           0 :                 return NT_STATUS_OK;
     607             :         }
     608             : 
     609           0 :         transport = dcerpc_transport_by_name(argv[1]);
     610           0 :         if (transport == NCA_UNKNOWN) {
     611           0 :                 printf("transport type %s unknown\n", argv[1]);
     612           0 :                 return NT_STATUS_NOT_SUPPORTED;
     613             :         }
     614           0 :         if (!((transport == NCACN_IP_TCP) ||
     615             :               (transport == NCACN_NP) ||
     616             :               (transport == NCALRPC))) {
     617           0 :                 printf("transport %s not supported\n", argv[1]);
     618           0 :                 return NT_STATUS_NOT_SUPPORTED;
     619             :         }
     620             : 
     621           0 :         status = dcerpc_binding_set_transport(binding, transport);
     622           0 :         if (!NT_STATUS_IS_OK(status)) {
     623           0 :                 return status;
     624             :         }
     625             : 
     626           0 :         status = cmd_set_transport(binding);
     627           0 :         if (!NT_STATUS_IS_OK(status)) {
     628           0 :                 return status;
     629             :         }
     630             : 
     631           0 :         printf("default transport is now: %s\n", argv[1]);
     632             : 
     633           0 :         return NT_STATUS_OK;
     634             : }
     635             : 
     636             : /* Built in rpcclient commands */
     637             : 
     638             : static struct cmd_set rpcclient_commands[] = {
     639             : 
     640             :         {
     641             :                 .name = "GENERAL OPTIONS",
     642             :         },
     643             : 
     644             :         {
     645             :                 .name               = "help",
     646             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     647             :                 .ntfn               = cmd_help,
     648             :                 .description        = "Get help on commands",
     649             :                 .usage              = "[command]",
     650             :         },
     651             :         {
     652             :                 .name               = "?",
     653             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     654             :                 .ntfn               = cmd_help,
     655             :                 .description        = "Get help on commands",
     656             :                 .usage              = "[command]",
     657             :         },
     658             :         {
     659             :                 .name               = "debuglevel",
     660             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     661             :                 .ntfn               = cmd_debuglevel,
     662             :                 .description        = "Set debug level",
     663             :                 .usage              = "level",
     664             :         },
     665             :         {
     666             :                 .name               = "debug",
     667             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     668             :                 .ntfn               = cmd_debuglevel,
     669             :                 .description        = "Set debug level",
     670             :                 .usage              = "level",
     671             :         },
     672             :         {
     673             :                 .name               = "list",
     674             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     675             :                 .ntfn               = cmd_listcommands,
     676             :                 .description        = "List available commands on <pipe>",
     677             :                 .usage              = "pipe",
     678             :         },
     679             :         {
     680             :                 .name               = "exit",
     681             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     682             :                 .ntfn               = cmd_quit,
     683             :                 .description        = "Exit program",
     684             :                 .usage              = "",
     685             :         },
     686             :         {
     687             :                 .name               = "quit",
     688             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     689             :                 .ntfn               = cmd_quit,
     690             :                 .description        = "Exit program",
     691             :                 .usage              = "",
     692             :         },
     693             :         {
     694             :                 .name               = "sign",
     695             :                 .returntype         = RPC_RTYPE_BINDING,
     696             :                 .bfn                = cmd_sign,
     697             :                 .description        = "Force RPC pipe connections to be signed",
     698             :                 .usage              = "",
     699             :         },
     700             :         {
     701             :                 .name               = "seal",
     702             :                 .returntype         = RPC_RTYPE_BINDING,
     703             :                 .bfn                = cmd_seal,
     704             :                 .description        = "Force RPC pipe connections to be sealed",
     705             :                 .usage              = "",
     706             :         },
     707             :         {
     708             :                 .name               = "packet",
     709             :                 .returntype         = RPC_RTYPE_BINDING,
     710             :                 .bfn                = cmd_packet,
     711             :                 .description        = "Force RPC pipe connections with packet authentication level",
     712             :                 .usage              = "",
     713             :         },
     714             :         {
     715             :                 .name               = "schannel",
     716             :                 .returntype         = RPC_RTYPE_BINDING,
     717             :                 .bfn                = cmd_schannel,
     718             :                 .description        = "Force RPC pipe connections to be sealed with 'schannel'. "
     719             :                                       "Assumes valid machine account to this domain controller.",
     720             :                 .usage              = "",
     721             :         },
     722             :         {
     723             :                 .name               = "schannelsign",
     724             :                 .returntype         = RPC_RTYPE_BINDING,
     725             :                 .bfn                = cmd_schannel_sign,
     726             :                 .description        = "Force RPC pipe connections to be signed (not sealed) with "
     727             :                                       "'schannel'.  Assumes valid machine account to this domain "
     728             :                                       "controller.",
     729             :                 .usage              = "",
     730             :         },
     731             :         {
     732             :                 .name               = "timeout",
     733             :                 .returntype         = RPC_RTYPE_NTSTATUS,
     734             :                 .ntfn               = cmd_timeout,
     735             :                 .description        = "Set timeout (in milliseconds) for RPC operations",
     736             :                 .usage              = "",
     737             :         },
     738             :         {
     739             :                 .name               = "transport",
     740             :                 .returntype         = RPC_RTYPE_BINDING,
     741             :                 .bfn                = cmd_choose_transport,
     742             :                 .description        = "Choose ncacn transport for RPC operations",
     743             :                 .usage              = "",
     744             :         },
     745             :         {
     746             :                 .name               = "none",
     747             :                 .returntype         = RPC_RTYPE_BINDING,
     748             :                 .bfn                = cmd_none,
     749             :                 .description        = "Force RPC pipe connections to have no special properties",
     750             :                 .usage              = "",
     751             :         },
     752             : 
     753             :         { .name = NULL, },
     754             : };
     755             : 
     756             : static struct cmd_set separator_command[] = {
     757             :         {
     758             :                 .name               = "---------------",
     759             :                 .returntype         = MAX_RPC_RETURN_TYPE,
     760             :                 .description        = "----------------------"
     761             :         },
     762             :         { .name = NULL, },
     763             : };
     764             : 
     765             : 
     766             : /* Various pipe commands */
     767             : 
     768             : extern struct cmd_set lsarpc_commands[];
     769             : extern struct cmd_set samr_commands[];
     770             : extern struct cmd_set spoolss_commands[];
     771             : extern struct cmd_set iremotewinspool_commands[];
     772             : extern struct cmd_set netlogon_commands[];
     773             : extern struct cmd_set srvsvc_commands[];
     774             : extern struct cmd_set dfs_commands[];
     775             : extern struct cmd_set ds_commands[];
     776             : extern struct cmd_set echo_commands[];
     777             : extern struct cmd_set epmapper_commands[];
     778             : extern struct cmd_set shutdown_commands[];
     779             : extern struct cmd_set wkssvc_commands[];
     780             : extern struct cmd_set ntsvcs_commands[];
     781             : extern struct cmd_set drsuapi_commands[];
     782             : extern struct cmd_set eventlog_commands[];
     783             : extern struct cmd_set winreg_commands[];
     784             : extern struct cmd_set fss_commands[];
     785             : extern struct cmd_set witness_commands[];
     786             : extern struct cmd_set clusapi_commands[];
     787             : extern struct cmd_set spotlight_commands[];
     788             : extern struct cmd_set unixinfo_commands[];
     789             : 
     790             : static struct cmd_set *rpcclient_command_list[] = {
     791             :         rpcclient_commands,
     792             :         lsarpc_commands,
     793             :         ds_commands,
     794             :         samr_commands,
     795             :         spoolss_commands,
     796             :         iremotewinspool_commands,
     797             :         netlogon_commands,
     798             :         srvsvc_commands,
     799             :         dfs_commands,
     800             :         echo_commands,
     801             :         epmapper_commands,
     802             :         shutdown_commands,
     803             :         wkssvc_commands,
     804             :         ntsvcs_commands,
     805             :         drsuapi_commands,
     806             :         eventlog_commands,
     807             :         winreg_commands,
     808             :         fss_commands,
     809             :         witness_commands,
     810             :         clusapi_commands,
     811             :         spotlight_commands,
     812             :         unixinfo_commands,
     813             :         NULL
     814             : };
     815             : 
     816        9240 : static void add_command_set(struct cmd_set *cmd_set)
     817             : {
     818             :         struct cmd_list *entry;
     819             : 
     820        9240 :         if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
     821           0 :                 DEBUG(0, ("out of memory\n"));
     822           0 :                 return;
     823             :         }
     824             : 
     825        9240 :         ZERO_STRUCTP(entry);
     826             : 
     827        9240 :         entry->cmd_set = cmd_set;
     828        9240 :         DLIST_ADD(cmd_list, entry);
     829             : }
     830             : 
     831          16 : static NTSTATUS rpccli_ncalrpc_connect(
     832             :         const struct ndr_interface_table *iface,
     833             :         TALLOC_CTX *mem_ctx,
     834             :         struct rpc_pipe_client **prpccli)
     835             : {
     836          16 :         struct rpc_pipe_client *rpccli = NULL;
     837          16 :         struct pipe_auth_data *auth = NULL;
     838             :         NTSTATUS status;
     839             : 
     840          16 :         status = rpc_pipe_open_ncalrpc(mem_ctx, iface, &rpccli);
     841          16 :         if (!NT_STATUS_IS_OK(status)) {
     842           8 :                 DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
     843             :                           nt_errstr(status));
     844           8 :                 goto fail;
     845             :         }
     846             : 
     847           8 :         status = rpccli_ncalrpc_bind_data(rpccli, &auth);
     848           8 :         if (!NT_STATUS_IS_OK(status)) {
     849           0 :                 DBG_DEBUG("rpccli_ncalrpc_bind_data failed: %s\n",
     850             :                           nt_errstr(status));
     851           0 :                 goto fail;
     852             :         }
     853             : 
     854           8 :         status = rpc_pipe_bind(rpccli, auth);
     855           8 :         if (!NT_STATUS_IS_OK(status)) {
     856           0 :                 DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
     857           0 :                 goto fail;
     858             :         }
     859             : 
     860           8 :         *prpccli = rpccli;
     861           8 :         return NT_STATUS_OK;
     862           8 : fail:
     863           8 :         TALLOC_FREE(rpccli);
     864           8 :         return status;
     865             : }
     866             : /**
     867             :  * Call an rpcclient function, passing an argv array.
     868             :  *
     869             :  * @param cmd Command to run, as a single string.
     870             :  **/
     871         232 : static NTSTATUS do_cmd(struct cli_state *cli,
     872             :                        struct cli_credentials *creds,
     873             :                        struct cmd_set *cmd_entry,
     874             :                        struct dcerpc_binding *binding,
     875             :                        int argc, const char **argv)
     876             : {
     877             :         NTSTATUS ntresult;
     878             :         WERROR wresult;
     879             :         enum dcerpc_transport_t transport;
     880             : 
     881         232 :         TALLOC_CTX *mem_ctx = talloc_stackframe();
     882         232 :         const char *remote_name = NULL;
     883         232 :         const struct sockaddr_storage *remote_sockaddr = NULL;
     884         232 :         struct sockaddr_storage remote_ss = {
     885             :                 .ss_family = AF_UNSPEC,
     886             :         };
     887             : 
     888         232 :         transport = dcerpc_binding_get_transport(binding);
     889             : 
     890         232 :         if (cli != NULL) {
     891         214 :                 remote_name = smbXcli_conn_remote_name(cli->conn);
     892         214 :                 remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
     893             :         } else {
     894          11 :                 const char *remote_host =
     895           7 :                         dcerpc_binding_get_string_option(binding, "host");
     896          18 :                 remote_name = dcerpc_binding_get_string_option(
     897             :                                 binding, "target_hostname");
     898             : 
     899          18 :                 if (remote_host != NULL) {
     900           2 :                         bool ok = interpret_string_addr(
     901             :                                 &remote_ss, remote_host, 0);
     902           2 :                         if (ok) {
     903           2 :                                 remote_sockaddr = &remote_ss;
     904             :                         }
     905             :                 }
     906             :         }
     907             : 
     908             :         /* Open pipe */
     909             : 
     910         232 :         if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
     911         210 :                 if (transport == NCALRPC) {
     912          16 :                         ntresult = rpccli_ncalrpc_connect(
     913             :                                 cmd_entry->table, cli, &cmd_entry->rpc_pipe);
     914          16 :                         if (!NT_STATUS_IS_OK(ntresult)) {
     915           8 :                                 TALLOC_FREE(mem_ctx);
     916           8 :                                 return ntresult;
     917             :                         }
     918             :                 } else {
     919             :                         enum dcerpc_AuthType auth_type;
     920             :                         enum dcerpc_AuthLevel auth_level;
     921         194 :                         enum credentials_use_kerberos krb5_state =
     922         194 :                                 cli_credentials_get_kerberos_state(creds);
     923             : 
     924         194 :                         binding_get_auth_info(
     925             :                                 binding, &auth_type, &auth_level, &krb5_state);
     926             : 
     927         194 :                         switch (auth_type) {
     928         160 :                         case DCERPC_AUTH_TYPE_NONE:
     929         160 :                                 ntresult = cli_rpc_pipe_open_noauth_transport(
     930             :                                         cli, transport,
     931             :                                         cmd_entry->table,
     932             :                                         remote_name,
     933             :                                         remote_sockaddr,
     934             :                                         &cmd_entry->rpc_pipe);
     935         160 :                                 break;
     936          18 :                         case DCERPC_AUTH_TYPE_SPNEGO:
     937             :                         case DCERPC_AUTH_TYPE_NTLMSSP:
     938             :                         case DCERPC_AUTH_TYPE_KRB5:
     939          18 :                                 cli_credentials_set_kerberos_state(creds,
     940             :                                                                    krb5_state,
     941             :                                                                    CRED_SPECIFIED);
     942             : 
     943          18 :                                 ntresult = cli_rpc_pipe_open_with_creds(
     944             :                                         cli, cmd_entry->table,
     945             :                                         transport,
     946             :                                         auth_type,
     947             :                                         auth_level,
     948             :                                         remote_name,
     949             :                                         remote_sockaddr,
     950             :                                         creds,
     951             :                                         &cmd_entry->rpc_pipe);
     952          18 :                                 break;
     953          16 :                         case DCERPC_AUTH_TYPE_SCHANNEL:
     954          16 :                                 TALLOC_FREE(rpcclient_netlogon_creds);
     955          16 :                                 ntresult = cli_rpc_pipe_open_schannel(
     956             :                                         cli, rpcclient_msg_ctx,
     957             :                                         cmd_entry->table,
     958             :                                         transport,
     959             :                                         rpcclient_netlogon_domain,
     960             :                                         remote_name,
     961             :                                         remote_sockaddr,
     962             :                                         &cmd_entry->rpc_pipe,
     963             :                                         rpcclient_msg_ctx,
     964             :                                         &rpcclient_netlogon_creds);
     965          16 :                                 break;
     966           0 :                         default:
     967           0 :                                 DEBUG(0, ("Could not initialise %s. Invalid "
     968             :                                           "auth type %u\n",
     969             :                                           cmd_entry->table->name,
     970             :                                           auth_type ));
     971           0 :                                 talloc_free(mem_ctx);
     972           0 :                                 return NT_STATUS_UNSUCCESSFUL;
     973             :                         }
     974         194 :                         if (!NT_STATUS_IS_OK(ntresult)) {
     975           0 :                                 DBG_ERR("Could not initialise %s. "
     976             :                                         "Error was %s\n",
     977             :                                         cmd_entry->table->name,
     978             :                                         nt_errstr(ntresult));
     979           0 :                                 talloc_free(mem_ctx);
     980           0 :                                 return ntresult;
     981             :                         }
     982             : 
     983         295 :                         if (rpcclient_netlogon_creds == NULL &&
     984         178 :                             cmd_entry->use_netlogon_creds) {
     985           9 :                                 const char *dc_name =
     986           9 :                                         cmd_entry->rpc_pipe->desthost;
     987           9 :                                 const char *domain = rpcclient_netlogon_domain;
     988           9 :                                 struct cli_credentials *trust_creds = NULL;
     989             : 
     990           9 :                                 ntresult = pdb_get_trust_credentials(
     991             :                                         domain,
     992             :                                         NULL,
     993             :                                         mem_ctx,
     994             :                                         &trust_creds);
     995           9 :                                 if (!NT_STATUS_IS_OK(ntresult)) {
     996           0 :                                         DBG_ERR("Failed to fetch trust "
     997             :                                                 "credentials for "
     998             :                                                 "%s to connect to %s: %s\n",
     999             :                                                 domain,
    1000             :                                                 cmd_entry->table->name,
    1001             :                                                 nt_errstr(ntresult));
    1002           0 :                                         TALLOC_FREE(cmd_entry->rpc_pipe);
    1003           0 :                                         talloc_free(mem_ctx);
    1004           0 :                                         return ntresult;
    1005             :                                 }
    1006             : 
    1007           9 :                                 ntresult = rpccli_create_netlogon_creds_ctx(
    1008             :                                         trust_creds,
    1009             :                                         dc_name,
    1010             :                                         rpcclient_msg_ctx,
    1011             :                                         rpcclient_msg_ctx,
    1012             :                                         &rpcclient_netlogon_creds);
    1013           9 :                                 if (!NT_STATUS_IS_OK(ntresult)) {
    1014           0 :                                         DBG_ERR("Could not initialise "
    1015             :                                                 "credentials for %s.\n",
    1016             :                                                 cmd_entry->table->name);
    1017           0 :                                         TALLOC_FREE(cmd_entry->rpc_pipe);
    1018           0 :                                         TALLOC_FREE(mem_ctx);
    1019           0 :                                         return ntresult;
    1020             :                                 }
    1021             : 
    1022           9 :                                 ntresult = rpccli_setup_netlogon_creds(
    1023             :                                         cli,
    1024             :                                         NCACN_NP,
    1025             :                                         rpcclient_netlogon_creds,
    1026             :                                         false, /* force_reauth */
    1027             :                                         trust_creds);
    1028           9 :                                 TALLOC_FREE(trust_creds);
    1029           9 :                                 if (!NT_STATUS_IS_OK(ntresult)) {
    1030           0 :                                         DBG_ERR("Could not initialise "
    1031             :                                                 "credentials for %s.\n",
    1032             :                                                 cmd_entry->table->name);
    1033           0 :                                         TALLOC_FREE(cmd_entry->rpc_pipe);
    1034           0 :                                         TALLOC_FREE(rpcclient_netlogon_creds);
    1035           0 :                                         TALLOC_FREE(mem_ctx);
    1036           0 :                                         return ntresult;
    1037             :                                 }
    1038             :                         }
    1039             :                 }
    1040             :         }
    1041             : 
    1042             :         /* Set timeout for new connections */
    1043         224 :         if (cmd_entry->rpc_pipe) {
    1044         212 :                 rpccli_set_timeout(cmd_entry->rpc_pipe, timeout);
    1045             :         }
    1046             : 
    1047             :         /* Run command */
    1048             : 
    1049         224 :         if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
    1050         183 :                 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
    1051         183 :                 if (!NT_STATUS_IS_OK(ntresult)) {
    1052          28 :                         printf("result was %s\n", nt_errstr(ntresult));
    1053             :                 }
    1054          41 :         } else if (cmd_entry->returntype == RPC_RTYPE_BINDING) {
    1055          12 :                 ntresult = cmd_entry->bfn(binding, mem_ctx, argc, argv);
    1056          12 :                 if (!NT_STATUS_IS_OK(ntresult)) {
    1057           0 :                         printf("result was %s\n", nt_errstr(ntresult));
    1058             :                 }
    1059             :         } else {
    1060          29 :                 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
    1061             :                 /* print out the DOS error */
    1062          29 :                 if (!W_ERROR_IS_OK(wresult)) {
    1063           1 :                         printf( "result was %s\n", win_errstr(wresult));
    1064             :                 }
    1065          29 :                 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
    1066             :         }
    1067             : 
    1068             :         /* Cleanup */
    1069             : 
    1070         224 :         talloc_free(mem_ctx);
    1071             : 
    1072         224 :         return ntresult;
    1073             : }
    1074             : 
    1075             : 
    1076             : /**
    1077             :  * Process a command entered at the prompt or as part of -c
    1078             :  *
    1079             :  * @returns The NTSTATUS from running the command.
    1080             :  **/
    1081         232 : static NTSTATUS process_cmd(struct cli_credentials *creds,
    1082             :                             struct cli_state *cli,
    1083             :                             struct dcerpc_binding *binding,
    1084             :                             char *cmd)
    1085             : {
    1086             :         struct cmd_list *temp_list;
    1087         232 :         NTSTATUS result = NT_STATUS_OK;
    1088             :         int ret;
    1089             :         int argc;
    1090         232 :         const char **argv = NULL;
    1091             : 
    1092         232 :         if ((ret = poptParseArgvString(cmd, &argc, &argv)) != 0) {
    1093           0 :                 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
    1094           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1095             :         }
    1096             : 
    1097             : 
    1098             :         /* Walk through a dlist of arrays of commands. */
    1099        8842 :         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
    1100        8842 :                 struct cmd_set *set = temp_list->cmd_set;
    1101             : 
    1102       60153 :                 while (set->name != NULL) {
    1103       46299 :                         if (!strequal(argv[0], set->name)) {
    1104       46067 :                                 set += 1;
    1105       46067 :                                 continue;
    1106             :                         }
    1107             : 
    1108         341 :                         if (((set->returntype == RPC_RTYPE_NTSTATUS) &&
    1109         332 :                              (set->ntfn == NULL)) ||
    1110         254 :                             ((set->returntype == RPC_RTYPE_WERROR) &&
    1111         170 :                              (set->wfn == NULL)) ||
    1112         242 :                             ((set->returntype == RPC_RTYPE_BINDING) &&
    1113          12 :                              (set->bfn == NULL))) {
    1114           0 :                                 fprintf (stderr, "Invalid command\n");
    1115           0 :                                 goto out_free;
    1116             :                         }
    1117             : 
    1118         232 :                         result = do_cmd(
    1119             :                                 cli, creds, set, binding, argc, argv);
    1120         232 :                         goto out_free;
    1121             :                 }
    1122             :         }
    1123             : 
    1124           0 :         if (argv[0]) {
    1125           0 :                 printf("command not found: %s\n", argv[0]);
    1126             :         }
    1127             : 
    1128         141 : out_free:
    1129             : /* moved to do_cmd()
    1130             :         if (!NT_STATUS_IS_OK(result)) {
    1131             :                 printf("result was %s\n", nt_errstr(result));
    1132             :         }
    1133             : */
    1134             : 
    1135             :         /* NOTE: popt allocates the whole argv, including the
    1136             :          * strings, as a single block.  So a single free is
    1137             :          * enough to release it -- we don't free the
    1138             :          * individual strings.  rtfm. */
    1139         232 :         free(argv);
    1140             : 
    1141         232 :         return result;
    1142             : }
    1143             : 
    1144             : 
    1145             : /* Main function */
    1146             : 
    1147         218 :  int main(int argc, char *argv[])
    1148             : {
    1149         218 :         const char **const_argv = discard_const_p(const char *, argv);
    1150             :         int                     opt;
    1151             :         static char             *cmdstr = NULL;
    1152             :         const char *server;
    1153         218 :         struct cli_state        *cli = NULL;
    1154             :         static char             *opt_ipaddr=NULL;
    1155             :         struct cmd_set          **cmd_set;
    1156             :         struct sockaddr_storage server_ss;
    1157             :         NTSTATUS                nt_status;
    1158             :         static int              opt_port = 0;
    1159         218 :         int result = 0;
    1160         218 :         TALLOC_CTX *frame = talloc_stackframe();
    1161         218 :         uint32_t flags = CLI_FULL_CONNECTION_IPC;
    1162         218 :         struct dcerpc_binding *binding = NULL;
    1163             :         enum dcerpc_transport_t transport;
    1164         218 :         const char *binding_string = NULL;
    1165             :         const char *host;
    1166         218 :         struct cli_credentials *creds = NULL;
    1167             :         bool ok;
    1168             : 
    1169             :         /* make sure the vars that get altered (4th field) are in
    1170             :            a fixed location or certain compilers complain */
    1171             :         poptContext pc;
    1172        1308 :         struct poptOption long_options[] = {
    1173             :                 POPT_AUTOHELP
    1174             :                 {"command",   'c', POPT_ARG_STRING,   &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
    1175             :                 {"dest-ip", 'I', POPT_ARG_STRING,   &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
    1176             :                 {"port", 'p', POPT_ARG_INT,   &opt_port, 'p', "Specify port number", "PORT"},
    1177         218 :                 POPT_COMMON_SAMBA
    1178         218 :                 POPT_COMMON_CONNECTION
    1179         218 :                 POPT_COMMON_CREDENTIALS
    1180         218 :                 POPT_LEGACY_S3
    1181         218 :                 POPT_COMMON_VERSION
    1182             :                 POPT_TABLEEND
    1183             :         };
    1184             : 
    1185         218 :         smb_init_locale();
    1186             : 
    1187         218 :         zero_sockaddr(&server_ss);
    1188             : 
    1189         218 :         setlinebuf(stdout);
    1190             : 
    1191         218 :         ok = samba_cmdline_init(frame,
    1192             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
    1193             :                                 false /* require_smbconf */);
    1194         218 :         if (!ok) {
    1195           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
    1196             :         }
    1197         218 :         lp_set_cmdline("log level", "0");
    1198             : 
    1199             :         /* Parse options */
    1200         218 :         pc = samba_popt_get_context(getprogname(),
    1201             :                                     argc,
    1202             :                                     const_argv,
    1203             :                                     long_options,
    1204             :                                     0);
    1205         218 :         if (pc == NULL) {
    1206           0 :                 DBG_ERR("Failed to setup popt context!\n");
    1207           0 :                 exit(1);
    1208             :         }
    1209             : 
    1210         218 :         poptSetOtherOptionHelp(pc, "[OPTION...] BINDING-STRING|HOST\nOptions:");
    1211             : 
    1212         218 :         if (argc == 1) {
    1213           0 :                 poptPrintHelp(pc, stderr, 0);
    1214           0 :                 goto done;
    1215             :         }
    1216             : 
    1217         654 :         while((opt = poptGetNextOpt(pc)) != -1) {
    1218         218 :                 switch (opt) {
    1219             : 
    1220           0 :                 case 'I':
    1221           0 :                         if (!interpret_string_addr(&server_ss,
    1222             :                                                 opt_ipaddr,
    1223             :                                                 AI_NUMERICHOST)) {
    1224           0 :                                 fprintf(stderr, "%s not a valid IP address\n",
    1225             :                                         opt_ipaddr);
    1226           0 :                                 result = 1;
    1227           0 :                                 goto done;
    1228             :                         }
    1229           0 :                         break;
    1230           0 :                 case POPT_ERROR_BADOPT:
    1231           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1232             :                                 poptBadOption(pc, 0), poptStrerror(opt));
    1233           0 :                         poptPrintUsage(pc, stderr, 0);
    1234           0 :                         exit(1);
    1235             :                 }
    1236             :         }
    1237             : 
    1238             :         /* Get server as remaining unparsed argument.  Print usage if more
    1239             :            than one unparsed argument is present. */
    1240             : 
    1241         218 :         server = talloc_strdup(frame, poptGetArg(pc));
    1242             : 
    1243         218 :         if (!server || poptGetArg(pc)) {
    1244           0 :                 poptPrintHelp(pc, stderr, 0);
    1245           0 :                 result = 1;
    1246           0 :                 goto done;
    1247             :         }
    1248             : 
    1249         218 :         poptFreeContext(pc);
    1250         218 :         samba_cmdline_burn(argc, argv);
    1251             : 
    1252         218 :         rpcclient_msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
    1253         218 :         creds = samba_cmdline_get_creds();
    1254             : 
    1255             :         /*
    1256             :          * Get password
    1257             :          * from stdin if necessary
    1258             :          */
    1259             : 
    1260         345 :         if ((server[0] == '/' && server[1] == '/') ||
    1261         218 :                         (server[0] == '\\' && server[1] ==  '\\')) {
    1262           0 :                 server += 2;
    1263             :         }
    1264             : 
    1265         218 :         nt_status = dcerpc_parse_binding(frame, server, &binding);
    1266             : 
    1267         218 :         if (!NT_STATUS_IS_OK(nt_status)) {
    1268             : 
    1269           0 :                 binding_string = talloc_asprintf(frame, "ncacn_np:%s",
    1270             :                                                  strip_hostname(server));
    1271           0 :                 if (!binding_string) {
    1272           0 :                         result = 1;
    1273           0 :                         goto done;
    1274             :                 }
    1275             : 
    1276           0 :                 nt_status = dcerpc_parse_binding(frame, binding_string, &binding);
    1277           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    1278           0 :                         result = -1;
    1279           0 :                         goto done;
    1280             :                 }
    1281             :         }
    1282             : 
    1283         218 :         transport = dcerpc_binding_get_transport(binding);
    1284             : 
    1285         218 :         if (transport == NCA_UNKNOWN) {
    1286         154 :                 transport = NCACN_NP;
    1287         154 :                 nt_status = dcerpc_binding_set_transport(binding, transport);
    1288         154 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    1289           0 :                         result = -1;
    1290           0 :                         goto done;
    1291             :                 }
    1292             :         }
    1293             : 
    1294         218 :         host = dcerpc_binding_get_string_option(binding, "host");
    1295             : 
    1296         218 :         rpcclient_netlogon_domain = cli_credentials_get_domain(creds);
    1297         345 :         if (rpcclient_netlogon_domain == NULL ||
    1298         218 :             rpcclient_netlogon_domain[0] == '\0')
    1299             :         {
    1300          31 :                 rpcclient_netlogon_domain = lp_workgroup();
    1301             :         }
    1302             : 
    1303         218 :         if (transport == NCACN_NP) {
    1304         316 :                 nt_status = cli_full_connection_creds(
    1305             :                         &cli,
    1306             :                         lp_netbios_name(),
    1307             :                         host,
    1308         200 :                         opt_ipaddr ? &server_ss : NULL,
    1309             :                         opt_port,
    1310             :                         "IPC$",
    1311             :                         "IPC",
    1312             :                         creds,
    1313             :                         flags);
    1314             : 
    1315         200 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    1316           8 :                         DEBUG(0, ("Cannot connect to server.  Error was %s\n",
    1317             :                                   nt_errstr(nt_status)));
    1318           8 :                         result = 1;
    1319           8 :                         goto done;
    1320             :                 }
    1321             : 
    1322             :                 /* Load command lists */
    1323         192 :                 cli_set_timeout(cli, timeout);
    1324             :         }
    1325             : 
    1326             : #if 0   /* COMMENT OUT FOR TESTING */
    1327             :         memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
    1328             : #endif
    1329             : 
    1330         210 :         cmd_set = rpcclient_command_list;
    1331             : 
    1332        4953 :         while(*cmd_set) {
    1333        4620 :                 add_command_set(*cmd_set);
    1334        4620 :                 add_command_set(separator_command);
    1335        4620 :                 cmd_set++;
    1336             :         }
    1337             : 
    1338             :        /* Do anything specified with -c */
    1339         210 :         if (cmdstr && cmdstr[0]) {
    1340             :                 char    *cmd;
    1341         210 :                 char    *p = cmdstr;
    1342             : 
    1343         210 :                 result = 0;
    1344             : 
    1345         565 :                 while((cmd=next_command(&p)) != NULL) {
    1346         232 :                         NTSTATUS cmd_result = process_cmd(creds,
    1347             :                                                           cli,
    1348             :                                                           binding,
    1349             :                                                           cmd);
    1350         232 :                         SAFE_FREE(cmd);
    1351         232 :                         result = NT_STATUS_IS_ERR(cmd_result);
    1352             :                 }
    1353             : 
    1354         210 :                 goto done;
    1355             :         }
    1356             : 
    1357             :         /* Loop around accepting commands */
    1358             : 
    1359           0 :         while(1) {
    1360           0 :                 char *line = NULL;
    1361             : 
    1362           0 :                 line = smb_readline("rpcclient $> ", NULL, completion_fn);
    1363             : 
    1364           0 :                 if (line == NULL) {
    1365           0 :                         printf("\n");
    1366           0 :                         break;
    1367             :                 }
    1368             : 
    1369           0 :                 if (line[0] != '\n')
    1370           0 :                         process_cmd(creds,
    1371             :                                     cli,
    1372             :                                     binding,
    1373             :                                     line);
    1374           0 :                 SAFE_FREE(line);
    1375             :         }
    1376             : 
    1377         218 : done:
    1378         218 :         if (cli != NULL) {
    1379         192 :                 cli_shutdown(cli);
    1380             :         }
    1381         218 :         netlogon_creds_cli_close_global_db();
    1382         218 :         TALLOC_FREE(rpcclient_msg_ctx);
    1383         218 :         TALLOC_FREE(frame);
    1384         218 :         return result;
    1385             : }

Generated by: LCOV version 1.13