diff options
Diffstat (limited to 'source/libsmb')
-rw-r--r-- | source/libsmb/clientgen.c | 199 |
1 files changed, 150 insertions, 49 deletions
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 550f7cc391d..bb792b7e2bd 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -39,18 +39,27 @@ static BOOL cli_receive_smb(struct cli_state *cli) /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) +static BOOL cli_send_smb(struct cli_state *cli, BOOL show) { size_t len; size_t nwritten=0; ssize_t ret; BOOL reestablished=False; + if (show) + { + show_msg(cli->outbuf); + } + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { + if (ret <= 0 && errno == EPIPE && !reestablished) + { + DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n", + strerror(errno))); + if (cli_reestablish_connection(cli)) { reestablished = True; nwritten=0; @@ -60,8 +69,7 @@ static BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", len,ret)); - close_sockets(); - exit(1); + return False; } nwritten += ret; } @@ -259,8 +267,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -300,8 +307,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); tot_data += this_ldata; tot_param += this_lparam; @@ -328,8 +334,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -382,8 +386,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -759,11 +761,12 @@ BOOL cli_session_setup(struct cli_state *cli, set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { + DEBUG(10,("cli_session_setup: receive smb failed\n")); return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; @@ -804,7 +807,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -858,7 +861,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -899,7 +902,7 @@ BOOL cli_tdis(struct cli_state *cli) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -931,7 +934,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) *p++ = 4; pstrcpy(p,fname_dst); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -965,7 +968,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) *p++ = 4; pstrcpy(p,fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -997,7 +1000,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1029,7 +1032,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1074,7 +1077,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1145,7 +1148,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1177,7 +1180,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1218,7 +1221,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1264,7 +1267,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1300,7 +1303,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1406,8 +1409,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1495,7 +1497,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1549,7 +1551,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, *p = 4; pstrcpy(p+1, fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1600,7 +1602,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = skip_string(p,1); *p = 4; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2163,13 +2165,14 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; - if (cli_send_trans(cli,SMBtrans, + if (!cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ data,data_len,0 /* data, length, max */ - ) == False) { + )) + { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; @@ -2223,11 +2226,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0 || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { @@ -2305,7 +2308,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli); + cli_send_smb(cli, False); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) @@ -2401,6 +2404,7 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { + DEBUG(10,("cli_shutdown\n")); if (cli->outbuf) { free(cli->outbuf); @@ -2414,7 +2418,9 @@ void cli_shutdown(struct cli_state *cli) sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ if (cli->fd != -1) - close(cli->fd); + { + close(cli->fd); + } memset(cli, 0, sizeof(*cli)); } @@ -2429,10 +2435,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; + if (!cli->initialised) + { + DEBUG(0,("cli_error: client state uninitialised!\n")); + return EINVAL; + } + + flgs2 = SVAL(cli->inbuf,smb_flg2); + if (eclass) *eclass = 0; if (num ) *num = 0; @@ -2671,7 +2685,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2682,20 +2698,105 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } } } if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return True; } /**************************************************************************** + connect to one of multiple servers: don't care which +****************************************************************************/ +BOOL cli_connect_serverlist(struct cli_state *cli, char *p) +{ + extern pstring global_myname; + extern pstring scope; + fstring remote_machine; + struct in_addr dest_ip; + struct nmb_name calling, called; + BOOL connected_ok = True; + + ZERO_STRUCT(cli); + + if (!cli_initialise(cli)) + { + DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + return False; + } + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) + { + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if (!resolve_name( remote_machine, &dest_ip, 0x20)) + { + DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); + continue; + } + + if (ismyip(dest_ip)) + { + DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); + continue; + } + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + pwd_set_nullpwd(&cli->pwd); + + if (!cli_establish_connection(cli, remote_machine, &dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + cli_shutdown(cli); + continue; + } + + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + + connected_ok = True; + break; + } + + if (!connected_ok) + { + DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); + cli_shutdown(cli); + } + + return connected_ok; +} + +/**************************************************************************** cancel a print job ****************************************************************************/ int cli_printjob_del(struct cli_state *cli, int job) @@ -2826,7 +2927,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) *p++ = 4; fstrcpy(p,path2); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2862,7 +2963,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2895,7 +2996,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) *p = 1; SSVAL(p,1,len); memcpy(p+3,msg,len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2920,7 +3021,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp) cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2943,7 +3044,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } |