summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/client.h1
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/libsmb/clientgen.c20
-rw-r--r--source3/rpc_client/cli_use.c9
-rw-r--r--source3/rpcclient/rpcclient.c11
-rw-r--r--source3/utils/smb-agent.c196
6 files changed, 164 insertions, 76 deletions
diff --git a/source3/include/client.h b/source3/include/client.h
index 821a333e54..477ceb1160 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -85,6 +85,7 @@ struct user_credentials
struct pwd_info pwd;
uint32 ntlmssp_flags;
+ BOOL reuse;
};
struct cli_state
diff --git a/source3/include/smb.h b/source3/include/smb.h
index ebc0e7ad9e..17da44e75b 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1740,6 +1740,9 @@ struct field_info
char *str;
};
+#define AGENT_CMD_CON 0
+#define AGENT_CMD_CON_REUSE 1
+
#endif /* _SMB_H */
/* _SMB_H */
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 176be9948b..3695680301 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -40,6 +40,7 @@ void copy_user_creds(struct user_credentials *to,
to->user_name[0] = 0;
pwd_set_nullpwd(&to->pwd);
to->ntlmssp_flags = 0;
+ to->reuse = False;
return;
}
@@ -47,6 +48,7 @@ void copy_user_creds(struct user_credentials *to,
safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
to->ntlmssp_flags = from->ntlmssp_flags;
+ to->reuse = from->reuse;
};
int cli_set_port(struct cli_state *cli, int port)
@@ -785,6 +787,12 @@ BOOL cli_session_setup_x(struct cli_state *cli,
char *p;
BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY;
+ if (cli->usr.reuse)
+ {
+ DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n"));
+ return True;
+ }
+
DEBUG(100,("cli_session_setup. extended security: %s\n",
BOOLSTR(esec)));
@@ -1063,6 +1071,12 @@ BOOL cli_session_setup(struct cli_state *cli,
BOOL cli_ulogoff(struct cli_state *cli)
{
+ if (cli->usr.reuse)
+ {
+ DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n"));
+ return True;
+ }
+
bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,2,0,True);
CVAL(cli->outbuf,smb_com) = SMBulogoffX;
@@ -2981,6 +2995,12 @@ static int cli_init_redirect(struct cli_state *cli,
ZERO_STRUCT(data);
p = &data[4];
+ SSVAL(p, 0, 0);
+ p += 2;
+
+ SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON);
+ p += 2;
+
safe_strcpy(p, srv_name, 16);
p = skip_string(p, 1);
safe_strcpy(p, usr != NULL ? usr->user_name : "", 16);
diff --git a/source3/rpc_client/cli_use.c b/source3/rpc_client/cli_use.c
index 31e3b69b2e..131edfeb5b 100644
--- a/source3/rpc_client/cli_use.c
+++ b/source3/rpc_client/cli_use.c
@@ -156,7 +156,8 @@ static struct cli_use *cli_find(const char* srv_name,
{
continue;
}
- if (!pwd_compare(&usr_creds->pwd, &c->cli->usr.pwd))
+ if (!usr_creds->reuse &&
+ !pwd_compare(&usr_creds->pwd, &c->cli->usr.pwd))
{
continue;
}
@@ -221,6 +222,12 @@ struct cli_state *cli_net_use_add(const char* srv_name,
return cli->cli;
}
+ /* reuse an existing connection requested, and one was not found */
+ if (usr_creds != NULL && usr_creds->reuse)
+ {
+ return False;
+ }
+
/*
* allocate
*/
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 19698a0f83..30fbd4ee9d 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -1362,6 +1362,7 @@ static void cmd_net(struct client_info *info, int argc, char *argv[])
pstrcpy(dest_host, cli_info.dest_host);
pstrcpy(u.user_name,optarg);
+ u.reuse = False;
if (argc <= 1)
{
@@ -1567,6 +1568,8 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
*term_code = 0;
#endif /* KANJI */
+ usr.reuse = False;
+
if (argc > 1 && *argv[1] != '-')
{
if (argc > 1 && (*argv[1] != '-'))
@@ -1579,10 +1582,16 @@ static void cmd_set(struct client_info *info, int argc, char *argv[])
}
}
- while ((opt = getopt(argc, argv, "s:B:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+ while ((opt = getopt(argc, argv, "Rs:B:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
{
switch (opt)
{
+ case 'R':
+ {
+ usr.reuse = True;
+ break;
+ }
+
case 'm':
{
/* FIXME ... max_protocol seems to be funny here */
diff --git a/source3/utils/smb-agent.c b/source3/utils/smb-agent.c
index 8c039dfc86..bcc5eebd75 100644
--- a/source3/utils/smb-agent.c
+++ b/source3/utils/smb-agent.c
@@ -99,6 +99,127 @@ static void agent_request(char *buf)
}
+#define AGENT_CMD_CON 0
+#define AGENT_CMD_CON_REUSE 1
+
+static struct cli_state *init_client_connection(int c)
+{
+ pstring buf;
+ uchar ntpw[16];
+ uchar lmpw[16];
+ fstring srv_name;
+ struct user_credentials usr;
+ char *p = buf;
+ int rl;
+ uint32 len;
+ uint16 version;
+ uint16 command;
+ BOOL new_con = False;
+
+ ZERO_STRUCT(usr);
+
+ DEBUG(10,("first request\n"));
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl != sizeof(len))
+ {
+ DEBUG(0,("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return NULL;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0,("length %d too long\n", len));
+ return NULL;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0,("Unable to read from connection\n"));
+ exit(1);
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+ version = SVAL(p, 0);
+ p += 2;
+ command = SVAL(p, 0);
+ p += 2;
+
+ fstrcpy(srv_name, p);
+ p = skip_string(p, 1);
+ fstrcpy(usr.user_name, p);
+ p = skip_string(p, 1);
+ fstrcpy(usr.domain, p);
+ p = skip_string(p, 1);
+
+ if (PTR_DIFF(p, buf) < rl)
+ {
+ memcpy(ntpw, p, 16);
+ p += 16;
+ memcpy(lmpw, p, 16);
+ p += 16;
+ pwd_set_lm_nt_16(&usr.pwd, lmpw, ntpw);
+ }
+ else
+ {
+ pwd_set_nullpwd(&usr.pwd);
+ }
+
+ if (PTR_DIFF(p, buf) != rl)
+ {
+ DEBUG(0,("Buffer size %d %d!\n",
+ PTR_DIFF(p, buf), rl));
+ exit(1);
+ }
+
+ switch (command)
+ {
+ case AGENT_CMD_CON:
+ {
+ new_con = True;
+ break;
+ }
+ case AGENT_CMD_CON_REUSE:
+ {
+ new_con = True;
+ usr.reuse = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("unknown command %d\n", command));
+ return NULL;
+ }
+ }
+
+ if (new_con)
+ {
+ struct cli_state *s;
+ s = cli_net_use_add(srv_name, &usr, False);
+
+ if (s == NULL)
+ {
+ DEBUG(0,("Unable to connect to %s\n", srv_name));
+ return NULL;
+ }
+ if (write(c, s, sizeof(*s)) < 0)
+ {
+ DEBUG(0,("Could not write connection down pipe.\n"));
+ cli_net_use_del(srv_name, &usr, False, NULL);
+ return NULL;
+ }
+ return s;
+ }
+ return NULL;
+}
static void agent_child(int c)
{
@@ -132,82 +253,9 @@ static void agent_child(int c)
{
if (s == NULL)
{
- pstring buf;
- uchar ntpw[16];
- uchar lmpw[16];
- fstring srv_name;
- struct user_credentials usr;
- char *p = buf;
- int rl;
- uint32 len;
-
- DEBUG(10,("first request\n"));
-
- rl = read(c, &buf, sizeof(len));
-
- if (rl != sizeof(len))
- {
- DEBUG(0,("Unable to read length\n"));
- dump_data(0, buf, sizeof(len));
- exit(1);
- }
-
- len = IVAL(buf, 0);
-
- if (len > sizeof(buf))
- {
- DEBUG(0,("length %d too long\n", len));
- exit(1);
- }
-
- rl = read(c, buf, len);
-
- if (rl < 0)
- {
- DEBUG(0,("Unable to read from connection\n"));
- exit(1);
- }
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, buf, rl);
-#endif
- fstrcpy(srv_name, p);
- p = skip_string(p, 1);
- fstrcpy(usr.user_name, p);
- p = skip_string(p, 1);
- fstrcpy(usr.domain, p);
- p = skip_string(p, 1);
-
- if (PTR_DIFF(p, buf) < rl)
- {
- memcpy(ntpw, p, 16);
- p += 16;
- memcpy(lmpw, p, 16);
- p += 16;
- pwd_set_lm_nt_16(&usr.pwd, lmpw, ntpw);
- }
- else
- {
- pwd_set_nullpwd(&usr.pwd);
- }
-
- if (PTR_DIFF(p, buf) != rl)
- {
- DEBUG(0,("Buffer size %d %d!\n",
- PTR_DIFF(p, buf), rl));
- exit(1);
- }
-
- s = cli_net_use_add(srv_name, &usr, False);
-
+ s = init_client_connection(c);
if (s == NULL)
{
- DEBUG(0,("Unable to connect to %s\n", srv_name));
- exit(1);
- }
- if (write(c, s, sizeof(*s)) < 0)
- {
- DEBUG(0,("Could not write ack\n"));
exit(1);
}
}