root/source3/rpcclient/rpcclient.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. completion_fn
  2. next_command
  3. fetch_machine_sid
  4. cmd_listcommands
  5. cmd_help
  6. cmd_debuglevel
  7. cmd_quit
  8. cmd_set_ss_level
  9. cmd_sign
  10. cmd_seal
  11. cmd_timeout
  12. cmd_none
  13. cmd_schannel
  14. cmd_schannel_sign
  15. add_command_set
  16. do_cmd
  17. process_cmd
  18. main

   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 "rpcclient.h"
  24 
  25 DOM_SID domain_sid;
  26 
  27 static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
  28 static enum pipe_auth_level pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
  29 static unsigned int timeout = 0;
  30 
  31 struct user_auth_info *rpcclient_auth_info;
  32 
  33 /* List to hold groups of commands.
  34  *
  35  * Commands are defined in a list of arrays: arrays are easy to
  36  * statically declare, and lists are easier to dynamically extend.
  37  */
  38 
  39 static struct cmd_list {
  40         struct cmd_list *prev, *next;
  41         struct cmd_set *cmd_set;
  42 } *cmd_list;
  43 
  44 /****************************************************************************
  45 handle completion of commands for readline
  46 ****************************************************************************/
  47 static char **completion_fn(const char *text, int start, int end)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49 #define MAX_COMPLETIONS 100
  50         char **matches;
  51         int i, count=0;
  52         struct cmd_list *commands = cmd_list;
  53 
  54 #if 0   /* JERRY */
  55         /* FIXME!!!  -- what to do when completing argument? */
  56         /* for words not at the start of the line fallback 
  57            to filename completion */
  58         if (start) 
  59                 return NULL;
  60 #endif
  61 
  62         /* make sure we have a list of valid commands */
  63         if (!commands) {
  64                 return NULL;
  65         }
  66 
  67         matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
  68         if (!matches) {
  69                 return NULL;
  70         }
  71 
  72         matches[count++] = SMB_STRDUP(text);
  73         if (!matches[0]) {
  74                 SAFE_FREE(matches);
  75                 return NULL;
  76         }
  77 
  78         while (commands && count < MAX_COMPLETIONS-1) {
  79                 if (!commands->cmd_set) {
  80                         break;
  81                 }
  82                 
  83                 for (i=0; commands->cmd_set[i].name; i++) {
  84                         if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
  85                                 (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
  86                         commands->cmd_set[i].ntfn ) || 
  87                       ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
  88                         commands->cmd_set[i].wfn))) {
  89                                 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
  90                                 if (!matches[count]) {
  91                                         for (i = 0; i < count; i++) {
  92                                                 SAFE_FREE(matches[count]);
  93                                         }
  94                                         SAFE_FREE(matches);
  95                                         return NULL;
  96                                 }
  97                                 count++;
  98                         }
  99                 }
 100                 commands = commands->next;
 101                 
 102         }
 103 
 104         if (count == 2) {
 105                 SAFE_FREE(matches[0]);
 106                 matches[0] = SMB_STRDUP(matches[1]);
 107         }
 108         matches[count] = NULL;
 109         return matches;
 110 }
 111 
 112 static char *next_command (char **cmdstr)
     /* [<][>][^][v][top][bottom][index][help] */
 113 {
 114         char *command;
 115         char                    *p;
 116         
 117         if (!cmdstr || !(*cmdstr))
 118                 return NULL;
 119         
 120         p = strchr_m(*cmdstr, ';');
 121         if (p)
 122                 *p = '\0';
 123         command = SMB_STRDUP(*cmdstr);
 124         if (p)
 125                 *cmdstr = p + 1;
 126         else
 127                 *cmdstr = NULL;
 128         
 129         return command;
 130 }
 131 
 132 /* Fetch the SID for this computer */
 133 
 134 static void fetch_machine_sid(struct cli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         struct policy_handle pol;
 137         NTSTATUS result = NT_STATUS_OK;
 138         static bool got_domain_sid;
 139         TALLOC_CTX *mem_ctx;
 140         struct rpc_pipe_client *lsapipe = NULL;
 141         union lsa_PolicyInformation *info = NULL;
 142 
 143         if (got_domain_sid) return;
 144 
 145         if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
 146                 DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
 147                 goto error;
 148         }
 149 
 150         result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
 151                                           &lsapipe);
 152         if (!NT_STATUS_IS_OK(result)) {
 153                 fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
 154                 goto error;
 155         }
 156         
 157         result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True, 
 158                                      SEC_FLAG_MAXIMUM_ALLOWED,
 159                                      &pol);
 160         if (!NT_STATUS_IS_OK(result)) {
 161                 goto error;
 162         }
 163 
 164         result = rpccli_lsa_QueryInfoPolicy(lsapipe, mem_ctx,
 165                                             &pol,
 166                                             LSA_POLICY_INFO_ACCOUNT_DOMAIN,
 167                                             &info);
 168         if (!NT_STATUS_IS_OK(result)) {
 169                 goto error;
 170         }
 171 
 172         got_domain_sid = True;
 173         sid_copy(&domain_sid, info->account_domain.sid);
 174 
 175         rpccli_lsa_Close(lsapipe, mem_ctx, &pol);
 176         TALLOC_FREE(lsapipe);
 177         talloc_destroy(mem_ctx);
 178 
 179         return;
 180 
 181  error:
 182 
 183         if (lsapipe) {
 184                 TALLOC_FREE(lsapipe);
 185         }
 186 
 187         fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
 188 
 189         if (!NT_STATUS_IS_OK(result)) {
 190                 fprintf(stderr, "error: %s\n", nt_errstr(result));
 191         }
 192 
 193         exit(1);
 194 }
 195 
 196 /* List the available commands on a given pipe */
 197 
 198 static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 199                                  int argc, const char **argv)
 200 {
 201         struct cmd_list *tmp;
 202         struct cmd_set *tmp_set;
 203         int i;
 204 
 205         /* Usage */
 206 
 207         if (argc != 2) {
 208                 printf("Usage: %s <pipe>\n", argv[0]);
 209                 return NT_STATUS_OK;
 210         }
 211 
 212         /* Help on one command */
 213 
 214         for (tmp = cmd_list; tmp; tmp = tmp->next) 
 215         {
 216                 tmp_set = tmp->cmd_set;
 217                 
 218                 if (!StrCaseCmp(argv[1], tmp_set->name))
 219                 {
 220                         printf("Available commands on the %s pipe:\n\n", tmp_set->name);
 221 
 222                         i = 0;
 223                         tmp_set++;
 224                         while(tmp_set->name) {
 225                                 printf("%30s", tmp_set->name);
 226                                 tmp_set++;
 227                                 i++;
 228                                 if (i%3 == 0)
 229                                         printf("\n");
 230                         }
 231                         
 232                         /* drop out of the loop */
 233                         break;
 234                 }
 235         }
 236         printf("\n\n");
 237 
 238         return NT_STATUS_OK;
 239 }
 240 
 241 /* Display help on commands */
 242 
 243 static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 244                          int argc, const char **argv)
 245 {
 246         struct cmd_list *tmp;
 247         struct cmd_set *tmp_set;
 248 
 249         /* Usage */
 250 
 251         if (argc > 2) {
 252                 printf("Usage: %s [command]\n", argv[0]);
 253                 return NT_STATUS_OK;
 254         }
 255 
 256         /* Help on one command */
 257 
 258         if (argc == 2) {
 259                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
 260                         
 261                         tmp_set = tmp->cmd_set;
 262 
 263                         while(tmp_set->name) {
 264                                 if (strequal(argv[1], tmp_set->name)) {
 265                                         if (tmp_set->usage &&
 266                                             tmp_set->usage[0])
 267                                                 printf("%s\n", tmp_set->usage);
 268                                         else
 269                                                 printf("No help for %s\n", tmp_set->name);
 270 
 271                                         return NT_STATUS_OK;
 272                                 }
 273 
 274                                 tmp_set++;
 275                         }
 276                 }
 277 
 278                 printf("No such command: %s\n", argv[1]);
 279                 return NT_STATUS_OK;
 280         }
 281 
 282         /* List all commands */
 283 
 284         for (tmp = cmd_list; tmp; tmp = tmp->next) {
 285 
 286                 tmp_set = tmp->cmd_set;
 287 
 288                 while(tmp_set->name) {
 289 
 290                         printf("%15s\t\t%s\n", tmp_set->name,
 291                                tmp_set->description ? tmp_set->description:
 292                                "");
 293 
 294                         tmp_set++;
 295                 }
 296         }
 297 
 298         return NT_STATUS_OK;
 299 }
 300 
 301 /* Change the debug level */
 302 
 303 static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 304                                int argc, const char **argv)
 305 {
 306         if (argc > 2) {
 307                 printf("Usage: %s [debuglevel]\n", argv[0]);
 308                 return NT_STATUS_OK;
 309         }
 310 
 311         if (argc == 2) {
 312                 DEBUGLEVEL = atoi(argv[1]);
 313         }
 314 
 315         printf("debuglevel is %d\n", DEBUGLEVEL);
 316 
 317         return NT_STATUS_OK;
 318 }
 319 
 320 static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 321                          int argc, const char **argv)
 322 {
 323         exit(0);
 324         return NT_STATUS_OK; /* NOTREACHED */
 325 }
 326 
 327 static NTSTATUS cmd_set_ss_level(void)
     /* [<][>][^][v][top][bottom][index][help] */
 328 {
 329         struct cmd_list *tmp;
 330 
 331         /* Close any existing connections not at this level. */
 332 
 333         for (tmp = cmd_list; tmp; tmp = tmp->next) {
 334                 struct cmd_set *tmp_set;
 335 
 336                 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
 337                         if (tmp_set->rpc_pipe == NULL) {
 338                                 continue;
 339                         }
 340 
 341                         if ((tmp_set->rpc_pipe->auth->auth_type
 342                              != pipe_default_auth_type)
 343                             || (tmp_set->rpc_pipe->auth->auth_level
 344                                 != pipe_default_auth_level)) {
 345                                 TALLOC_FREE(tmp_set->rpc_pipe);
 346                                 tmp_set->rpc_pipe = NULL;
 347                         }
 348                 }
 349         }
 350         return NT_STATUS_OK;
 351 }
 352 
 353 static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 354                          int argc, const char **argv)
 355 {
 356         const char *type = "NTLMSSP";
 357 
 358         pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
 359         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 360 
 361         if (argc > 2) {
 362                 printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
 363                 return NT_STATUS_OK;
 364         }
 365 
 366         if (argc == 2) {
 367                 type = argv[1];
 368                 if (strequal(type, "NTLMSSP")) {
 369                         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 370                 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
 371                         pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
 372                 } else if (strequal(type, "SCHANNEL")) {
 373                         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 374                 } else {
 375                         printf("unknown type %s\n", type);
 376                         return NT_STATUS_INVALID_LEVEL;
 377                 }
 378         }
 379 
 380         d_printf("Setting %s - sign\n", type);
 381 
 382         return cmd_set_ss_level();
 383 }
 384 
 385 static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 386                          int argc, const char **argv)
 387 {
 388         const char *type = "NTLMSSP";
 389 
 390         pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
 391         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 392 
 393         if (argc > 2) {
 394                 printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
 395                 return NT_STATUS_OK;
 396         }
 397 
 398         if (argc == 2) {
 399                 type = argv[1];
 400                 if (strequal(type, "NTLMSSP")) {
 401                         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
 402                 } else if (strequal(type, "NTLMSSP_SPNEGO")) {
 403                         pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
 404                 } else if (strequal(type, "SCHANNEL")) {
 405                         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 406                 } else {
 407                         printf("unknown type %s\n", type);
 408                         return NT_STATUS_INVALID_LEVEL;
 409                 }
 410         }
 411 
 412         d_printf("Setting %s - sign and seal\n", type);
 413 
 414         return cmd_set_ss_level();
 415 }
 416 
 417 static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 418                             int argc, const char **argv)
 419 {
 420         struct cmd_list *tmp;
 421 
 422         if (argc > 2) {
 423                 printf("Usage: %s timeout\n", argv[0]);
 424                 return NT_STATUS_OK;
 425         }
 426 
 427         if (argc == 2) {
 428                 timeout = atoi(argv[1]);
 429 
 430                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
 431                         
 432                         struct cmd_set *tmp_set;
 433 
 434                         for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
 435                                 if (tmp_set->rpc_pipe == NULL) {
 436                                         continue;
 437                                 }
 438 
 439                                 rpccli_set_timeout(tmp_set->rpc_pipe, timeout);
 440                         }
 441                 }
 442         }
 443 
 444         printf("timeout is %d\n", timeout);
 445 
 446         return NT_STATUS_OK;
 447 }
 448 
 449 
 450 static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 451                          int argc, const char **argv)
 452 {
 453         pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
 454         pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
 455 
 456         return cmd_set_ss_level();
 457 }
 458 
 459 static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 460                              int argc, const char **argv)
 461 {
 462         d_printf("Setting schannel - sign and seal\n");
 463         pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
 464         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 465 
 466         return cmd_set_ss_level();
 467 }
 468 
 469 static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 470                              int argc, const char **argv)
 471 {
 472         d_printf("Setting schannel - sign only\n");
 473         pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
 474         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
 475 
 476         return cmd_set_ss_level();
 477 }
 478 
 479 
 480 /* Built in rpcclient commands */
 481 
 482 static struct cmd_set rpcclient_commands[] = {
 483 
 484         { "GENERAL OPTIONS" },
 485 
 486         { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL,     NULL, NULL,   "Get help on commands", "[command]" },
 487         { "?",  RPC_RTYPE_NTSTATUS, cmd_help, NULL,       NULL, NULL,   "Get help on commands", "[command]" },
 488         { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,       NULL, "Set debug level", "level" },
 489         { "debug", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,    NULL, "Set debug level", "level" },
 490         { "list",       RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, NULL,       NULL, "List available commands on <pipe>", "pipe" },
 491         { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,   NULL,   NULL,   "Exit program", "" },
 492         { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,     NULL, NULL, "Exit program", "" },
 493         { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL,     NULL, NULL, "Force RPC pipe connections to be signed", "" },
 494         { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL,     NULL, NULL, "Force RPC pipe connections to be sealed", "" },
 495         { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL,     NULL, NULL,   "Force RPC pipe connections to be sealed with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
 496         { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL,    NULL, NULL, "Force RPC pipe connections to be signed (not sealed) with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
 497         { "timeout", RPC_RTYPE_NTSTATUS, cmd_timeout, NULL,       NULL, NULL, "Set timeout (in milliseonds) for RPC operations", "" },
 498         { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL,     NULL, NULL, "Force RPC pipe connections to have no special properties", "" },
 499 
 500         { NULL }
 501 };
 502 
 503 static struct cmd_set separator_command[] = {
 504         { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   NULL, NULL, "----------------------" },
 505         { NULL }
 506 };
 507 
 508 
 509 /* Various pipe commands */
 510 
 511 extern struct cmd_set lsarpc_commands[];
 512 extern struct cmd_set samr_commands[];
 513 extern struct cmd_set spoolss_commands[];
 514 extern struct cmd_set netlogon_commands[];
 515 extern struct cmd_set srvsvc_commands[];
 516 extern struct cmd_set dfs_commands[];
 517 extern struct cmd_set ds_commands[];
 518 extern struct cmd_set echo_commands[];
 519 extern struct cmd_set epmapper_commands[];
 520 extern struct cmd_set shutdown_commands[];
 521 extern struct cmd_set test_commands[];
 522 extern struct cmd_set wkssvc_commands[];
 523 extern struct cmd_set ntsvcs_commands[];
 524 extern struct cmd_set drsuapi_commands[];
 525 extern struct cmd_set eventlog_commands[];
 526 
 527 static struct cmd_set *rpcclient_command_list[] = {
 528         rpcclient_commands,
 529         lsarpc_commands,
 530         ds_commands,
 531         samr_commands,
 532         spoolss_commands,
 533         netlogon_commands,
 534         srvsvc_commands,
 535         dfs_commands,
 536         echo_commands,
 537         epmapper_commands,
 538         shutdown_commands,
 539         test_commands,
 540         wkssvc_commands,
 541         ntsvcs_commands,
 542         drsuapi_commands,
 543         eventlog_commands,
 544         NULL
 545 };
 546 
 547 static void add_command_set(struct cmd_set *cmd_set)
     /* [<][>][^][v][top][bottom][index][help] */
 548 {
 549         struct cmd_list *entry;
 550 
 551         if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
 552                 DEBUG(0, ("out of memory\n"));
 553                 return;
 554         }
 555 
 556         ZERO_STRUCTP(entry);
 557 
 558         entry->cmd_set = cmd_set;
 559         DLIST_ADD(cmd_list, entry);
 560 }
 561 
 562 
 563 /**
 564  * Call an rpcclient function, passing an argv array.
 565  *
 566  * @param cmd Command to run, as a single string.
 567  **/
 568 static NTSTATUS do_cmd(struct cli_state *cli,
     /* [<][>][^][v][top][bottom][index][help] */
 569                        struct user_auth_info *auth_info,
 570                        struct cmd_set *cmd_entry,
 571                        int argc, char **argv)
 572 {
 573         NTSTATUS ntresult;
 574         WERROR wresult;
 575         
 576         TALLOC_CTX *mem_ctx;
 577 
 578         /* Create mem_ctx */
 579 
 580         if (!(mem_ctx = talloc_init("do_cmd"))) {
 581                 DEBUG(0, ("talloc_init() failed\n"));
 582                 return NT_STATUS_NO_MEMORY;
 583         }
 584 
 585         /* Open pipe */
 586 
 587         if ((cmd_entry->interface != NULL) && (cmd_entry->rpc_pipe == NULL)) {
 588                 switch (pipe_default_auth_type) {
 589                         case PIPE_AUTH_TYPE_NONE:
 590                                 ntresult = cli_rpc_pipe_open_noauth(
 591                                         cli, cmd_entry->interface,
 592                                         &cmd_entry->rpc_pipe);
 593                                 break;
 594                         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
 595                                 ntresult = cli_rpc_pipe_open_spnego_ntlmssp(
 596                                         cli, cmd_entry->interface,
 597                                         NCACN_NP,
 598                                         pipe_default_auth_level,
 599                                         lp_workgroup(),
 600                                         get_cmdline_auth_info_username(auth_info),
 601                                         get_cmdline_auth_info_password(auth_info),
 602                                         &cmd_entry->rpc_pipe);
 603                                 break;
 604                         case PIPE_AUTH_TYPE_NTLMSSP:
 605                                 ntresult = cli_rpc_pipe_open_ntlmssp(
 606                                         cli, cmd_entry->interface,
 607                                         NCACN_NP,
 608                                         pipe_default_auth_level,
 609                                         lp_workgroup(),
 610                                         get_cmdline_auth_info_username(auth_info),
 611                                         get_cmdline_auth_info_password(auth_info),
 612                                         &cmd_entry->rpc_pipe);
 613                                 break;
 614                         case PIPE_AUTH_TYPE_SCHANNEL:
 615                                 ntresult = cli_rpc_pipe_open_schannel(
 616                                         cli, cmd_entry->interface,
 617                                         NCACN_NP,
 618                                         pipe_default_auth_level,
 619                                         lp_workgroup(),
 620                                         &cmd_entry->rpc_pipe);
 621                                 break;
 622                         default:
 623                                 DEBUG(0, ("Could not initialise %s. Invalid "
 624                                           "auth type %u\n",
 625                                           get_pipe_name_from_iface(
 626                                                   cmd_entry->interface),
 627                                           pipe_default_auth_type ));
 628                                 return NT_STATUS_UNSUCCESSFUL;
 629                 }
 630                 if (!NT_STATUS_IS_OK(ntresult)) {
 631                         DEBUG(0, ("Could not initialise %s. Error was %s\n",
 632                                   get_pipe_name_from_iface(
 633                                           cmd_entry->interface),
 634                                   nt_errstr(ntresult) ));
 635                         return ntresult;
 636                 }
 637 
 638                 if (ndr_syntax_id_equal(cmd_entry->interface,
 639                                         &ndr_table_netlogon.syntax_id)) {
 640                         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
 641                         uint32 sec_channel_type;
 642                         uchar trust_password[16];
 643         
 644                         if (!secrets_fetch_trust_account_password(lp_workgroup(),
 645                                                         trust_password,
 646                                                         NULL, &sec_channel_type)) {
 647                                 return NT_STATUS_UNSUCCESSFUL;
 648                         }
 649                 
 650                         ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
 651                                                 cli->desthost,   /* server name */
 652                                                 lp_workgroup(),  /* domain */
 653                                                 global_myname(), /* client name */
 654                                                 global_myname(), /* machine account name */
 655                                                 trust_password,
 656                                                 sec_channel_type,
 657                                                 &neg_flags);
 658 
 659                         if (!NT_STATUS_IS_OK(ntresult)) {
 660                                 DEBUG(0, ("Could not initialise credentials for %s.\n",
 661                                           get_pipe_name_from_iface(
 662                                                   cmd_entry->interface)));
 663                                 return ntresult;
 664                         }
 665                 }
 666         }
 667 
 668         /* Run command */
 669 
 670         if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
 671                 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
 672                 if (!NT_STATUS_IS_OK(ntresult)) {
 673                         printf("result was %s\n", nt_errstr(ntresult));
 674                 }
 675         } else {
 676                 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
 677                 /* print out the DOS error */
 678                 if (!W_ERROR_IS_OK(wresult)) {
 679                         printf( "result was %s\n", win_errstr(wresult));
 680                 }
 681                 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
 682         }
 683 
 684         /* Cleanup */
 685 
 686         talloc_destroy(mem_ctx);
 687 
 688         return ntresult;
 689 }
 690 
 691 
 692 /**
 693  * Process a command entered at the prompt or as part of -c
 694  *
 695  * @returns The NTSTATUS from running the command.
 696  **/
 697 static NTSTATUS process_cmd(struct user_auth_info *auth_info,
     /* [<][>][^][v][top][bottom][index][help] */
 698                             struct cli_state *cli, char *cmd)
 699 {
 700         struct cmd_list *temp_list;
 701         NTSTATUS result = NT_STATUS_OK;
 702         int ret;
 703         int argc;
 704         char **argv = NULL;
 705 
 706         if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
 707                 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
 708                 return NT_STATUS_UNSUCCESSFUL;
 709         }
 710 
 711 
 712         /* Walk through a dlist of arrays of commands. */
 713         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
 714                 struct cmd_set *temp_set = temp_list->cmd_set;
 715 
 716                 while (temp_set->name) {
 717                         if (strequal(argv[0], temp_set->name)) {
 718                                 if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
 719                          !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
 720                                         fprintf (stderr, "Invalid command\n");
 721                                         goto out_free;
 722                                 }
 723 
 724                                 result = do_cmd(cli, auth_info, temp_set,
 725                                                 argc, argv);
 726 
 727                                 goto out_free;
 728                         }
 729                         temp_set++;
 730                 }
 731         }
 732 
 733         if (argv[0]) {
 734                 printf("command not found: %s\n", argv[0]);
 735         }
 736 
 737 out_free:
 738 /* moved to do_cmd()
 739         if (!NT_STATUS_IS_OK(result)) {
 740                 printf("result was %s\n", nt_errstr(result));
 741         }
 742 */
 743 
 744         /* NOTE: popt allocates the whole argv, including the
 745          * strings, as a single block.  So a single free is
 746          * enough to release it -- we don't free the
 747          * individual strings.  rtfm. */
 748         free(argv);
 749 
 750         return result;
 751 }
 752 
 753 
 754 /* Main function */
 755 
 756  int main(int argc, char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 757 {
 758         int                     opt;
 759         static char             *cmdstr = NULL;
 760         const char *server;
 761         struct cli_state        *cli = NULL;
 762         static char             *opt_ipaddr=NULL;
 763         struct cmd_set          **cmd_set;
 764         struct sockaddr_storage server_ss;
 765         NTSTATUS                nt_status;
 766         static int              opt_port = 0;
 767         fstring new_workgroup;
 768         int result = 0;
 769         TALLOC_CTX *frame = talloc_stackframe();
 770         uint32_t flags = 0;
 771 
 772         /* make sure the vars that get altered (4th field) are in
 773            a fixed location or certain compilers complain */
 774         poptContext pc;
 775         struct poptOption long_options[] = {
 776                 POPT_AUTOHELP
 777                 {"command",     'c', POPT_ARG_STRING,   &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
 778                 {"dest-ip", 'I', POPT_ARG_STRING,   &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
 779                 {"port", 'p', POPT_ARG_INT,   &opt_port, 'p', "Specify port number", "PORT"},
 780                 POPT_COMMON_SAMBA
 781                 POPT_COMMON_CONNECTION
 782                 POPT_COMMON_CREDENTIALS
 783                 POPT_TABLEEND
 784         };
 785 
 786         load_case_tables();
 787 
 788         zero_sockaddr(&server_ss);
 789 
 790         setlinebuf(stdout);
 791 
 792         /* the following functions are part of the Samba debugging
 793            facilities.  See lib/debug.c */
 794         setup_logging("rpcclient", True);
 795 
 796         rpcclient_auth_info = user_auth_info_init(frame);
 797         if (rpcclient_auth_info == NULL) {
 798                 exit(1);
 799         }
 800         popt_common_set_auth_info(rpcclient_auth_info);
 801 
 802         /* Parse options */
 803 
 804         pc = poptGetContext("rpcclient", argc, (const char **) argv,
 805                             long_options, 0);
 806 
 807         if (argc == 1) {
 808                 poptPrintHelp(pc, stderr, 0);
 809                 goto done;
 810         }
 811 
 812         while((opt = poptGetNextOpt(pc)) != -1) {
 813                 switch (opt) {
 814 
 815                 case 'I':
 816                         if (!interpret_string_addr(&server_ss,
 817                                                 opt_ipaddr,
 818                                                 AI_NUMERICHOST)) {
 819                                 fprintf(stderr, "%s not a valid IP address\n",
 820                                         opt_ipaddr);
 821                                 result = 1;
 822                                 goto done;
 823                         }
 824                 }
 825         }
 826 
 827         /* Get server as remaining unparsed argument.  Print usage if more
 828            than one unparsed argument is present. */
 829 
 830         server = poptGetArg(pc);
 831 
 832         if (!server || poptGetArg(pc)) {
 833                 poptPrintHelp(pc, stderr, 0);
 834                 result = 1;
 835                 goto done;
 836         }
 837 
 838         poptFreeContext(pc);
 839 
 840         load_interfaces();
 841 
 842         if (!init_names()) {
 843                 result = 1;
 844                 goto done;
 845         }
 846 
 847         /* save the workgroup...
 848 
 849            FIXME!! do we need to do this for other options as well
 850            (or maybe a generic way to keep lp_load() from overwriting
 851            everything)?  */
 852 
 853         fstrcpy( new_workgroup, lp_workgroup() );
 854 
 855         /* Load smb.conf file */
 856 
 857         if (!lp_load(get_dyn_CONFIGFILE(),True,False,False,True))
 858                 fprintf(stderr, "Can't load %s\n", get_dyn_CONFIGFILE());
 859 
 860         if ( strlen(new_workgroup) != 0 )
 861                 set_global_myworkgroup( new_workgroup );
 862 
 863         /*
 864          * Get password
 865          * from stdin if necessary
 866          */
 867 
 868         if (get_cmdline_auth_info_use_machine_account(rpcclient_auth_info) &&
 869             !set_cmdline_auth_info_machine_account_creds(rpcclient_auth_info)) {
 870                 result = 1;
 871                 goto done;
 872         }
 873 
 874         set_cmdline_auth_info_getpass(rpcclient_auth_info);
 875 
 876         if ((server[0] == '/' && server[1] == '/') ||
 877                         (server[0] == '\\' && server[1] ==  '\\')) {
 878                 server += 2;
 879         }
 880 
 881         if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) {
 882                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
 883                          CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
 884         }
 885 
 886 
 887         nt_status = cli_full_connection(&cli, global_myname(), server,
 888                                         opt_ipaddr ? &server_ss : NULL, opt_port,
 889                                         "IPC$", "IPC",
 890                                         get_cmdline_auth_info_username(rpcclient_auth_info),
 891                                         lp_workgroup(),
 892                                         get_cmdline_auth_info_password(rpcclient_auth_info),
 893                                         flags,
 894                                         get_cmdline_auth_info_signing_state(rpcclient_auth_info),
 895                                         NULL);
 896 
 897         if (!NT_STATUS_IS_OK(nt_status)) {
 898                 DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
 899                 result = 1;
 900                 goto done;
 901         }
 902 
 903         if (get_cmdline_auth_info_smb_encrypt(rpcclient_auth_info)) {
 904                 nt_status = cli_cm_force_encryption(cli,
 905                                         get_cmdline_auth_info_username(rpcclient_auth_info),
 906                                         get_cmdline_auth_info_password(rpcclient_auth_info),
 907                                         lp_workgroup(),
 908                                         "IPC$");
 909                 if (!NT_STATUS_IS_OK(nt_status)) {
 910                         result = 1;
 911                         goto done;
 912                 }
 913         }
 914 
 915 #if 0   /* COMMENT OUT FOR TESTING */
 916         memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
 917 #endif
 918 
 919         /* Load command lists */
 920 
 921         timeout = cli_set_timeout(cli, 10000);
 922 
 923         cmd_set = rpcclient_command_list;
 924 
 925         while(*cmd_set) {
 926                 add_command_set(*cmd_set);
 927                 add_command_set(separator_command);
 928                 cmd_set++;
 929         }
 930 
 931         fetch_machine_sid(cli);
 932 
 933        /* Do anything specified with -c */
 934         if (cmdstr && cmdstr[0]) {
 935                 char    *cmd;
 936                 char    *p = cmdstr;
 937 
 938                 result = 0;
 939 
 940                 while((cmd=next_command(&p)) != NULL) {
 941                         NTSTATUS cmd_result = process_cmd(rpcclient_auth_info, cli, cmd);
 942                         SAFE_FREE(cmd);
 943                         result = NT_STATUS_IS_ERR(cmd_result);
 944                 }
 945 
 946                 goto done;
 947         }
 948 
 949         /* Loop around accepting commands */
 950 
 951         while(1) {
 952                 char *line = NULL;
 953 
 954                 line = smb_readline("rpcclient $> ", NULL, completion_fn);
 955 
 956                 if (line == NULL)
 957                         break;
 958 
 959                 if (line[0] != '\n')
 960                         process_cmd(rpcclient_auth_info, cli, line);
 961                 SAFE_FREE(line);
 962         }
 963 
 964 done:
 965         if (cli != NULL) {
 966                 cli_shutdown(cli);
 967         }
 968         TALLOC_FREE(frame);
 969         return result;
 970 }

/* [<][>][^][v][top][bottom][index][help] */