[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[samba.git] / source / rpcclient / rpcclient.c
index 4421e12054c5ba413f66d68770fa288b1d8ab08c..7a7b463b717087abbf15fb72129cbaacc1c1c724 100644 (file)
@@ -7,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -16,8 +16,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -27,6 +26,7 @@ DOM_SID domain_sid;
 
 static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
 static enum pipe_auth_level pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
+static unsigned int timeout = 0;
 
 /* List to hold groups of commands.
  *
@@ -58,35 +58,43 @@ static char **completion_fn(const char *text, int start, int end)
 #endif
 
        /* make sure we have a list of valid commands */
-       if (!commands) 
+       if (!commands) {
                return NULL;
+       }
 
        matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
-       if (!matches) return NULL;
+       if (!matches) {
+               return NULL;
+       }
 
        matches[count++] = SMB_STRDUP(text);
-       if (!matches[0]) return NULL;
+       if (!matches[0]) {
+               SAFE_FREE(matches);
+               return NULL;
+       }
 
-       while (commands && count < MAX_COMPLETIONS-1) 
-       {
-               if (!commands->cmd_set)
+       while (commands && count < MAX_COMPLETIONS-1) {
+               if (!commands->cmd_set) {
                        break;
+               }
                
-               for (i=0; commands->cmd_set[i].name; i++)
-               {
+               for (i=0; commands->cmd_set[i].name; i++) {
                        if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
                                (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS &&
                         commands->cmd_set[i].ntfn ) || 
                       ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
-                        commands->cmd_set[i].wfn)))
-                       {
+                        commands->cmd_set[i].wfn))) {
                                matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
-                               if (!matches[count]) 
+                               if (!matches[count]) {
+                                       for (i = 0; i < count; i++) {
+                                               SAFE_FREE(matches[count]);
+                                       }
+                                       SAFE_FREE(matches);
                                        return NULL;
+                               }
                                count++;
                        }
                }
-               
                commands = commands->next;
                
        }
@@ -99,9 +107,9 @@ static char **completion_fn(const char *text, int start, int end)
        return matches;
 }
 
-static char* next_command (char** cmdstr)
+static char *next_command (char **cmdstr)
 {
-       static pstring          command;
+       char *command;
        char                    *p;
        
        if (!cmdstr || !(*cmdstr))
@@ -110,7 +118,7 @@ static char* next_command (char** cmdstr)
        p = strchr_m(*cmdstr, ';');
        if (p)
                *p = '\0';
-       pstrcpy(command, *cmdstr);
+       command = SMB_STRDUP(*cmdstr);
        if (p)
                *cmdstr = p + 1;
        else
@@ -160,7 +168,7 @@ static void fetch_machine_sid(struct cli_state *cli)
        got_domain_sid = True;
        sid_copy( &domain_sid, dom_sid );
 
-       rpccli_lsa_close(lsapipe, mem_ctx, &pol);
+       rpccli_lsa_Close(lsapipe, mem_ctx, &pol);
        cli_rpc_pipe_close(lsapipe);
        talloc_destroy(mem_ctx);
 
@@ -390,6 +398,39 @@ static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
        return cmd_set_ss_level();
 }
 
+static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+                           int argc, const char **argv)
+{
+       struct cmd_list *tmp;
+
+       if (argc > 2) {
+               printf("Usage: %s timeout\n", argv[0]);
+               return NT_STATUS_OK;
+       }
+
+       if (argc == 2) {
+               timeout = atoi(argv[1]);
+
+               for (tmp = cmd_list; tmp; tmp = tmp->next) {
+                       
+                       struct cmd_set *tmp_set;
+
+                       for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
+                               if (tmp_set->rpc_pipe == NULL) {
+                                       continue;
+                               }
+
+                               cli_set_timeout(tmp_set->rpc_pipe->cli, timeout);
+                       }
+               }
+       }
+
+       printf("timeout is %d\n", timeout);
+
+       return NT_STATUS_OK;
+}
+
+
 static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                          int argc, const char **argv)
 {
@@ -429,6 +470,7 @@ static struct cmd_set rpcclient_commands[] = {
        { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL,     -1, NULL,     "Get help on commands", "[command]" },
        { "?",  RPC_RTYPE_NTSTATUS, cmd_help, NULL,       -1, NULL,     "Get help on commands", "[command]" },
        { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   -1, NULL, "Set debug level", "level" },
+       { "debug", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   -1,      NULL, "Set debug level", "level" },
        { "list",       RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, -1, NULL, "List available commands on <pipe>", "pipe" },
        { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,   -1,     NULL,   "Exit program", "" },
        { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,     -1,   NULL, "Exit program", "" },
@@ -436,6 +478,7 @@ static struct cmd_set rpcclient_commands[] = {
        { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL,     -1,   NULL, "Force RPC pipe connections to be sealed", "" },
        { "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.", "" },
        { "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.", "" },
+       { "timeout", RPC_RTYPE_NTSTATUS, cmd_timeout, NULL,       -1, NULL, "Set timeout (in milliseonds) for RPC operations", "" },
        { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL,     -1, NULL, "Force RPC pipe connections to have no special properties", "" },
 
        { NULL }
@@ -455,7 +498,6 @@ extern struct cmd_set spoolss_commands[];
 extern struct cmd_set netlogon_commands[];
 extern struct cmd_set srvsvc_commands[];
 extern struct cmd_set dfs_commands[];
-extern struct cmd_set reg_commands[];
 extern struct cmd_set ds_commands[];
 extern struct cmd_set echo_commands[];
 extern struct cmd_set shutdown_commands[];
@@ -470,7 +512,6 @@ static struct cmd_set *rpcclient_command_list[] = {
        netlogon_commands,
        srvsvc_commands,
        dfs_commands,
-       reg_commands,
        echo_commands,
        shutdown_commands,
        test_commands,
@@ -663,13 +704,11 @@ out_free:
        }
 */
 
-       if (argv) {
-               /* NOTE: popt allocates the whole argv, including the
-                * strings, as a single block.  So a single free is
-                * enough to release it -- we don't free the
-                * individual strings.  rtfm. */
-               free(argv);
-       }
+       /* NOTE: popt allocates the whole argv, including the
+        * strings, as a single block.  So a single free is
+        * enough to release it -- we don't free the
+        * individual strings.  rtfm. */
+       free(argv);
        
        return result;
 }
@@ -679,7 +718,6 @@ out_free:
 
  int main(int argc, char *argv[])
 {
-       BOOL                    interactive = True;
        int                     opt;
        static char             *cmdstr = NULL;
        const char *server;
@@ -689,6 +727,7 @@ out_free:
        struct in_addr          server_ip;
        NTSTATUS                nt_status;
        static int              opt_port = 0;
+       fstring new_workgroup;
 
        /* make sure the vars that get altered (4th field) are in
           a fixed location or certain compilers complain */
@@ -712,20 +751,8 @@ out_free:
 
        /* the following functions are part of the Samba debugging
           facilities.  See lib/debug.c */
-       setup_logging("rpcclient", interactive);
-       if (!interactive) 
-               reopen_logs();
+       setup_logging("rpcclient", True);
        
-       load_interfaces();
-
-       if (!init_names())
-               return 1;
-
-       /* Load smb.conf file */
-
-       if (!lp_load(dyn_CONFIGFILE,True,False,False,True))
-               fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
-
        /* Parse options */
 
        pc = poptGetContext("rpcclient", argc, (const char **) argv,
@@ -760,6 +787,27 @@ out_free:
 
        poptFreeContext(pc);
 
+       load_interfaces();
+
+       if (!init_names())
+               return 1;
+
+       /* save the workgroup...
+       
+          FIXME!! do we need to do this for other options as well 
+          (or maybe a generic way to keep lp_load() from overwriting 
+          everything)?  */
+       
+       fstrcpy( new_workgroup, lp_workgroup() );
+
+       /* Load smb.conf file */
+
+       if (!lp_load(dyn_CONFIGFILE,True,False,False,True))
+               fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
+
+       if ( strlen(new_workgroup) != 0 )
+               set_global_myworkgroup( new_workgroup );
+
        /*
         * Get password
         * from stdin if necessary
@@ -772,6 +820,11 @@ out_free:
                }
        }
        
+       if ((server[0] == '/' && server[1] == '/') ||
+                       (server[0] == '\\' && server[1] ==  '\\')) {
+               server += 2;
+       }
+
        nt_status = cli_full_connection(&cli, global_myname(), server, 
                                        opt_ipaddr ? &server_ip : NULL, opt_port,
                                        "IPC$", "IPC",  
@@ -792,6 +845,8 @@ out_free:
 
        /* Load command lists */
 
+       timeout = cli_set_timeout(cli, 10000);
+
        cmd_set = rpcclient_command_list;
 
        while(*cmd_set) {
@@ -810,6 +865,7 @@ out_free:
  
                 while((cmd=next_command(&p)) != NULL) {
                         NTSTATUS cmd_result = process_cmd(cli, cmd);
+                       SAFE_FREE(cmd);
                        result = NT_STATUS_IS_ERR(cmd_result);
                 }