summaryrefslogtreecommitdiffstats
path: root/source3/libsmb/clientgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb/clientgen.c')
-rw-r--r--source3/libsmb/clientgen.c173
1 files changed, 161 insertions, 12 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index c85de929893..89caad419fd 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -1604,31 +1604,26 @@ BOOL cli_negprot(struct cli_state *cli)
/****************************************************************************
- send a session request
+ send a session request. see rfc1002.txt 4.3 and 4.3.2
****************************************************************************/
-BOOL cli_session_request(struct cli_state *cli, char *host, int name_type,
- char *myname)
+BOOL cli_session_request(struct cli_state *cli,
+ struct nmb_name *calling, struct nmb_name *called)
{
- fstring dest;
char *p;
int len = 4;
/* send a session request (RFC 1002) */
- fstrcpy(dest,host);
+ memcpy(&(cli->calling), calling, sizeof(*calling));
+ memcpy(&(cli->called ), called , sizeof(*called ));
- p = strchr(dest,'.');
- if (p) *p = 0;
-
- fstrcpy(cli->desthost, dest);
-
/* put in the destination name */
p = cli->outbuf+len;
- name_mangle(dest,p,name_type);
+ name_mangle(cli->called .name, p, cli->called .name_type);
len += name_len(p);
/* and my name */
p = cli->outbuf+len;
- name_mangle(myname,p,0);
+ name_mangle(cli->calling.name, p, cli->calling.name_type);
len += name_len(p);
/* setup the packet length */
@@ -1754,3 +1749,157 @@ int cli_setpid(struct cli_state *cli, int pid)
cli->pid = pid;
return ret;
}
+
+/****************************************************************************
+establishes a connection right up to doing tconX, reading in a password.
+****************************************************************************/
+BOOL cli_reestablish_connection(struct cli_state *cli)
+{
+ struct nmb_name calling;
+ struct nmb_name called;
+ fstring dest_host;
+ struct in_addr dest_ip;
+ fstring share;
+ fstring dev;
+ BOOL do_tcon = False;
+
+ if (!cli->initialised || cli->fd == -1)
+ {
+ DEBUG(3,("cli_reestablish_connection: not connected\n"));
+ return False;
+ }
+
+ /* copy the parameters necessary to re-establish the connection */
+
+ if (cli->cnum != 0)
+ {
+ fstrcpy(share, cli->share);
+ fstrcpy(dev , cli->dev);
+ do_tcon = True;
+ }
+
+ memcpy(&called , &(cli->called ), sizeof(called ));
+ memcpy(&calling, &(cli->calling), sizeof(calling));
+ fstrcpy(dest_host, cli->full_dest_host_name);
+ dest_ip = cli->dest_ip;
+
+ DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
+ namestr(&calling), namestr(&called), inet_ntoa(dest_ip),
+ cli->user_name, cli->domain));
+
+ return cli_establish_connection(cli,
+ dest_host, &dest_ip,
+ &calling, &called,
+ share, dev, False, do_tcon);
+}
+
+/****************************************************************************
+establishes a connection right up to doing tconX, reading in a password.
+****************************************************************************/
+BOOL cli_establish_connection(struct cli_state *cli,
+ char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ char *service, char *service_type,
+ BOOL do_shutdown, BOOL do_tcon)
+{
+ DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
+ namestr(calling), namestr(called), inet_ntoa(*dest_ip),
+ cli->user_name, cli->domain));
+
+ /* establish connection */
+
+ if ((!cli->initialised))
+ {
+ return False;
+ }
+
+ if (cli->fd == -1)
+ {
+ if (!cli_connect(cli, dest_host, dest_ip))
+ {
+ DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
+ namestr(calling), inet_ntoa(*dest_ip)));
+ return False;
+ }
+ }
+
+ if (!cli_session_request(cli, calling, called))
+ {
+ DEBUG(1,("failed session request\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+
+ if (!cli_negprot(cli))
+ {
+ DEBUG(1,("failed negprot\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+
+ if (cli->pwd.cleartext || cli->pwd.null_pwd)
+ {
+ /* attempt clear-text session */
+
+ fstring passwd;
+
+ pwd_get_cleartext(&(cli->pwd), passwd);
+
+ /* attempt clear-text session */
+ if (!cli_session_setup(cli, cli->user_name,
+ passwd, strlen(passwd),
+ NULL, 0,
+ cli->domain))
+ {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+ if (do_tcon)
+ {
+ if (!cli_send_tconX(cli, service, service_type,
+ (char*)passwd, strlen(passwd)))
+ {
+ DEBUG(1,("failed tcon_X\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+ }
+ }
+ else
+ {
+ /* attempt encrypted session */
+ uchar nt_sess_pwd[24];
+ uchar lm_sess_pwd[24];
+
+ /* creates (storing a copy of) and then obtains a 24 byte password OWF */
+ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
+ pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
+
+ /* attempt encrypted session */
+ if (!cli_session_setup(cli, cli->user_name,
+ (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
+ nt_sess_pwd, sizeof(nt_sess_pwd),
+ cli->domain))
+ {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+
+ if (do_tcon)
+ {
+ if (!cli_send_tconX(cli, service, service_type,
+ (char*)nt_sess_pwd, sizeof(nt_sess_pwd)))
+ {
+ DEBUG(1,("failed tcon_X\n"));
+ if (do_shutdown) cli_shutdown(cli);
+ return False;
+ }
+ }
+ }
+
+ if (do_shutdown) cli_shutdown(cli);
+
+ return True;
+}