rpcclient/rpcclient.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    RPC pipe client
00004 
00005    Copyright (C) Tim Potter 2000-2001
00006    Copyright (C) Martin Pool 2003
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 #include "rpcclient.h"
00025 
00026 DOM_SID domain_sid;
00027 
00028 static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
00029 static enum pipe_auth_level pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
00030 
00031 /* List to hold groups of commands.
00032  *
00033  * Commands are defined in a list of arrays: arrays are easy to
00034  * statically declare, and lists are easier to dynamically extend.
00035  */
00036 
00037 static struct cmd_list {
00038         struct cmd_list *prev, *next;
00039         struct cmd_set *cmd_set;
00040 } *cmd_list;
00041 
00042 /****************************************************************************
00043 handle completion of commands for readline
00044 ****************************************************************************/
00045 static char **completion_fn(const char *text, int start, int end)
00046 {
00047 #define MAX_COMPLETIONS 100
00048         char **matches;
00049         int i, count=0;
00050         struct cmd_list *commands = cmd_list;
00051 
00052 #if 0   /* JERRY */
00053         /* FIXME!!!  -- what to do when completing argument? */
00054         /* for words not at the start of the line fallback 
00055            to filename completion */
00056         if (start) 
00057                 return NULL;
00058 #endif
00059 
00060         /* make sure we have a list of valid commands */
00061         if (!commands) {
00062                 return NULL;
00063         }
00064 
00065         matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
00066         if (!matches) {
00067                 return NULL;
00068         }
00069 
00070         matches[count++] = SMB_STRDUP(text);
00071         if (!matches[0]) {
00072                 SAFE_FREE(matches);
00073                 return NULL;
00074         }
00075 
00076         while (commands && count < MAX_COMPLETIONS-1) {
00077                 if (!commands->cmd_set) {
00078                         break;
00079                 }
00080                 
00081                 for (i=0; commands->cmd_set[i].name; i++) {
00082                         if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
00083                                 (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
00084                         commands->cmd_set[i].ntfn ) || 
00085                       ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
00086                         commands->cmd_set[i].wfn))) {
00087                                 matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
00088                                 if (!matches[count]) {
00089                                         for (i = 0; i < count; i++) {
00090                                                 SAFE_FREE(matches[count]);
00091                                         }
00092                                         SAFE_FREE(matches);
00093                                         return NULL;
00094                                 }
00095                                 count++;
00096                         }
00097                 }
00098                 commands = commands->next;
00099                 
00100         }
00101 
00102         if (count == 2) {
00103                 SAFE_FREE(matches[0]);
00104                 matches[0] = SMB_STRDUP(matches[1]);
00105         }
00106         matches[count] = NULL;
00107         return matches;
00108 }
00109 
00110 static char *next_command (char **cmdstr)
00111 {
00112         char *command;
00113         char                    *p;
00114         
00115         if (!cmdstr || !(*cmdstr))
00116                 return NULL;
00117         
00118         p = strchr_m(*cmdstr, ';');
00119         if (p)
00120                 *p = '\0';
00121         command = SMB_STRDUP(*cmdstr);
00122         if (p)
00123                 *cmdstr = p + 1;
00124         else
00125                 *cmdstr = NULL;
00126         
00127         return command;
00128 }
00129 
00130 /* Fetch the SID for this computer */
00131 
00132 static void fetch_machine_sid(struct cli_state *cli)
00133 {
00134         POLICY_HND pol;
00135         NTSTATUS result = NT_STATUS_OK;
00136         uint32 info_class = 5;
00137         char *domain_name = NULL;
00138         static BOOL got_domain_sid;
00139         TALLOC_CTX *mem_ctx;
00140         DOM_SID *dom_sid = NULL;
00141         struct rpc_pipe_client *lsapipe = NULL;
00142 
00143         if (got_domain_sid) return;
00144 
00145         if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
00146                 DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
00147                 goto error;
00148         }
00149 
00150         if ((lsapipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result)) == NULL) {
00151                 fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
00152                 goto error;
00153         }
00154         
00155         result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True, 
00156                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
00157                                      &pol);
00158         if (!NT_STATUS_IS_OK(result)) {
00159                 goto error;
00160         }
00161 
00162         result = rpccli_lsa_query_info_policy(lsapipe, mem_ctx, &pol, info_class, 
00163                                            &domain_name, &dom_sid);
00164         if (!NT_STATUS_IS_OK(result)) {
00165                 goto error;
00166         }
00167 
00168         got_domain_sid = True;
00169         sid_copy( &domain_sid, dom_sid );
00170 
00171         rpccli_lsa_close(lsapipe, mem_ctx, &pol);
00172         cli_rpc_pipe_close(lsapipe);
00173         talloc_destroy(mem_ctx);
00174 
00175         return;
00176 
00177  error:
00178 
00179         if (lsapipe) {
00180                 cli_rpc_pipe_close(lsapipe);
00181         }
00182 
00183         fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
00184 
00185         if (!NT_STATUS_IS_OK(result)) {
00186                 fprintf(stderr, "error: %s\n", nt_errstr(result));
00187         }
00188 
00189         exit(1);
00190 }
00191 
00192 /* List the available commands on a given pipe */
00193 
00194 static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00195                                  int argc, const char **argv)
00196 {
00197         struct cmd_list *tmp;
00198         struct cmd_set *tmp_set;
00199         int i;
00200 
00201         /* Usage */
00202 
00203         if (argc != 2) {
00204                 printf("Usage: %s <pipe>\n", argv[0]);
00205                 return NT_STATUS_OK;
00206         }
00207 
00208         /* Help on one command */
00209 
00210         for (tmp = cmd_list; tmp; tmp = tmp->next) 
00211         {
00212                 tmp_set = tmp->cmd_set;
00213                 
00214                 if (!StrCaseCmp(argv[1], tmp_set->name))
00215                 {
00216                         printf("Available commands on the %s pipe:\n\n", tmp_set->name);
00217 
00218                         i = 0;
00219                         tmp_set++;
00220                         while(tmp_set->name) {
00221                                 printf("%30s", tmp_set->name);
00222                                 tmp_set++;
00223                                 i++;
00224                                 if (i%3 == 0)
00225                                         printf("\n");
00226                         }
00227                         
00228                         /* drop out of the loop */
00229                         break;
00230                 }
00231         }
00232         printf("\n\n");
00233 
00234         return NT_STATUS_OK;
00235 }
00236 
00237 /* Display help on commands */
00238 
00239 static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00240                          int argc, const char **argv)
00241 {
00242         struct cmd_list *tmp;
00243         struct cmd_set *tmp_set;
00244 
00245         /* Usage */
00246 
00247         if (argc > 2) {
00248                 printf("Usage: %s [command]\n", argv[0]);
00249                 return NT_STATUS_OK;
00250         }
00251 
00252         /* Help on one command */
00253 
00254         if (argc == 2) {
00255                 for (tmp = cmd_list; tmp; tmp = tmp->next) {
00256                         
00257                         tmp_set = tmp->cmd_set;
00258 
00259                         while(tmp_set->name) {
00260                                 if (strequal(argv[1], tmp_set->name)) {
00261                                         if (tmp_set->usage &&
00262                                             tmp_set->usage[0])
00263                                                 printf("%s\n", tmp_set->usage);
00264                                         else
00265                                                 printf("No help for %s\n", tmp_set->name);
00266 
00267                                         return NT_STATUS_OK;
00268                                 }
00269 
00270                                 tmp_set++;
00271                         }
00272                 }
00273 
00274                 printf("No such command: %s\n", argv[1]);
00275                 return NT_STATUS_OK;
00276         }
00277 
00278         /* List all commands */
00279 
00280         for (tmp = cmd_list; tmp; tmp = tmp->next) {
00281 
00282                 tmp_set = tmp->cmd_set;
00283 
00284                 while(tmp_set->name) {
00285 
00286                         printf("%15s\t\t%s\n", tmp_set->name,
00287                                tmp_set->description ? tmp_set->description:
00288                                "");
00289 
00290                         tmp_set++;
00291                 }
00292         }
00293 
00294         return NT_STATUS_OK;
00295 }
00296 
00297 /* Change the debug level */
00298 
00299 static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00300                                int argc, const char **argv)
00301 {
00302         if (argc > 2) {
00303                 printf("Usage: %s [debuglevel]\n", argv[0]);
00304                 return NT_STATUS_OK;
00305         }
00306 
00307         if (argc == 2) {
00308                 DEBUGLEVEL = atoi(argv[1]);
00309         }
00310 
00311         printf("debuglevel is %d\n", DEBUGLEVEL);
00312 
00313         return NT_STATUS_OK;
00314 }
00315 
00316 static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00317                          int argc, const char **argv)
00318 {
00319         exit(0);
00320         return NT_STATUS_OK; /* NOTREACHED */
00321 }
00322 
00323 static NTSTATUS cmd_set_ss_level(void)
00324 {
00325         struct cmd_list *tmp;
00326 
00327         /* Close any existing connections not at this level. */
00328 
00329         for (tmp = cmd_list; tmp; tmp = tmp->next) {
00330                 struct cmd_set *tmp_set;
00331 
00332                 for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
00333                         if (tmp_set->rpc_pipe == NULL) {
00334                                 continue;
00335                         }
00336 
00337                         if (tmp_set->rpc_pipe->auth.auth_type != pipe_default_auth_type ||
00338                                         tmp_set->rpc_pipe->auth.auth_level != pipe_default_auth_level) {
00339                                 cli_rpc_pipe_close(tmp_set->rpc_pipe);
00340                                 tmp_set->rpc_pipe = NULL;
00341                         }
00342                 }
00343         }
00344         return NT_STATUS_OK;
00345 }
00346 
00347 static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00348                          int argc, const char **argv)
00349 {
00350         pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
00351         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
00352 
00353         if (argc > 2) {
00354                 printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
00355                 return NT_STATUS_OK;
00356         }
00357 
00358         if (argc == 2) {
00359                 if (strequal(argv[1], "NTLMSSP")) {
00360                         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
00361                 } else if (strequal(argv[1], "NTLMSSP_SPNEGO")) {
00362                         pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
00363                 } else if (strequal(argv[1], "SCHANNEL")) {
00364                         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
00365                 } else {
00366                         printf("unknown type %s\n", argv[1]);
00367                         return NT_STATUS_INVALID_LEVEL;
00368                 }
00369         }
00370 
00371         printf("debuglevel is %d\n", DEBUGLEVEL);
00372         return cmd_set_ss_level();
00373 }
00374 
00375 static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00376                          int argc, const char **argv)
00377 {
00378         pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
00379         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
00380 
00381         if (argc > 2) {
00382                 printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
00383                 return NT_STATUS_OK;
00384         }
00385 
00386         if (argc == 2) {
00387                 if (strequal(argv[1], "NTLMSSP")) {
00388                         pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
00389                 } else if (strequal(argv[1], "NTLMSSP_SPNEGO")) {
00390                         pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
00391                 } else if (strequal(argv[1], "SCHANNEL")) {
00392                         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
00393                 } else {
00394                         printf("unknown type %s\n", argv[1]);
00395                         return NT_STATUS_INVALID_LEVEL;
00396                 }
00397         }
00398         return cmd_set_ss_level();
00399 }
00400 
00401 static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00402                          int argc, const char **argv)
00403 {
00404         pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
00405         pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
00406 
00407         return cmd_set_ss_level();
00408 }
00409 
00410 static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00411                              int argc, const char **argv)
00412 {
00413         d_printf("Setting schannel - sign and seal\n");
00414         pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
00415         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
00416 
00417         return cmd_set_ss_level();
00418 }
00419 
00420 static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
00421                              int argc, const char **argv)
00422 {
00423         d_printf("Setting schannel - sign only\n");
00424         pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
00425         pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
00426 
00427         return cmd_set_ss_level();
00428 }
00429 
00430 
00431 /* Built in rpcclient commands */
00432 
00433 static struct cmd_set rpcclient_commands[] = {
00434 
00435         { "GENERAL OPTIONS" },
00436 
00437         { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL,     -1, NULL,     "Get help on commands", "[command]" },
00438         { "?",  RPC_RTYPE_NTSTATUS, cmd_help, NULL,       -1, NULL,     "Get help on commands", "[command]" },
00439         { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   -1, NULL, "Set debug level", "level" },
00440         { "list",       RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, -1, NULL, "List available commands on <pipe>", "pipe" },
00441         { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,   -1,     NULL,   "Exit program", "" },
00442         { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,     -1,   NULL, "Exit program", "" },
00443         { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL,     -1,   NULL, "Force RPC pipe connections to be signed", "" },
00444         { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL,     -1,   NULL, "Force RPC pipe connections to be sealed", "" },
00445         { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL,     -1, NULL,     "Force RPC pipe connections to be sealed with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
00446         { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL,    -1, NULL, "Force RPC pipe connections to be signed (not sealed) with 'schannel'.  Assumes valid machine account to this domain controller.", "" },
00447         { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL,     -1, NULL, "Force RPC pipe connections to have no special properties", "" },
00448 
00449         { NULL }
00450 };
00451 
00452 static struct cmd_set separator_command[] = {
00453         { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   -1, NULL, "----------------------" },
00454         { NULL }
00455 };
00456 
00457 
00458 /* Various pipe commands */
00459 
00460 extern struct cmd_set lsarpc_commands[];
00461 extern struct cmd_set samr_commands[];
00462 extern struct cmd_set spoolss_commands[];
00463 extern struct cmd_set netlogon_commands[];
00464 extern struct cmd_set srvsvc_commands[];
00465 extern struct cmd_set dfs_commands[];
00466 extern struct cmd_set ds_commands[];
00467 extern struct cmd_set echo_commands[];
00468 extern struct cmd_set shutdown_commands[];
00469 extern struct cmd_set test_commands[];
00470 
00471 static struct cmd_set *rpcclient_command_list[] = {
00472         rpcclient_commands,
00473         lsarpc_commands,
00474         ds_commands,
00475         samr_commands,
00476         spoolss_commands,
00477         netlogon_commands,
00478         srvsvc_commands,
00479         dfs_commands,
00480         echo_commands,
00481         shutdown_commands,
00482         test_commands,
00483         NULL
00484 };
00485 
00486 static void add_command_set(struct cmd_set *cmd_set)
00487 {
00488         struct cmd_list *entry;
00489 
00490         if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
00491                 DEBUG(0, ("out of memory\n"));
00492                 return;
00493         }
00494 
00495         ZERO_STRUCTP(entry);
00496 
00497         entry->cmd_set = cmd_set;
00498         DLIST_ADD(cmd_list, entry);
00499 }
00500 
00501 
00502 /**
00503  * Call an rpcclient function, passing an argv array.
00504  *
00505  * @param cmd Command to run, as a single string.
00506  **/
00507 static NTSTATUS do_cmd(struct cli_state *cli,
00508                        struct cmd_set *cmd_entry,
00509                        int argc, char **argv)
00510 {
00511         NTSTATUS ntresult;
00512         WERROR wresult;
00513         
00514         TALLOC_CTX *mem_ctx;
00515 
00516         /* Create mem_ctx */
00517 
00518         if (!(mem_ctx = talloc_init("do_cmd"))) {
00519                 DEBUG(0, ("talloc_init() failed\n"));
00520                 return NT_STATUS_NO_MEMORY;
00521         }
00522 
00523         /* Open pipe */
00524 
00525         if (cmd_entry->pipe_idx != -1 && cmd_entry->rpc_pipe == NULL) {
00526                 switch (pipe_default_auth_type) {
00527                         case PIPE_AUTH_TYPE_NONE:
00528                                 cmd_entry->rpc_pipe = cli_rpc_pipe_open_noauth(cli,
00529                                                                 cmd_entry->pipe_idx,
00530                                                                 &ntresult);
00531                                 break;
00532                         case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
00533                                 cmd_entry->rpc_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli,
00534                                                                 cmd_entry->pipe_idx,
00535                                                                 pipe_default_auth_level,
00536                                                                 lp_workgroup(),
00537                                                                 cmdline_auth_info.username,
00538                                                                 cmdline_auth_info.password,
00539                                                                 &ntresult);
00540                                 break;
00541                         case PIPE_AUTH_TYPE_NTLMSSP:
00542                                 cmd_entry->rpc_pipe = cli_rpc_pipe_open_ntlmssp(cli,
00543                                                                 cmd_entry->pipe_idx,
00544                                                                 pipe_default_auth_level,
00545                                                                 lp_workgroup(),
00546                                                                 cmdline_auth_info.username,
00547                                                                 cmdline_auth_info.password,
00548                                                                 &ntresult);
00549                                 break;
00550                         case PIPE_AUTH_TYPE_SCHANNEL:
00551                                 cmd_entry->rpc_pipe = cli_rpc_pipe_open_schannel(cli,
00552                                                                 cmd_entry->pipe_idx,
00553                                                                 pipe_default_auth_level,
00554                                                                 lp_workgroup(),
00555                                                                 &ntresult);
00556                                 break;
00557                         default:
00558                                 DEBUG(0, ("Could not initialise %s. Invalid auth type %u\n",
00559                                         cli_get_pipe_name(cmd_entry->pipe_idx),
00560                                         pipe_default_auth_type ));
00561                                 return NT_STATUS_UNSUCCESSFUL;
00562                 }
00563                 if (!cmd_entry->rpc_pipe) {
00564                         DEBUG(0, ("Could not initialise %s. Error was %s\n",
00565                                 cli_get_pipe_name(cmd_entry->pipe_idx),
00566                                 nt_errstr(ntresult) ));
00567                         return ntresult;
00568                 }
00569 
00570                 if (cmd_entry->pipe_idx == PI_NETLOGON) {
00571                         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
00572                         uint32 sec_channel_type;
00573                         uchar trust_password[16];
00574         
00575                         if (!secrets_fetch_trust_account_password(lp_workgroup(),
00576                                                         trust_password,
00577                                                         NULL, &sec_channel_type)) {
00578                                 return NT_STATUS_UNSUCCESSFUL;
00579                         }
00580                 
00581                         ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
00582                                                 cli->desthost,   /* server name */
00583                                                 lp_workgroup(),  /* domain */
00584                                                 global_myname(), /* client name */
00585                                                 global_myname(), /* machine account name */
00586                                                 trust_password,
00587                                                 sec_channel_type,
00588                                                 &neg_flags);
00589 
00590                         if (!NT_STATUS_IS_OK(ntresult)) {
00591                                 DEBUG(0, ("Could not initialise credentials for %s.\n",
00592                                         cli_get_pipe_name(cmd_entry->pipe_idx)));
00593                                 return ntresult;
00594                         }
00595                 }
00596         }
00597 
00598         /* Run command */
00599 
00600         if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
00601                 ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
00602                 if (!NT_STATUS_IS_OK(ntresult)) {
00603                         printf("result was %s\n", nt_errstr(ntresult));
00604                 }
00605         } else {
00606                 wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
00607                 /* print out the DOS error */
00608                 if (!W_ERROR_IS_OK(wresult)) {
00609                         printf( "result was %s\n", dos_errstr(wresult));
00610                 }
00611                 ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
00612         }
00613 
00614         /* Cleanup */
00615 
00616         talloc_destroy(mem_ctx);
00617 
00618         return ntresult;
00619 }
00620 
00621 
00622 /**
00623  * Process a command entered at the prompt or as part of -c
00624  *
00625  * @returns The NTSTATUS from running the command.
00626  **/
00627 static NTSTATUS process_cmd(struct cli_state *cli, char *cmd)
00628 {
00629         struct cmd_list *temp_list;
00630         NTSTATUS result = NT_STATUS_OK;
00631         int ret;
00632         int argc;
00633         char **argv = NULL;
00634 
00635         if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
00636                 fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
00637                 return NT_STATUS_UNSUCCESSFUL;
00638         }
00639 
00640 
00641         /* Walk through a dlist of arrays of commands. */
00642         for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
00643                 struct cmd_set *temp_set = temp_list->cmd_set;
00644 
00645                 while (temp_set->name) {
00646                         if (strequal(argv[0], temp_set->name)) {
00647                                 if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
00648                          !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
00649                                         fprintf (stderr, "Invalid command\n");
00650                                         goto out_free;
00651                                 }
00652 
00653                                 result = do_cmd(cli, temp_set, argc, argv);
00654 
00655                                 goto out_free;
00656                         }
00657                         temp_set++;
00658                 }
00659         }
00660 
00661         if (argv[0]) {
00662                 printf("command not found: %s\n", argv[0]);
00663         }
00664 
00665 out_free:
00666 /* moved to do_cmd()
00667         if (!NT_STATUS_IS_OK(result)) {
00668                 printf("result was %s\n", nt_errstr(result));
00669         }
00670 */
00671 
00672         /* NOTE: popt allocates the whole argv, including the
00673          * strings, as a single block.  So a single free is
00674          * enough to release it -- we don't free the
00675          * individual strings.  rtfm. */
00676         free(argv);
00677         
00678         return result;
00679 }
00680 
00681 
00682 /* Main function */
00683 
00684  int main(int argc, char *argv[])
00685 {
00686         int                     opt;
00687         static char             *cmdstr = NULL;
00688         const char *server;
00689         struct cli_state        *cli;
00690         static char             *opt_ipaddr=NULL;
00691         struct cmd_set          **cmd_set;
00692         struct in_addr          server_ip;
00693         NTSTATUS                nt_status;
00694         static int              opt_port = 0;
00695         fstring new_workgroup;
00696 
00697         /* make sure the vars that get altered (4th field) are in
00698            a fixed location or certain compilers complain */
00699         poptContext pc;
00700         struct poptOption long_options[] = {
00701                 POPT_AUTOHELP
00702                 {"command",     'c', POPT_ARG_STRING,   &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
00703                 {"dest-ip", 'I', POPT_ARG_STRING,   &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
00704                 {"port", 'p', POPT_ARG_INT,   &opt_port, 'p', "Specify port number", "PORT"},
00705                 POPT_COMMON_SAMBA
00706                 POPT_COMMON_CONNECTION
00707                 POPT_COMMON_CREDENTIALS
00708                 POPT_TABLEEND
00709         };
00710 
00711         load_case_tables();
00712 
00713         ZERO_STRUCT(server_ip);
00714 
00715         setlinebuf(stdout);
00716 
00717         /* the following functions are part of the Samba debugging
00718            facilities.  See lib/debug.c */
00719         setup_logging("rpcclient", True);
00720         
00721         /* Parse options */
00722 
00723         pc = poptGetContext("rpcclient", argc, (const char **) argv,
00724                             long_options, 0);
00725 
00726         if (argc == 1) {
00727                 poptPrintHelp(pc, stderr, 0);
00728                 return 0;
00729         }
00730         
00731         while((opt = poptGetNextOpt(pc)) != -1) {
00732                 switch (opt) {
00733 
00734                 case 'I':
00735                         if ( (server_ip.s_addr=inet_addr(opt_ipaddr)) == INADDR_NONE ) {
00736                                 fprintf(stderr, "%s not a valid IP address\n",
00737                                         opt_ipaddr);
00738                                 return 1;
00739                         }
00740                 }
00741         }
00742 
00743         /* Get server as remaining unparsed argument.  Print usage if more
00744            than one unparsed argument is present. */
00745 
00746         server = poptGetArg(pc);
00747         
00748         if (!server || poptGetArg(pc)) {
00749                 poptPrintHelp(pc, stderr, 0);
00750                 return 1;
00751         }
00752 
00753         poptFreeContext(pc);
00754 
00755         load_interfaces();
00756 
00757         if (!init_names())
00758                 return 1;
00759 
00760         /* save the workgroup...
00761         
00762            FIXME!! do we need to do this for other options as well 
00763            (or maybe a generic way to keep lp_load() from overwriting 
00764            everything)?  */
00765         
00766         fstrcpy( new_workgroup, lp_workgroup() );
00767 
00768         /* Load smb.conf file */
00769 
00770         if (!lp_load(dyn_CONFIGFILE,True,False,False,True))
00771                 fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
00772 
00773         if ( strlen(new_workgroup) != 0 )
00774                 set_global_myworkgroup( new_workgroup );
00775 
00776         /*
00777          * Get password
00778          * from stdin if necessary
00779          */
00780 
00781         if (!cmdline_auth_info.got_pass) {
00782                 char *pass = getpass("Password:");
00783                 if (pass) {
00784                         pstrcpy(cmdline_auth_info.password, pass);
00785                 }
00786         }
00787         
00788         if ((server[0] == '/' && server[1] == '/') ||
00789                         (server[0] == '\\' && server[1] ==  '\\')) {
00790                 server += 2;
00791         }
00792 
00793         nt_status = cli_full_connection(&cli, global_myname(), server, 
00794                                         opt_ipaddr ? &server_ip : NULL, opt_port,
00795                                         "IPC$", "IPC",  
00796                                         cmdline_auth_info.username, 
00797                                         lp_workgroup(),
00798                                         cmdline_auth_info.password, 
00799                                         cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
00800                                         cmdline_auth_info.signing_state,NULL);
00801         
00802         if (!NT_STATUS_IS_OK(nt_status)) {
00803                 DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
00804                 return 1;
00805         }
00806 
00807 #if 0   /* COMMENT OUT FOR TESTING */
00808         memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
00809 #endif
00810 
00811         /* Load command lists */
00812 
00813         cmd_set = rpcclient_command_list;
00814 
00815         while(*cmd_set) {
00816                 add_command_set(*cmd_set);
00817                 add_command_set(separator_command);
00818                 cmd_set++;
00819         }
00820 
00821         fetch_machine_sid(cli);
00822  
00823        /* Do anything specified with -c */
00824         if (cmdstr && cmdstr[0]) {
00825                 char    *cmd;
00826                 char    *p = cmdstr;
00827                 int result = 0;
00828  
00829                 while((cmd=next_command(&p)) != NULL) {
00830                         NTSTATUS cmd_result = process_cmd(cli, cmd);
00831                         SAFE_FREE(cmd);
00832                         result = NT_STATUS_IS_ERR(cmd_result);
00833                 }
00834                 
00835                 cli_shutdown(cli);
00836                 return result;
00837         }
00838 
00839         /* Loop around accepting commands */
00840 
00841         while(1) {
00842                 pstring prompt;
00843                 char *line;
00844 
00845                 slprintf(prompt, sizeof(prompt) - 1, "rpcclient $> ");
00846 
00847                 line = smb_readline(prompt, NULL, completion_fn);
00848 
00849                 if (line == NULL)
00850                         break;
00851 
00852                 if (line[0] != '\n')
00853                         process_cmd(cli, line);
00854         }
00855         
00856         cli_shutdown(cli);
00857         return 0;
00858 }

Sambaに対してSat Aug 29 21:23:23 2009に生成されました。  doxygen 1.4.7