This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define NO_SYSLOG
-
#include "includes.h"
/****************************************************************************
if ((SMB_BIG_UINT)offset >> 32)
bigoffset = True;
- set_message(cli->outbuf,bigoffset ? 12 : 10,0,True);
+ set_message(NULL,cli->outbuf,bigoffset ? 12 : 10,0,True);
SCVAL(cli->outbuf,smb_com,SMBreadX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
SIVAL(cli->outbuf,smb_vwv3,offset);
SSVAL(cli->outbuf,smb_vwv5,size);
SSVAL(cli->outbuf,smb_vwv6,size);
- SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1));
+ SSVAL(cli->outbuf,smb_vwv7,(size >> 16));
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
- if (bigoffset)
- SIVAL(cli->outbuf,smb_vwv10,(offset>>32) & 0xffffffff);
+ if (bigoffset) {
+ SIVAL(cli->outbuf,smb_vwv10,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff);
+ }
return cli_send_smb(cli);
}
ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
{
char *p;
- int size2;
- int readsize;
+ size_t size2;
+ size_t readsize;
ssize_t total = 0;
+ /* We can only do direct reads if not signing. */
+ BOOL direct_reads = !client_is_signing_on(cli);
if (size == 0)
return 0;
* rounded down to a multiple of 1024.
*/
- if (cli->capabilities & CAP_LARGE_READX) {
- readsize = CLI_MAX_LARGE_READX_SIZE;
+ if (client_is_signing_on(cli) == False &&
+ cli_encryption_on(cli) == False &&
+ (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
+ readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE;
+ } else if (cli->capabilities & CAP_LARGE_READX) {
+ if (cli->is_samba) {
+ readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE;
+ } else {
+ readsize = CLI_WINDOWS_MAX_LARGE_READX_SIZE;
+ }
} else {
readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
}
if (!cli_issue_read(cli, fnum, offset, readsize, 0))
return -1;
- if (!cli_receive_smb(cli))
- return -1;
+ if (direct_reads) {
+ if (!cli_receive_smb_readX_header(cli))
+ return -1;
+ } else {
+ if (!cli_receive_smb(cli))
+ return -1;
+ }
/* Check for error. Make sure to check for DOS and NT
errors. */
}
size2 = SVAL(cli->inbuf, smb_vwv5);
- size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7) & 1)) << 16);
+ size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16);
if (size2 > readsize) {
DEBUG(5,("server returned more than we wanted!\n"));
return -1;
}
- /* Copy data into buffer */
+ if (!direct_reads) {
+ /* Copy data into buffer */
+ p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6);
+ memcpy(buf + total, p, size2);
+ } else {
+ /* Ensure the remaining data matches the return size. */
+ ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6);
+
+ /* Ensure the size is correct. */
+ if (toread != size2) {
+ DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n",
+ (int)toread, (unsigned int)size2 ));
+ return -1;
+ }
- p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6);
- memcpy(buf + total, p, size2);
+ /* Read data directly into buffer */
+ toread = cli_receive_smb_data(cli,buf+total,size2);
+ if (toread != size2) {
+ DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n",
+ (int)toread, (unsigned int)size2 ));
+ return -1;
+ }
+ }
total += size2;
offset += size2;
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,10,0,True);
+ set_message(NULL,cli->outbuf,10,0,True);
SCVAL(cli->outbuf,smb_com,SMBreadbraw);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
BOOL large_writex = False;
if (size > cli->bufsize) {
- cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024);
- cli->inbuf = SMB_REALLOC(cli->inbuf, size + 1024);
- if (cli->outbuf == NULL || cli->inbuf == NULL)
+ cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024);
+ if (!cli->outbuf) {
return False;
+ }
+ cli->inbuf = (char *)SMB_REALLOC(cli->inbuf, size + 1024);
+ if (cli->inbuf == NULL) {
+ SAFE_FREE(cli->outbuf);
+ return False;
+ }
cli->bufsize = size + 1024;
}
}
if (large_writex)
- set_message(cli->outbuf,14,0,True);
+ set_message(NULL,cli->outbuf,14,0,True);
else
- set_message(cli->outbuf,12,0,True);
+ set_message(NULL,cli->outbuf,12,0,True);
SCVAL(cli->outbuf,smb_com,SMBwriteX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
- if (large_writex)
- SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff);
+ if (large_writex) {
+ SIVAL(cli->outbuf,smb_vwv12,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff);
+ }
p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11);
memcpy(p, buf, size);
0x0008 start of message mode named pipe protocol
****************************************************************************/
-size_t cli_write(struct cli_state *cli,
+ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
const char *buf, off_t offset, size_t size)
{
- int bwritten = 0;
- int issued = 0;
- int received = 0;
+ ssize_t bwritten = 0;
+ unsigned int issued = 0;
+ unsigned int received = 0;
int mpx = 1;
int block = cli->max_xmit - (smb_size+32);
int blocks = (size + (block-1)) / block;
while (received < blocks) {
while ((issued - received < mpx) && (issued < blocks)) {
- int bsent = issued * block;
- int size1 = MIN(block, size - bsent);
+ ssize_t bsent = issued * block;
+ ssize_t size1 = MIN(block, size - bsent);
if (!cli_issue_write(cli, fnum, offset + bsent,
write_mode,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,5, 0,True);
+ set_message(NULL,cli->outbuf,5, 0,True);
SCVAL(cli->outbuf,smb_com,SMBwrite);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
p = smb_buf(cli->outbuf);
*p++ = 1;
SSVAL(p, 0, size); p += 2;
- memcpy(p, buf, size); p += size;
+ memcpy(p, buf + total, size); p += size;
cli_setup_bcc(cli, p);