diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/client.h | 1 | ||||
-rw-r--r-- | source3/include/smb.h | 3 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 20 | ||||
-rw-r--r-- | source3/rpc_client/cli_use.c | 9 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 11 | ||||
-rw-r--r-- | source3/utils/smb-agent.c | 196 |
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); } } |