smbd: Remove unused [push_pull]_file_id_24
[samba.git] / source3 / rpcclient / rpcclient.c
index 0dad971c9688d7772d226b0f30dd0f0bfc5e4d7b..eed8e4654f2414fdf2c3ad87d196e059855731ee 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    RPC pipe client
 
@@ -20,7 +20,7 @@
 */
 
 #include "includes.h"
-#include "popt_common.h"
+#include "../libcli/auth/netlogon_creds_cli.h"
 #include "rpcclient.h"
 #include "../libcli/auth/libcli_auth.h"
 #include "../librpc/gen_ndr/ndr_lsa_c.h"
 #include "libsmb/libsmb.h"
 #include "auth/gensec/gensec.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "messages.h"
+#include "cmdline_contexts.h"
+#include "../librpc/gen_ndr/ndr_samr.h"
+#include "lib/cmdline/cmdline.h"
+#include "lib/param/param.h"
 
 enum pipe_auth_type_spnego {
        PIPE_AUTH_TYPE_SPNEGO_NONE = 0,
@@ -40,15 +45,11 @@ enum pipe_auth_type_spnego {
        PIPE_AUTH_TYPE_SPNEGO_KRB5
 };
 
-struct dom_sid domain_sid;
+static unsigned int timeout = 10000;
 
-static enum dcerpc_AuthType pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
-static enum pipe_auth_type_spnego pipe_default_auth_spnego_type = 0;
-static enum dcerpc_AuthLevel pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
-static unsigned int timeout = 0;
-static enum dcerpc_transport_t default_transport = NCACN_NP;
-
-struct user_auth_info *rpcclient_auth_info;
+struct messaging_context *rpcclient_msg_ctx;
+struct netlogon_creds_cli_context *rpcclient_netlogon_creds;
+static const char *rpcclient_netlogon_domain;
 
 /* List to hold groups of commands.
  *
@@ -68,14 +69,14 @@ static char **completion_fn(const char *text, int start, int end)
 {
 #define MAX_COMPLETIONS 1000
        char **matches;
-       int i, count=0;
+       size_t i, count=0;
        struct cmd_list *commands = cmd_list;
 
 #if 0  /* JERRY */
        /* FIXME!!!  -- what to do when completing argument? */
-       /* for words not at the start of the line fallback 
+       /* for words not at the start of the line fallback
           to filename completion */
-       if (start) 
+       if (start)
                return NULL;
 #endif
 
@@ -103,7 +104,7 @@ static char **completion_fn(const char *text, int start, int end)
                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].ntfn ) ||
                       ( commands->cmd_set[i].returntype == RPC_RTYPE_WERROR &&
                         commands->cmd_set[i].wfn))) {
                                matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
@@ -148,76 +149,71 @@ static char *next_command (char **cmdstr)
        return command;
 }
 
-/* Fetch the SID for this computer */
-
-static void fetch_machine_sid(struct cli_state *cli)
+static void binding_get_auth_info(
+       const struct dcerpc_binding *b,
+       enum dcerpc_AuthType *_auth_type,
+       enum dcerpc_AuthLevel *_auth_level,
+       enum credentials_use_kerberos *_krb5_state)
 {
-       struct policy_handle pol;
-       NTSTATUS result = NT_STATUS_OK, status;
-       static bool got_domain_sid;
-       TALLOC_CTX *mem_ctx;
-       struct rpc_pipe_client *lsapipe = NULL;
-       union lsa_PolicyInformation *info = NULL;
-       struct dcerpc_binding_handle *b;
+       uint32_t bflags = dcerpc_binding_get_flags(b);
+       enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
+       enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
+       enum credentials_use_kerberos krb5_state = CRED_USE_KERBEROS_DESIRED;
 
-       if (got_domain_sid) return;
-
-       if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
-               DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
-               goto error;
+       if (_krb5_state != NULL) {
+               krb5_state = *_krb5_state;
        }
 
-       result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
-                                         &lsapipe);
-       if (!NT_STATUS_IS_OK(result)) {
-               fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
-               goto error;
+       if (bflags & DCERPC_CONNECT) {
+               auth_level = DCERPC_AUTH_LEVEL_CONNECT;
        }
-
-       b = lsapipe->binding_handle;
-
-       result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True, 
-                                    SEC_FLAG_MAXIMUM_ALLOWED,
-                                    &pol);
-       if (!NT_STATUS_IS_OK(result)) {
-               goto error;
+       if (bflags & DCERPC_PACKET) {
+               auth_level = DCERPC_AUTH_LEVEL_PACKET;
        }
-
-       status = dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
-                                           &pol,
-                                           LSA_POLICY_INFO_ACCOUNT_DOMAIN,
-                                           &info,
-                                           &result);
-       if (!NT_STATUS_IS_OK(status)) {
-               result = status;
-               goto error;
+       if (bflags & DCERPC_SIGN) {
+               auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
        }
-       if (!NT_STATUS_IS_OK(result)) {
-               goto error;
+       if (bflags & DCERPC_SEAL) {
+               auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
        }
 
-       got_domain_sid = True;
-       sid_copy(&domain_sid, info->account_domain.sid);
-
-       dcerpc_lsa_Close(b, mem_ctx, &pol, &result);
-       TALLOC_FREE(lsapipe);
-       talloc_destroy(mem_ctx);
+       if (bflags & DCERPC_SCHANNEL) {
+               auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
+       }
 
-       return;
+       if ((auth_level != DCERPC_AUTH_LEVEL_NONE) &&
+           (auth_type == DCERPC_AUTH_TYPE_NONE)) {
+               auth_type = (krb5_state == CRED_USE_KERBEROS_REQUIRED) ?
+                       DCERPC_AUTH_TYPE_KRB5 : DCERPC_AUTH_TYPE_NTLMSSP;
+       }
 
- error:
+       if (bflags & DCERPC_AUTH_SPNEGO) {
+               auth_type = DCERPC_AUTH_TYPE_SPNEGO;
 
-       if (lsapipe) {
-               TALLOC_FREE(lsapipe);
+               if (bflags & DCERPC_AUTH_NTLM) {
+                       krb5_state = CRED_USE_KERBEROS_DISABLED;
+               }
+               if (bflags & DCERPC_AUTH_KRB5) {
+                       krb5_state = CRED_USE_KERBEROS_REQUIRED;
+               }
        }
 
-       fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
-
-       if (!NT_STATUS_IS_OK(result)) {
-               fprintf(stderr, "error: %s\n", nt_errstr(result));
+       if (auth_type != DCERPC_AUTH_TYPE_NONE) {
+               /* If nothing is requested then default to integrity */
+               if (auth_level == DCERPC_AUTH_LEVEL_NONE) {
+                       auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
+               }
        }
 
-       exit(1);
+       if (_auth_type != NULL) {
+               *_auth_type = auth_type;
+       }
+       if (_auth_level != NULL) {
+               *_auth_level = auth_level;
+       }
+       if (_krb5_state != NULL) {
+               *_krb5_state = krb5_state;
+       }
 }
 
 /* List the available commands on a given pipe */
@@ -238,7 +234,7 @@ static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct
 
         /* Help on one command */
 
-       for (tmp = cmd_list; tmp; tmp = tmp->next) 
+       for (tmp = cmd_list; tmp; tmp = tmp->next)
        {
                tmp_set = tmp->cmd_set;
 
@@ -336,7 +332,8 @@ static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
        }
 
        if (argc == 2) {
-               lp_set_cmdline("log level", argv[1]);
+               struct loadparm_context *lp_ctx = samba_cmdline_get_lp_ctx();
+               lpcfg_set_cmdline(lp_ctx, "log level", argv[1]);
        }
 
        printf("debuglevel is %d\n", DEBUGLEVEL);
@@ -351,12 +348,16 @@ static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK; /* NOTREACHED */
 }
 
-static NTSTATUS cmd_set_ss_level(void)
+static NTSTATUS cmd_set_ss_level(struct dcerpc_binding *binding)
 {
        struct cmd_list *tmp;
+       enum dcerpc_AuthType auth_type;
+       enum dcerpc_AuthLevel auth_level;
 
        /* Close any existing connections not at this level. */
 
+       binding_get_auth_info(binding, &auth_type, &auth_level, NULL);
+
        for (tmp = cmd_list; tmp; tmp = tmp->next) {
                struct cmd_set *tmp_set;
 
@@ -366,9 +367,9 @@ static NTSTATUS cmd_set_ss_level(void)
                        }
 
                        if ((tmp_set->rpc_pipe->auth->auth_type
-                            != pipe_default_auth_type)
+                            != auth_type)
                            || (tmp_set->rpc_pipe->auth->auth_level
-                               != pipe_default_auth_level)) {
+                               != auth_level)) {
                                TALLOC_FREE(tmp_set->rpc_pipe);
                                tmp_set->rpc_pipe = NULL;
                        }
@@ -377,8 +378,9 @@ static NTSTATUS cmd_set_ss_level(void)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS cmd_set_transport(void)
+static NTSTATUS cmd_set_transport(struct dcerpc_binding *b)
 {
+       enum dcerpc_transport_t t = dcerpc_binding_get_transport(b);
        struct cmd_list *tmp;
 
        /* Close any existing connections not at this level. */
@@ -391,7 +393,7 @@ static NTSTATUS cmd_set_transport(void)
                                continue;
                        }
 
-                       if (tmp_set->rpc_pipe->transport->transport != default_transport) {
+                       if (tmp_set->rpc_pipe->transport->transport != t) {
                                TALLOC_FREE(tmp_set->rpc_pipe);
                                tmp_set->rpc_pipe = NULL;
                        }
@@ -400,54 +402,89 @@ static NTSTATUS cmd_set_transport(void)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                         int argc, const char **argv)
+static NTSTATUS binding_reset_auth(struct dcerpc_binding *b)
 {
-       const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
-       const char *type = "NTLMSSP";
+       NTSTATUS status = dcerpc_binding_set_flags(
+               b,
+               0,
+               DCERPC_PACKET|
+               DCERPC_CONNECT|
+               DCERPC_SIGN|
+               DCERPC_SEAL|
+               DCERPC_SCHANNEL|
+               DCERPC_AUTH_SPNEGO|
+               DCERPC_AUTH_KRB5|
+               DCERPC_AUTH_NTLM);
+       return status;
+}
 
-       pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
-       pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+static NTSTATUS binding_set_auth(
+       struct dcerpc_binding *b, const char *level, const char *type)
+{
+       NTSTATUS status;
 
-       if (argc > 2) {
-               printf("Usage: %s %s\n", argv[0], p);
-               return NT_STATUS_OK;
+       status = binding_reset_auth(b);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       if (argc == 2) {
-               type = argv[1];
-               if (strequal(type, "KRB5")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
-               } else if (strequal(type, "KRB5_SPNEGO")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
-               } else if (strequal(type, "NTLMSSP")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-               } else if (strequal(type, "NTLMSSP_SPNEGO")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
-               } else if (strequal(type, "SCHANNEL")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
-               } else {
-                       printf("unknown type %s\n", type);
-                       printf("Usage: %s %s\n", argv[0], p);
-                       return NT_STATUS_INVALID_LEVEL;
+       if (level != NULL) {
+               status = dcerpc_binding_set_string_option(b, level, level);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
                }
        }
 
-       d_printf("Setting %s - sign\n", type);
+       if (strequal(type, "SPNEGO")) {
+               status = dcerpc_binding_set_string_option(
+                       b, "spnego", "spnego");
+               return status;
+       }
+       if (strequal(type, "NTLMSSP")) {
+               status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
+               return status;
+       }
+       if (strequal(type, "NTLMSSP_SPNEGO")) {
+               status = dcerpc_binding_set_string_option(
+                       b, "spnego", "spnego");
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               status = dcerpc_binding_set_string_option(b, "ntlm", "ntlm");
+               return status;
+       }
+       if (strequal(type, "KRB5")) {
+               status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
+               return status;
+       }
+       if (strequal(type, "KRB5_SPNEGO")) {
+               status = dcerpc_binding_set_string_option(
+                       b, "spnego", "spnego");
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+               status = dcerpc_binding_set_string_option(b, "krb5", "krb5");
+               return status;
+       }
+       if (strequal(type, "SCHANNEL")) {
+               status = dcerpc_binding_set_string_option(
+                       b, "schannel", "schannel");
+               return status;
+       }
 
-       return cmd_set_ss_level();
+       return NT_STATUS_INVALID_PARAMETER;
 }
 
-static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                         int argc, const char **argv)
+static NTSTATUS cmd_set_auth(
+       struct dcerpc_binding *binding,
+       const char *level,
+       const char *display,
+       int argc,
+       const char **argv)
 {
        const char *p = "[KRB5|KRB5_SPNEGO|NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]";
        const char *type = "NTLMSSP";
-
-       pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
-       pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+       NTSTATUS status;
 
        if (argc > 2) {
                printf("Usage: %s %s\n", argv[0], p);
@@ -456,35 +493,55 @@ static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
        if (argc == 2) {
                type = argv[1];
-               if (strequal(type, "KRB5")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
-               } else if (strequal(type, "KRB5_SPNEGO")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
-               } else if (strequal(type, "NTLMSSP")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-               } else if (strequal(type, "NTLMSSP_SPNEGO")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
-               } else if (strequal(type, "SCHANNEL")) {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
-               } else {
-                       printf("unknown type %s\n", type);
-                       printf("Usage: %s %s\n", argv[0], p);
-                       return NT_STATUS_INVALID_LEVEL;
-               }
        }
 
-       d_printf("Setting %s - sign and seal\n", type);
+       status = binding_set_auth(binding, level, type);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Usage: %s %s\n", argv[0], p);
+               return status;
+       }
+
+       d_printf("Setting %s - %s: %s\n", type, display, nt_errstr(status));
+
+       status = cmd_set_ss_level(binding);
+       return status;
+}
+
+static NTSTATUS cmd_sign(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **argv)
+{
+       NTSTATUS status = cmd_set_auth(binding, "sign", "sign", argc, argv);
+       return status;
+}
+
+static NTSTATUS cmd_seal(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **argv)
+{
+       NTSTATUS status = cmd_set_auth(
+               binding, "seal", "sign and seal", argc, argv);
+       return status;
+}
 
-       return cmd_set_ss_level();
+static NTSTATUS cmd_packet(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **argv)
+{
+       NTSTATUS status = cmd_set_auth(
+               binding, "packet", "packet", argc, argv);
+       return status;
 }
 
 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;
@@ -492,19 +549,6 @@ static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 
        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;
-                               }
-
-                               rpccli_set_timeout(tmp_set->rpc_pipe, timeout);
-                       }
-               }
        }
 
        printf("timeout is %d\n", timeout);
@@ -513,56 +557,75 @@ static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
 }
 
 
-static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                         int argc, const char **argv)
+static NTSTATUS cmd_none(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **argv)
 {
-       pipe_default_auth_level = DCERPC_AUTH_LEVEL_NONE;
-       pipe_default_auth_type = DCERPC_AUTH_TYPE_NONE;
-       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
-
-       return cmd_set_ss_level();
+       NTSTATUS status = binding_reset_auth(binding);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       status = cmd_set_ss_level(binding);
+       return status;
 }
 
-static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                            int argc, const char **argv)
+static NTSTATUS cmd_schannel(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **_argv)
 {
-       d_printf("Setting schannel - sign and seal\n");
-       pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
-       pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
-
-       return cmd_set_ss_level();
+       const char *argv[] = { "schannel", "SCHANNEL" };
+       NTSTATUS status = cmd_set_auth(
+               binding, "seal", "sign and seal", 2, argv);
+       return status;
 }
 
-static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                            int argc, const char **argv)
+static NTSTATUS cmd_schannel_sign(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **_argv)
 {
-       d_printf("Setting schannel - sign only\n");
-       pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
-       pipe_default_auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
-
-       return cmd_set_ss_level();
+       const char *argv[] = { "schannel_sign", "SCHANNEL" };
+       NTSTATUS status = cmd_set_auth(binding, "sign", "sign only", 2, argv);
+       return status;
 }
 
-static NTSTATUS cmd_choose_transport(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
-                                    int argc, const char **argv)
+static NTSTATUS cmd_choose_transport(
+       struct dcerpc_binding *binding,
+       TALLOC_CTX *mem_ctx,
+       int argc,
+       const char **argv)
 {
        NTSTATUS status;
+       enum dcerpc_transport_t transport;
 
        if (argc != 2) {
                printf("Usage: %s [NCACN_NP|NCACN_IP_TCP]\n", argv[0]);
                return NT_STATUS_OK;
        }
 
-       if (strequal(argv[1], "NCACN_NP")) {
-               default_transport = NCACN_NP;
-       } else if (strequal(argv[1], "NCACN_IP_TCP")) {
-               default_transport = NCACN_IP_TCP;
-       } else {
-               printf("transport type: %s unknown or not supported\n", argv[1]);
+       transport = dcerpc_transport_by_name(argv[1]);
+       if (transport == NCA_UNKNOWN) {
+               printf("transport type %s unknown\n", argv[1]);
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+       if (!((transport == NCACN_IP_TCP) ||
+             (transport == NCACN_NP) ||
+             (transport == NCALRPC))) {
+               printf("transport %s not supported\n", argv[1]);
                return NT_STATUS_NOT_SUPPORTED;
        }
 
-       status = cmd_set_transport();
+       status = dcerpc_binding_set_transport(binding, transport);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = cmd_set_transport(binding);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -576,29 +639,129 @@ static NTSTATUS cmd_choose_transport(struct rpc_pipe_client *cli, TALLOC_CTX *me
 
 static struct cmd_set rpcclient_commands[] = {
 
-       { "GENERAL OPTIONS" },
-
-       { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL,     NULL, NULL,   "Get help on commands", "[command]" },
-       { "?",  RPC_RTYPE_NTSTATUS, cmd_help, NULL,       NULL, NULL,   "Get help on commands", "[command]" },
-       { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,       NULL, "Set debug level", "level" },
-       { "debug", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL,   NULL,    NULL, "Set debug level", "level" },
-       { "list",       RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, NULL,       NULL, "List available commands on <pipe>", "pipe" },
-       { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,   NULL,   NULL,   "Exit program", "" },
-       { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL,     NULL, NULL, "Exit program", "" },
-       { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL,     NULL, NULL, "Force RPC pipe connections to be signed", "" },
-       { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL,     NULL, NULL, "Force RPC pipe connections to be sealed", "" },
-       { "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.", "" },
-       { "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.", "" },
-       { "timeout", RPC_RTYPE_NTSTATUS, cmd_timeout, NULL,       NULL, NULL, "Set timeout (in milliseconds) for RPC operations", "" },
-       { "transport", RPC_RTYPE_NTSTATUS, cmd_choose_transport, NULL,    NULL, NULL, "Choose ncacn transport for RPC operations", "" },
-       { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL,     NULL, NULL, "Force RPC pipe connections to have no special properties", "" },
-
-       { NULL }
+       {
+               .name = "GENERAL OPTIONS",
+       },
+
+       {
+               .name               = "help",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_help,
+               .description        = "Get help on commands",
+               .usage              = "[command]",
+       },
+       {
+               .name               = "?",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_help,
+               .description        = "Get help on commands",
+               .usage              = "[command]",
+       },
+       {
+               .name               = "debuglevel",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_debuglevel,
+               .description        = "Set debug level",
+               .usage              = "level",
+       },
+       {
+               .name               = "debug",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_debuglevel,
+               .description        = "Set debug level",
+               .usage              = "level",
+       },
+       {
+               .name               = "list",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_listcommands,
+               .description        = "List available commands on <pipe>",
+               .usage              = "pipe",
+       },
+       {
+               .name               = "exit",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_quit,
+               .description        = "Exit program",
+               .usage              = "",
+       },
+       {
+               .name               = "quit",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_quit,
+               .description        = "Exit program",
+               .usage              = "",
+       },
+       {
+               .name               = "sign",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_sign,
+               .description        = "Force RPC pipe connections to be signed",
+               .usage              = "",
+       },
+       {
+               .name               = "seal",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_seal,
+               .description        = "Force RPC pipe connections to be sealed",
+               .usage              = "",
+       },
+       {
+               .name               = "packet",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_packet,
+               .description        = "Force RPC pipe connections with packet authentication level",
+               .usage              = "",
+       },
+       {
+               .name               = "schannel",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_schannel,
+               .description        = "Force RPC pipe connections to be sealed with 'schannel'. "
+                                     "Assumes valid machine account to this domain controller.",
+               .usage              = "",
+       },
+       {
+               .name               = "schannelsign",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_schannel_sign,
+               .description        = "Force RPC pipe connections to be signed (not sealed) with "
+                                     "'schannel'.  Assumes valid machine account to this domain "
+                                     "controller.",
+               .usage              = "",
+       },
+       {
+               .name               = "timeout",
+               .returntype         = RPC_RTYPE_NTSTATUS,
+               .ntfn               = cmd_timeout,
+               .description        = "Set timeout (in milliseconds) for RPC operations",
+               .usage              = "",
+       },
+       {
+               .name               = "transport",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_choose_transport,
+               .description        = "Choose ncacn transport for RPC operations",
+               .usage              = "",
+       },
+       {
+               .name               = "none",
+               .returntype         = RPC_RTYPE_BINDING,
+               .bfn                = cmd_none,
+               .description        = "Force RPC pipe connections to have no special properties",
+               .usage              = "",
+       },
+
+       { .name = NULL, },
 };
 
 static struct cmd_set separator_command[] = {
-       { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   NULL, NULL, "----------------------" },
-       { NULL }
+       {
+               .name               = "---------------",
+               .returntype         = MAX_RPC_RETURN_TYPE,
+               .description        = "----------------------"
+       },
+       { .name = NULL, },
 };
 
 
@@ -607,6 +770,7 @@ static struct cmd_set separator_command[] = {
 extern struct cmd_set lsarpc_commands[];
 extern struct cmd_set samr_commands[];
 extern struct cmd_set spoolss_commands[];
+extern struct cmd_set iremotewinspool_commands[];
 extern struct cmd_set netlogon_commands[];
 extern struct cmd_set srvsvc_commands[];
 extern struct cmd_set dfs_commands[];
@@ -614,13 +778,16 @@ extern struct cmd_set ds_commands[];
 extern struct cmd_set echo_commands[];
 extern struct cmd_set epmapper_commands[];
 extern struct cmd_set shutdown_commands[];
-extern struct cmd_set test_commands[];
 extern struct cmd_set wkssvc_commands[];
 extern struct cmd_set ntsvcs_commands[];
 extern struct cmd_set drsuapi_commands[];
 extern struct cmd_set eventlog_commands[];
 extern struct cmd_set winreg_commands[];
 extern struct cmd_set fss_commands[];
+extern struct cmd_set witness_commands[];
+extern struct cmd_set clusapi_commands[];
+extern struct cmd_set spotlight_commands[];
+extern struct cmd_set unixinfo_commands[];
 
 static struct cmd_set *rpcclient_command_list[] = {
        rpcclient_commands,
@@ -628,19 +795,23 @@ static struct cmd_set *rpcclient_command_list[] = {
        ds_commands,
        samr_commands,
        spoolss_commands,
+       iremotewinspool_commands,
        netlogon_commands,
        srvsvc_commands,
        dfs_commands,
        echo_commands,
        epmapper_commands,
        shutdown_commands,
-       test_commands,
        wkssvc_commands,
        ntsvcs_commands,
        drsuapi_commands,
        eventlog_commands,
        winreg_commands,
        fss_commands,
+       witness_commands,
+       clusapi_commands,
+       spotlight_commands,
+       unixinfo_commands,
        NULL
 };
 
@@ -659,141 +830,236 @@ static void add_command_set(struct cmd_set *cmd_set)
        DLIST_ADD(cmd_list, entry);
 }
 
+static NTSTATUS rpccli_ncalrpc_connect(
+       const struct ndr_interface_table *iface,
+       TALLOC_CTX *mem_ctx,
+       struct rpc_pipe_client **prpccli)
+{
+       struct rpc_pipe_client *rpccli = NULL;
+       struct pipe_auth_data *auth = NULL;
+       NTSTATUS status;
+
+       status = rpc_pipe_open_ncalrpc(mem_ctx, iface, &rpccli);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
+                         nt_errstr(status));
+               goto fail;
+       }
+
+       status = rpccli_ncalrpc_bind_data(rpccli, &auth);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("rpccli_ncalrpc_bind_data failed: %s\n",
+                         nt_errstr(status));
+               goto fail;
+       }
 
+       status = rpc_pipe_bind(rpccli, auth);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
+               goto fail;
+       }
+
+       *prpccli = rpccli;
+       return NT_STATUS_OK;
+fail:
+       TALLOC_FREE(rpccli);
+       return status;
+}
 /**
  * Call an rpcclient function, passing an argv array.
  *
  * @param cmd Command to run, as a single string.
  **/
 static NTSTATUS do_cmd(struct cli_state *cli,
-                      struct user_auth_info *auth_info,
+                      struct cli_credentials *creds,
                       struct cmd_set *cmd_entry,
                       struct dcerpc_binding *binding,
-                      int argc, char **argv)
+                      int argc, const char **argv)
 {
        NTSTATUS ntresult;
        WERROR wresult;
+       enum dcerpc_transport_t transport;
 
-       TALLOC_CTX *mem_ctx;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+       const char *remote_name = NULL;
+       const struct sockaddr_storage *remote_sockaddr = NULL;
+       struct sockaddr_storage remote_ss = {
+               .ss_family = AF_UNSPEC,
+       };
 
-       /* Create mem_ctx */
+       transport = dcerpc_binding_get_transport(binding);
 
-       if (!(mem_ctx = talloc_init("do_cmd"))) {
-               DEBUG(0, ("talloc_init() failed\n"));
-               return NT_STATUS_NO_MEMORY;
+       if (cli != NULL) {
+               remote_name = smbXcli_conn_remote_name(cli->conn);
+               remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
+       } else {
+               const char *remote_host =
+                       dcerpc_binding_get_string_option(binding, "host");
+               remote_name = dcerpc_binding_get_string_option(
+                               binding, "target_hostname");
+
+               if (remote_host != NULL) {
+                       bool ok = interpret_string_addr(
+                               &remote_ss, remote_host, 0);
+                       if (ok) {
+                               remote_sockaddr = &remote_ss;
+                       }
+               }
        }
 
        /* Open pipe */
 
        if ((cmd_entry->table != NULL) && (cmd_entry->rpc_pipe == NULL)) {
-               switch (pipe_default_auth_type) {
-               case DCERPC_AUTH_TYPE_NONE:
-                       ntresult = cli_rpc_pipe_open_noauth_transport(
-                               cli, default_transport,
-                               &cmd_entry->table->syntax_id,
-                               &cmd_entry->rpc_pipe);
-                       break;
-               case DCERPC_AUTH_TYPE_SPNEGO:
-               {
-                       /* won't happen, but if it does it will fail in cli_rpc_pipe_open_spnego() eventually */
-                       const char *oid = "INVALID";
-                       switch (pipe_default_auth_spnego_type) {
-                       case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
-                               oid = GENSEC_OID_NTLMSSP;
+               if (transport == NCALRPC) {
+                       ntresult = rpccli_ncalrpc_connect(
+                               cmd_entry->table, cli, &cmd_entry->rpc_pipe);
+                       if (!NT_STATUS_IS_OK(ntresult)) {
+                               TALLOC_FREE(mem_ctx);
+                               return ntresult;
+                       }
+               } else {
+                       enum dcerpc_AuthType auth_type;
+                       enum dcerpc_AuthLevel auth_level;
+                       enum credentials_use_kerberos krb5_state =
+                               cli_credentials_get_kerberos_state(creds);
+
+                       binding_get_auth_info(
+                               binding, &auth_type, &auth_level, &krb5_state);
+
+                       switch (auth_type) {
+                       case DCERPC_AUTH_TYPE_NONE:
+                               ntresult = cli_rpc_pipe_open_noauth_transport(
+                                       cli, transport,
+                                       cmd_entry->table,
+                                       remote_name,
+                                       remote_sockaddr,
+                                       &cmd_entry->rpc_pipe);
                                break;
-                       case PIPE_AUTH_TYPE_SPNEGO_KRB5:
-                               oid = GENSEC_OID_KERBEROS5;
+                       case DCERPC_AUTH_TYPE_SPNEGO:
+                       case DCERPC_AUTH_TYPE_NTLMSSP:
+                       case DCERPC_AUTH_TYPE_KRB5:
+                               cli_credentials_set_kerberos_state(creds,
+                                                                  krb5_state,
+                                                                  CRED_SPECIFIED);
+
+                               ntresult = cli_rpc_pipe_open_with_creds(
+                                       cli, cmd_entry->table,
+                                       transport,
+                                       auth_type,
+                                       auth_level,
+                                       remote_name,
+                                       remote_sockaddr,
+                                       creds,
+                                       &cmd_entry->rpc_pipe);
                                break;
-                       case PIPE_AUTH_TYPE_SPNEGO_NONE:
+                       case DCERPC_AUTH_TYPE_SCHANNEL:
+                               TALLOC_FREE(rpcclient_netlogon_creds);
+                               ntresult = cli_rpc_pipe_open_schannel(
+                                       cli, rpcclient_msg_ctx,
+                                       cmd_entry->table,
+                                       transport,
+                                       rpcclient_netlogon_domain,
+                                       remote_name,
+                                       remote_sockaddr,
+                                       &cmd_entry->rpc_pipe,
+                                       rpcclient_msg_ctx,
+                                       &rpcclient_netlogon_creds);
                                break;
+                       default:
+                               DEBUG(0, ("Could not initialise %s. Invalid "
+                                         "auth type %u\n",
+                                         cmd_entry->table->name,
+                                         auth_type ));
+                               talloc_free(mem_ctx);
+                               return NT_STATUS_UNSUCCESSFUL;
                        }
-                       ntresult = cli_rpc_pipe_open_spnego(
-                               cli, cmd_entry->table,
-                               default_transport,
-                               oid,
-                               pipe_default_auth_level,
-                               smbXcli_conn_remote_name(cli->conn),
-                               get_cmdline_auth_info_domain(auth_info),
-                               get_cmdline_auth_info_username(auth_info),
-                               get_cmdline_auth_info_password(auth_info),
-                               &cmd_entry->rpc_pipe);
-                       break;
-               }
-               case DCERPC_AUTH_TYPE_NTLMSSP:
-               case DCERPC_AUTH_TYPE_KRB5:
-                       ntresult = cli_rpc_pipe_open_generic_auth(
-                               cli, cmd_entry->table,
-                               default_transport,
-                               pipe_default_auth_type,
-                               pipe_default_auth_level,
-                               smbXcli_conn_remote_name(cli->conn),
-                               get_cmdline_auth_info_domain(auth_info),
-                               get_cmdline_auth_info_username(auth_info),
-                               get_cmdline_auth_info_password(auth_info),
-                               &cmd_entry->rpc_pipe);
-                       break;
-               case DCERPC_AUTH_TYPE_SCHANNEL:
-                       ntresult = cli_rpc_pipe_open_schannel(
-                               cli, &cmd_entry->table->syntax_id,
-                               default_transport,
-                               pipe_default_auth_level,
-                               get_cmdline_auth_info_domain(auth_info),
-                               &cmd_entry->rpc_pipe);
-                       break;
-               default:
-                       DEBUG(0, ("Could not initialise %s. Invalid "
-                                 "auth type %u\n",
-                                 cmd_entry->table->name,
-                                 pipe_default_auth_type ));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-               if (!NT_STATUS_IS_OK(ntresult)) {
-                       DEBUG(0, ("Could not initialise %s. Error was %s\n",
-                                 cmd_entry->table->name,
-                                 nt_errstr(ntresult) ));
-                       return ntresult;
-               }
-
-               if (ndr_syntax_id_equal(&cmd_entry->table->syntax_id,
-                                       &ndr_table_netlogon.syntax_id)) {
-                       uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
-                       enum netr_SchannelType sec_channel_type;
-                       uchar trust_password[16];
-                       const char *machine_account;
-
-                       if (!get_trust_pw_hash(get_cmdline_auth_info_domain(auth_info),
-                                              trust_password, &machine_account,
-                                              &sec_channel_type))
-                       {
-                               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+                       if (!NT_STATUS_IS_OK(ntresult)) {
+                               DBG_ERR("Could not initialise %s. "
+                                       "Error was %s\n",
+                                       cmd_entry->table->name,
+                                       nt_errstr(ntresult));
+                               talloc_free(mem_ctx);
+                               return ntresult;
                        }
 
-                       ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
-                                               cmd_entry->rpc_pipe->desthost,   /* server name */
-                                               get_cmdline_auth_info_domain(auth_info),  /* domain */
-                                               lp_netbios_name(), /* client name */
-                                               machine_account, /* machine account name */
-                                               trust_password,
-                                               sec_channel_type,
-                                               &neg_flags);
+                       if (rpcclient_netlogon_creds == NULL &&
+                           cmd_entry->use_netlogon_creds) {
+                               const char *dc_name =
+                                       cmd_entry->rpc_pipe->desthost;
+                               const char *domain = rpcclient_netlogon_domain;
+                               struct cli_credentials *trust_creds = NULL;
+
+                               ntresult = pdb_get_trust_credentials(
+                                       domain,
+                                       NULL,
+                                       mem_ctx,
+                                       &trust_creds);
+                               if (!NT_STATUS_IS_OK(ntresult)) {
+                                       DBG_ERR("Failed to fetch trust "
+                                               "credentials for "
+                                               "%s to connect to %s: %s\n",
+                                               domain,
+                                               cmd_entry->table->name,
+                                               nt_errstr(ntresult));
+                                       TALLOC_FREE(cmd_entry->rpc_pipe);
+                                       talloc_free(mem_ctx);
+                                       return ntresult;
+                               }
 
-                       if (!NT_STATUS_IS_OK(ntresult)) {
-                               DEBUG(0, ("Could not initialise credentials for %s.\n",
-                                         cmd_entry->table->name));
-                               return ntresult;
+                               ntresult = rpccli_create_netlogon_creds_ctx(
+                                       trust_creds,
+                                       dc_name,
+                                       rpcclient_msg_ctx,
+                                       rpcclient_msg_ctx,
+                                       &rpcclient_netlogon_creds);
+                               if (!NT_STATUS_IS_OK(ntresult)) {
+                                       DBG_ERR("Could not initialise "
+                                               "credentials for %s.\n",
+                                               cmd_entry->table->name);
+                                       TALLOC_FREE(cmd_entry->rpc_pipe);
+                                       TALLOC_FREE(mem_ctx);
+                                       return ntresult;
+                               }
+
+                               ntresult = rpccli_setup_netlogon_creds(
+                                       cli,
+                                       NCACN_NP,
+                                       rpcclient_netlogon_creds,
+                                       false, /* force_reauth */
+                                       trust_creds);
+                               TALLOC_FREE(trust_creds);
+                               if (!NT_STATUS_IS_OK(ntresult)) {
+                                       DBG_ERR("Could not initialise "
+                                               "credentials for %s.\n",
+                                               cmd_entry->table->name);
+                                       TALLOC_FREE(cmd_entry->rpc_pipe);
+                                       TALLOC_FREE(rpcclient_netlogon_creds);
+                                       TALLOC_FREE(mem_ctx);
+                                       return ntresult;
+                               }
                        }
                }
        }
 
+       /* Set timeout for new connections */
+       if (cmd_entry->rpc_pipe) {
+               rpccli_set_timeout(cmd_entry->rpc_pipe, timeout);
+       }
+
        /* Run command */
 
        if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
-               ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
+               ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
+               if (!NT_STATUS_IS_OK(ntresult)) {
+                       printf("result was %s\n", nt_errstr(ntresult));
+               }
+       } else if (cmd_entry->returntype == RPC_RTYPE_BINDING) {
+               ntresult = cmd_entry->bfn(binding, mem_ctx, argc, argv);
                if (!NT_STATUS_IS_OK(ntresult)) {
                        printf("result was %s\n", nt_errstr(ntresult));
                }
        } else {
-               wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
+               wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, argv);
                /* print out the DOS error */
                if (!W_ERROR_IS_OK(wresult)) {
                        printf( "result was %s\n", win_errstr(wresult));
@@ -803,7 +1069,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 
        /* Cleanup */
 
-       talloc_destroy(mem_ctx);
+       talloc_free(mem_ctx);
 
        return ntresult;
 }
@@ -814,7 +1080,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
  *
  * @returns The NTSTATUS from running the command.
  **/
-static NTSTATUS process_cmd(struct user_auth_info *auth_info,
+static NTSTATUS process_cmd(struct cli_credentials *creds,
                            struct cli_state *cli,
                            struct dcerpc_binding *binding,
                            char *cmd)
@@ -823,9 +1089,9 @@ static NTSTATUS process_cmd(struct user_auth_info *auth_info,
        NTSTATUS result = NT_STATUS_OK;
        int ret;
        int argc;
-       char **argv = NULL;
+       const char **argv = NULL;
 
-       if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) {
+       if ((ret = poptParseArgvString(cmd, &argc, &argv)) != 0) {
                fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -833,22 +1099,27 @@ static NTSTATUS process_cmd(struct user_auth_info *auth_info,
 
        /* Walk through a dlist of arrays of commands. */
        for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
-               struct cmd_set *temp_set = temp_list->cmd_set;
-
-               while (temp_set->name) {
-                       if (strequal(argv[0], temp_set->name)) {
-                               if (!(temp_set->returntype == RPC_RTYPE_NTSTATUS && temp_set->ntfn ) &&
-                         !(temp_set->returntype == RPC_RTYPE_WERROR && temp_set->wfn )) {
-                                       fprintf (stderr, "Invalid command\n");
-                                       goto out_free;
-                               }
+               struct cmd_set *set = temp_list->cmd_set;
 
-                               result = do_cmd(cli, auth_info, temp_set,
-                                               binding, argc, argv);
+               while (set->name != NULL) {
+                       if (!strequal(argv[0], set->name)) {
+                               set += 1;
+                               continue;
+                       }
 
+                       if (((set->returntype == RPC_RTYPE_NTSTATUS) &&
+                            (set->ntfn == NULL)) ||
+                           ((set->returntype == RPC_RTYPE_WERROR) &&
+                            (set->wfn == NULL)) ||
+                           ((set->returntype == RPC_RTYPE_BINDING) &&
+                            (set->bfn == NULL))) {
+                               fprintf (stderr, "Invalid command\n");
                                goto out_free;
                        }
-                       temp_set++;
+
+                       result = do_cmd(
+                               cli, creds, set, binding, argc, argv);
+                       goto out_free;
                }
        }
 
@@ -877,6 +1148,7 @@ out_free:
 
  int main(int argc, char *argv[])
 {
+       const char **const_argv = discard_const_p(const char *, argv);
        int                     opt;
        static char             *cmdstr = NULL;
        const char *server;
@@ -888,10 +1160,14 @@ out_free:
        static int              opt_port = 0;
        int result = 0;
        TALLOC_CTX *frame = talloc_stackframe();
-       uint32_t flags = 0;
+       uint32_t flags = CLI_FULL_CONNECTION_IPC;
        struct dcerpc_binding *binding = NULL;
+       enum dcerpc_transport_t transport;
        const char *binding_string = NULL;
-       char *user, *domain, *q;
+       const char *host;
+       struct cli_credentials *creds = NULL;
+       struct loadparm_context *lp_ctx = NULL;
+       bool ok;
 
        /* make sure the vars that get altered (4th field) are in
           a fixed location or certain compilers complain */
@@ -904,29 +1180,38 @@ out_free:
                POPT_COMMON_SAMBA
                POPT_COMMON_CONNECTION
                POPT_COMMON_CREDENTIALS
+               POPT_LEGACY_S3
+               POPT_COMMON_VERSION
                POPT_TABLEEND
        };
 
-       load_case_tables();
+       smb_init_locale();
 
        zero_sockaddr(&server_ss);
 
        setlinebuf(stdout);
 
-       /* the following functions are part of the Samba debugging
-          facilities.  See lib/debug.c */
-       setup_logging("rpcclient", DEBUG_STDOUT);
-
-       rpcclient_auth_info = user_auth_info_init(frame);
-       if (rpcclient_auth_info == NULL) {
-               exit(1);
+       ok = samba_cmdline_init(frame,
+                               SAMBA_CMDLINE_CONFIG_CLIENT,
+                               false /* require_smbconf */);
+       if (!ok) {
+               DBG_ERR("Failed to init cmdline parser!\n");
        }
-       popt_common_set_auth_info(rpcclient_auth_info);
+       lp_ctx = samba_cmdline_get_lp_ctx();
+       lpcfg_set_cmdline(lp_ctx, "log level", "0");
 
        /* Parse options */
+       pc = samba_popt_get_context(getprogname(),
+                                   argc,
+                                   const_argv,
+                                   long_options,
+                                   0);
+       if (pc == NULL) {
+               DBG_ERR("Failed to setup popt context!\n");
+               exit(1);
+       }
 
-       pc = poptGetContext("rpcclient", argc, (const char **) argv,
-                           long_options, 0);
+       poptSetOtherOptionHelp(pc, "[OPTION...] BINDING-STRING|HOST\nOptions:");
 
        if (argc == 1) {
                poptPrintHelp(pc, stderr, 0);
@@ -945,13 +1230,19 @@ out_free:
                                result = 1;
                                goto done;
                        }
+                       break;
+               case POPT_ERROR_BADOPT:
+                       fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                               poptBadOption(pc, 0), poptStrerror(opt));
+                       poptPrintUsage(pc, stderr, 0);
+                       exit(1);
                }
        }
 
        /* Get server as remaining unparsed argument.  Print usage if more
           than one unparsed argument is present. */
 
-       server = poptGetArg(pc);
+       server = talloc_strdup(frame, poptGetArg(pc));
 
        if (!server || poptGetArg(pc)) {
                poptPrintHelp(pc, stderr, 0);
@@ -960,33 +1251,16 @@ out_free:
        }
 
        poptFreeContext(pc);
+       samba_cmdline_burn(argc, argv);
 
-       if (!init_names()) {
-               result = 1;
-               goto done;
-       }
-
-       /* Load smb.conf file */
-
-       if (!lp_load_global(get_dyn_CONFIGFILE()))
-               fprintf(stderr, "Can't load %s\n", get_dyn_CONFIGFILE());
-
-       /* We must load interfaces after we load the smb.conf */
-       load_interfaces();
+       rpcclient_msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
+       creds = samba_cmdline_get_creds();
 
        /*
         * Get password
         * from stdin if necessary
         */
 
-       if (get_cmdline_auth_info_use_machine_account(rpcclient_auth_info) &&
-           !set_cmdline_auth_info_machine_account_creds(rpcclient_auth_info)) {
-               result = 1;
-               goto done;
-       }
-
-       set_cmdline_auth_info_getpass(rpcclient_auth_info);
-
        if ((server[0] == '/' && server[1] == '/') ||
                        (server[0] == '\\' && server[1] ==  '\\')) {
                server += 2;
@@ -1010,105 +1284,54 @@ out_free:
                }
        }
 
-       if (binding->transport == NCA_UNKNOWN) {
-               binding->transport = NCACN_NP;
-       }
-
-       if (binding->flags & DCERPC_SIGN) {
-               pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
-               pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-       }
-       if (binding->flags & DCERPC_SEAL) {
-               pipe_default_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
-               pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-       }
-       if (binding->flags & DCERPC_AUTH_SPNEGO) {
-               pipe_default_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-               pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
-       }
-       if (binding->flags & DCERPC_AUTH_NTLM) {
-               /* If neither Integrity or Privacy are requested then
-                * Use just Connect level */
-               if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
-                       pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
-               }
+       transport = dcerpc_binding_get_transport(binding);
 
-               if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
-               } else {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
-               }
-       }
-       if (binding->flags & DCERPC_AUTH_KRB5) {
-               /* If neither Integrity or Privacy are requested then
-                * Use just Connect level */
-               if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
-                       pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
-               }
-
-               if (pipe_default_auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
-                       pipe_default_auth_spnego_type = PIPE_AUTH_TYPE_SPNEGO_KRB5;
-               } else {
-                       pipe_default_auth_type = DCERPC_AUTH_TYPE_KRB5;
+       if (transport == NCA_UNKNOWN) {
+               transport = NCACN_NP;
+               nt_status = dcerpc_binding_set_transport(binding, transport);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       result = -1;
+                       goto done;
                }
        }
 
-       if (get_cmdline_auth_info_use_kerberos(rpcclient_auth_info)) {
-               flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
-                        CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
-       }
-       if (get_cmdline_auth_info_use_ccache(rpcclient_auth_info)) {
-               flags |= CLI_FULL_CONNECTION_USE_CCACHE;
-       }
-
-       user = talloc_strdup(frame, get_cmdline_auth_info_username(rpcclient_auth_info));
-       SMB_ASSERT(user != NULL);
-       domain = talloc_strdup(frame, lp_workgroup());
-       SMB_ASSERT(domain != NULL);
-       set_cmdline_auth_info_domain(rpcclient_auth_info, domain);
+       host = dcerpc_binding_get_string_option(binding, "host");
 
-       if ((q = strchr_m(user,'\\'))) {
-               *q = 0;
-               set_cmdline_auth_info_domain(rpcclient_auth_info, user);
-               set_cmdline_auth_info_username(rpcclient_auth_info, q+1);
+       rpcclient_netlogon_domain = cli_credentials_get_domain(creds);
+       if (rpcclient_netlogon_domain == NULL ||
+           rpcclient_netlogon_domain[0] == '\0')
+       {
+               rpcclient_netlogon_domain = lp_workgroup();
        }
 
+       if (transport == NCACN_NP) {
+               nt_status = cli_full_connection_creds(frame,
+                                                     &cli,
+                                                     lp_netbios_name(),
+                                                     host,
+                                                     opt_ipaddr ? &server_ss
+                                                                : NULL,
+                                                     opt_port,
+                                                     "IPC$",
+                                                     "IPC",
+                                                     creds,
+                                                     flags);
 
-       nt_status = cli_full_connection(&cli, lp_netbios_name(), binding->host,
-                                       opt_ipaddr ? &server_ss : NULL, opt_port,
-                                       "IPC$", "IPC",
-                                       get_cmdline_auth_info_username(rpcclient_auth_info),
-                                       get_cmdline_auth_info_domain(rpcclient_auth_info),
-                                       get_cmdline_auth_info_password(rpcclient_auth_info),
-                                       flags,
-                                       get_cmdline_auth_info_signing_state(rpcclient_auth_info));
-
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
-               result = 1;
-               goto done;
-       }
-
-       if (get_cmdline_auth_info_smb_encrypt(rpcclient_auth_info)) {
-               nt_status = cli_cm_force_encryption(cli,
-                                       get_cmdline_auth_info_username(rpcclient_auth_info),
-                                       get_cmdline_auth_info_password(rpcclient_auth_info),
-                                       get_cmdline_auth_info_domain(rpcclient_auth_info),
-                                       "IPC$");
                if (!NT_STATUS_IS_OK(nt_status)) {
+                       DEBUG(0, ("Cannot connect to server.  Error was %s\n",
+                                 nt_errstr(nt_status)));
                        result = 1;
                        goto done;
                }
+
+               /* Load command lists */
+               cli_set_timeout(cli, timeout);
        }
 
 #if 0  /* COMMENT OUT FOR TESTING */
        memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
 #endif
 
-       /* Load command lists */
-
-       timeout = cli_set_timeout(cli, 10000);
-
        cmd_set = rpcclient_command_list;
 
        while(*cmd_set) {
@@ -1117,10 +1340,6 @@ out_free:
                cmd_set++;
        }
 
-       default_transport = binding->transport;
-
-       fetch_machine_sid(cli);
-
        /* Do anything specified with -c */
         if (cmdstr && cmdstr[0]) {
                 char    *cmd;
@@ -1129,8 +1348,10 @@ out_free:
                result = 0;
 
                 while((cmd=next_command(&p)) != NULL) {
-                        NTSTATUS cmd_result = process_cmd(rpcclient_auth_info, cli,
-                                                         binding, cmd);
+                        NTSTATUS cmd_result = process_cmd(creds,
+                                                         cli,
+                                                         binding,
+                                                         cmd);
                        SAFE_FREE(cmd);
                        result = NT_STATUS_IS_ERR(cmd_result);
                 }
@@ -1145,11 +1366,16 @@ out_free:
 
                line = smb_readline("rpcclient $> ", NULL, completion_fn);
 
-               if (line == NULL)
+               if (line == NULL) {
+                       printf("\n");
                        break;
+               }
 
                if (line[0] != '\n')
-                       process_cmd(rpcclient_auth_info, cli, binding, line);
+                       process_cmd(creds,
+                                   cli,
+                                   binding,
+                                   line);
                SAFE_FREE(line);
        }
 
@@ -1157,6 +1383,8 @@ done:
        if (cli != NULL) {
                cli_shutdown(cli);
        }
+       netlogon_creds_cli_close_global_db();
+       TALLOC_FREE(rpcclient_msg_ctx);
        TALLOC_FREE(frame);
        return result;
 }