Updated to version 1.124

Please keep in mind that this is still a development version and might surprise you (not necessarily in a good way).

Do not let me discourage you to build and test this version, although there will be some risks involved such as data corruption or loss of data.
This commit is contained in:
obarthel
2018-05-06 16:50:02 +02:00
parent 61735b08c2
commit 047be4f827
8 changed files with 350 additions and 103 deletions
+29
View File
@@ -1315,3 +1315,32 @@ smbfs 1.122 (5.5.2018)
NetBIOS frame size came out as 65583 bytes (which the NetBIOS
frame handles fine), and the size parameter being a 16 bit integer,
the truncated size (47 bytes) wreaked havoc all over the place.
smbfs 1.123 (6.5.2018)
- smb_proc_readdir_long() could return an error code which would be
mistaken as the number of directory entries available. The error
code should have been negative. Fixed.
- Action_ExamineObject() failed to compare the correct file name
length against the maximum permitted file name length. It retained
the full path name length, which could lead to the operation being
aborted. The same problem also existed in Action_ExamineFH().
- The buffer size check in the UTF-8 conversion code used by
Action_ExamineObject() should have verified that the name in
ISO 8859-1 form fits into the name buffer. Fixed.
- Time stamps used for cache validation are now unsigned integers
rather than signed integers.
smbfs 1.124 (6.5.2018)
- recv() returning 0 is now consistently treated as it should
be: end of stream.
- SMB_COM_READ now receives the inbound data straight into the
file read buffer instead of into the packet buffer, from which
it would then be copied into the file read buffer.
+1 -3
View File
@@ -69,13 +69,11 @@ int smb_proc_dskattr (struct smb_server *server, struct smb_dskattr *attr);
int smb_proc_connect(struct smb_server *server);
/* sock.c */
int smb_receive (struct smb_server *server, int sock_fd);
int smb_receive_with_payload (struct smb_server *server, int sock_fd, void * payload, int payload_size, int * payload_size_received);
int smb_catch_keepalive(struct smb_server *server);
int smb_dont_catch_keepalive(struct smb_server *server);
void smb_release(struct smb_server *server);
int smb_connect(struct smb_server *server);
int smb_request(struct smb_server *server,const void * payload,int payload_size);
int smb_request(struct smb_server *server,void * input_payload,const void * output_payload,int payload_size);
int smb_trans2_request(struct smb_server *server, int *data_len, int *param_len, char **data, char **param);
int smb_request_read_raw(struct smb_server *server, unsigned char *target, int max_len);
int smb_request_write_raw(struct smb_server *server, unsigned const char *source, int length);
+30 -25
View File
@@ -26,8 +26,8 @@
* copy "amiga:Public/Documents/Amiga Files/Shared/dir/Windows-Export/LP2NRFP.h" ram:
* smbfs.debug user=guest volume=sicherung //192.168.1.76/sicherung-smb
* smbfs maxtransmit=16600 debuglevel=2 dumpsmb dumpsmblevel=2 domain=workgroup user=olsen password=... volume=olsen //felix/olsen
* smbfs debuglevel=2 dumpsmb dumpsmblevel=2 volume=ubuntu-test //192.168.1.33/test
* smbfs debuglevel=2 dumpsmb dumpsmblevel=2 user=olsen password=... volume=olsen //192.168.1.118/olsen
* Samba 4.6.7: smbfs debuglevel=2 dumpsmb dumpsmblevel=2 volume=ubuntu-test //192.168.1.33/test
* Samba 3.0.25: smbfs debuglevel=2 dumpsmb dumpsmblevel=1 user=olsen password=... volume=olsen //192.168.1.118/olsen
*/
#include "smbfs.h"
@@ -4296,6 +4296,8 @@ Action_ExamineObject(
SHOWMSG("ZERO root lock");
ASSERT( len < sizeof(fib->fib_FileName) );
memcpy(&fib->fib_FileName[1],&volume_name[1],len);
fib->fib_FileName[0] = len;
@@ -4339,6 +4341,8 @@ Action_ExamineObject(
SHOWMSG("root lock");
ASSERT( len < sizeof(fib->fib_FileName) );
memcpy(&fib->fib_FileName[1],&volume_name[1],len);
fib->fib_FileName[0] = len;
@@ -4351,32 +4355,25 @@ Action_ExamineObject(
else
{
const UBYTE * name;
LONG name_len;
LONG i;
int name_len;
int i;
name = ln->ln_FullName;
name_len = strlen(name);
/* We just want the base name, not the path
* leading up to it.
*/
for(i = name_len-1 ; i >= 0 ; i--)
{
if(name[i] == SMB_PATH_SEPARATOR)
{
name = &name[i+1];
/* We just lost a character and need to account for it. */
name_len--;
name_len -= i+1;
break;
}
}
/* Just checking: will the name fit? */
if(name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
}
/* Translate the name of the file/directory from UTF-8
* into AmigaOS ISO 8859-1 (ISO Latin 1) encoding?
*/
@@ -4385,13 +4382,13 @@ Action_ExamineObject(
UBYTE decoded_name[MAX_FILENAME_LEN];
int decoded_name_len;
/* Try to decode the file file, translating it into ISO 8859-1 format. */
/* Try to decode the file name, translating it into ISO 8859-1 format. */
decoded_name_len = decode_utf8_as_iso8859_1_string(name,name_len,NULL,0);
/* Decoding error occured, or the decoded name would be longer than
* buffer would allow?
*/
if(decoded_name_len < 0 || decoded_name_len >= MAX_FILENAME_LEN)
if(decoded_name_len < 0 || decoded_name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
@@ -4408,6 +4405,13 @@ Action_ExamineObject(
}
else
{
/* Will the name fit? */
if(name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
}
/* Store the file/directory name in the form expected
* by dos.library.
*/
@@ -5844,17 +5848,11 @@ Action_ExamineFH(
if(name[i] == SMB_PATH_SEPARATOR)
{
name = &name[i+1];
name_len -= i+1;
break;
}
}
/* Just checking: will the name fit? */
if(name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
}
memset(fib,0,sizeof(*fib));
if(TranslateUTF8)
@@ -5863,7 +5861,7 @@ Action_ExamineFH(
int decoded_name_len;
decoded_name_len = decode_utf8_as_iso8859_1_string(name,name_len,NULL,0);
if(decoded_name_len < 0 || decoded_name_len >= MAX_FILENAME_LEN)
if(decoded_name_len < 0 || decoded_name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
@@ -5876,6 +5874,13 @@ Action_ExamineFH(
}
else
{
/* Will the name fit? */
if(name_len >= sizeof(fib->fib_FileName))
{
error = ERROR_INVALID_COMPONENT_NAME;
goto out;
}
ConvertCString(fib->fib_FileName,sizeof(fib->fib_FileName),name,name_len);
if(TranslateNames)
+67 -29
View File
@@ -702,7 +702,8 @@ smb_request_ok_with_payload (
int command,
int wct,
int bcc,
const void * payload,
void * input_payload,
const void * output_payload,
int payload_size)
{
int result;
@@ -712,7 +713,7 @@ smb_request_ok_with_payload (
s->err = 0;
/* Send the message and wait for the response to arrive. */
result = smb_request (s, payload, payload_size);
result = smb_request (s, input_payload, output_payload, payload_size);
/* smb_request() failed? */
if (result < 0)
@@ -751,7 +752,7 @@ smb_request_ok_with_payload (
static int
smb_request_ok (struct smb_server *s, int command, int wct, int bcc)
{
return(smb_request_ok_with_payload (s, command, wct, bcc, NULL, 0));
return(smb_request_ok_with_payload (s, command, wct, bcc, NULL, NULL, 0));
}
/* smb_retry: This function should be called when smb_request_ok has
@@ -977,7 +978,6 @@ smb_proc_close (struct smb_server *server, word fileid, dword mtime)
int
smb_proc_read (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data)
{
word returned_count, data_len;
char *buf = server->transmit_buffer;
int result;
int error;
@@ -991,31 +991,69 @@ smb_proc_read (struct smb_server *server, struct smb_dirent *finfo, off_t offset
DSET (buf, smb_vwv2, offset);
WSET (buf, smb_vwv4, 0);
if ((error = smb_request_ok (server, SMBread, 5, -1)) < 0)
#if 1
{
result = error;
goto out;
int buffer_format;
LOG(("smb_proc_read: requesting %ld bytes\n", count));
if ((error = smb_request_ok_with_payload (server, SMBread, 5, -1, data, NULL, count)) < 0)
{
LOG(("smb_proc_read: error=%ld\n", error));
result = error;
goto out;
}
buffer_format = BVAL(buf, NETBIOS_HEADER_SIZE+45);
LOG(("smb_proc_read: buffer_format=%ld, should be %ld\n", buffer_format, 1));
/* The buffer format must be 1. */
if(buffer_format == 1)
{
result = WVAL (buf, NETBIOS_HEADER_SIZE+46); /* count of bytes to read */
ASSERT( result <= count );
LOG(("smb_proc_read: read %ld bytes (should be < %ld)\n", result, count));
}
else
{
LOG(("smb_proc_read: returning EOF\n"));
result = 0;
}
}
returned_count = WVAL (buf, smb_vwv0);
/* ZZZ olsen 2018-05-01: this should not be necessary; we should be
* able to break this down into two subsequent
* recv() calls.
*/
smb_decode_data (SMB_BUF (server->transmit_buffer), data, &data_len);
if (returned_count != data_len)
#else
{
LOG (("Warning, returned_count != data_len\n"));
LOG (("ret_c=%ld, data_len=%ld\n", returned_count, data_len));
}
else
{
LOG (("ret_c=%ld, data_len=%ld\n", returned_count, data_len));
}
word returned_count, data_len;
result = data_len;
if ((error = smb_request_ok_with_payload (server, SMBread, 5, -1, data, NULL, count)) < 0)
{
result = error;
goto out;
}
returned_count = WVAL (buf, smb_vwv0);
/* ZZZ olsen 2018-05-01: this should not be necessary; we should be
* able to break this down into two subsequent
* recv() calls.
*/
smb_decode_data (SMB_BUF (server->transmit_buffer), data, &data_len);
if (returned_count != data_len)
{
LOG (("Warning, returned_count != data_len\n"));
LOG (("ret_c=%ld, data_len=%ld\n", returned_count, data_len));
}
else
{
LOG (("ret_c=%ld, data_len=%ld\n", returned_count, data_len));
}
result = data_len;
}
#endif
out:
@@ -1065,7 +1103,7 @@ smb_proc_write (struct smb_server *server, struct smb_dirent *finfo, off_t offse
(*p++) = 1; /* Buffer format - this field must be 1 */
WSET (p, 0, count); /* Data length - this field must match what the count field in the SMB header says */
if ((res = smb_request_ok_with_payload (server, SMBwrite, 1, 0, data, count)) >= 0)
if ((res = smb_request_ok_with_payload (server, SMBwrite, 1, 0, NULL, data, count)) >= 0)
res = WVAL (buf, smb_vwv0);
return res;
@@ -1158,7 +1196,7 @@ smb_proc_write_raw (struct smb_server *server, struct smb_dirent *finfo, off_t o
LOG(("requesting SMBwritebraw\n"));
result = smb_request_ok_with_payload (server, SMBwritebraw, 1, 0, data, len);
result = smb_request_ok_with_payload (server, SMBwritebraw, 1, 0, NULL, data, len);
if (result < 0)
goto out;
@@ -2122,7 +2160,7 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
smb_printerr (server->rcls, server->err);
error = smb_errno (server->rcls, server->err);
error = -smb_errno (server->rcls, server->err);
SHOWVALUE(error);
break;
}
@@ -2631,7 +2669,7 @@ smb_proc_reconnect (struct smb_server *server)
packet[0] = 0x81; /* SESSION REQUEST */
if ((result = smb_request (server, NULL, 0)) < 0)
if ((result = smb_request (server, NULL, NULL, 0)) < 0)
{
LOG (("smb_proc_connect: Failed to send SESSION REQUEST.\n"));
goto fail;
+21 -15
View File
@@ -20,8 +20,8 @@
/*****************************************************************************/
#define ATTR_CACHE_TIME 5 /* cache attributes for this time */
#define DIR_CACHE_TIME 5 /* cache directories for this time */
#define ATTR_CACHE_TIME 5 /* cache attributes for this time (seconds) */
#define DIR_CACHE_TIME 5 /* cache directories for this time (seconds) */
#define DIRCACHE_SIZE 170
#define DOS_PATHSEP '\\'
@@ -32,7 +32,7 @@ typedef struct dircache
int base;
int len;
int eof; /* cache end is eof */
long created_at; /* for invalidation */
ULONG created_at; /* for invalidation */
struct smba_file * cache_for; /* owner of this cache */
int cache_size;
struct smb_dirent cache[1];
@@ -53,7 +53,7 @@ struct smba_file
struct MinNode node;
struct smba_server * server;
struct smb_dirent dirent;
long attr_time; /* time when dirent was read */
ULONG attr_time; /* time when dirent was read */
dircache_t * dircache; /* content cache for directories */
unsigned attr_dirty:1; /* attribute cache is dirty */
unsigned is_valid:1; /* server was down, entry removed, ... */
@@ -79,7 +79,7 @@ struct smba_file
/*****************************************************************************/
static INLINE int make_open(smba_file_t *f, int need_fid);
static int make_open(smba_file_t *f, int need_fid);
static int write_attr(smba_file_t *f);
static void invalidate_dircache(struct smba_server *server, char *path);
static void close_path(smba_server_t *s, char *path);
@@ -256,7 +256,7 @@ smba_disconnect (smba_server_t * server)
/*****************************************************************************/
static INLINE int
static int
make_open (smba_file_t * f, int need_fid)
{
smba_server_t *s;
@@ -264,9 +264,11 @@ make_open (smba_file_t * f, int need_fid)
if (!f->is_valid || (need_fid && !f->dirent.opened))
{
ULONG now = GetCurrentTime();
s = f->server;
if (!f->is_valid || f->attr_time == -1 || GetCurrentTime() - f->attr_time > ATTR_CACHE_TIME)
if (!f->is_valid || f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
{
errnum = smb_proc_getattr_core (&s->server, f->dirent.complete_path, f->dirent.len, &f->dirent);
if (errnum < 0)
@@ -385,7 +387,7 @@ write_attr (smba_file_t * f)
if (errnum < 0)
{
f->attr_time = -1;
f->attr_time = 0;
goto out;
}
@@ -765,7 +767,7 @@ smba_write (smba_file_t * f, char *data, long len, long offset)
out:
if (result < 0)
f->attr_time = -1;
f->attr_time = 0;
else if (result > 0)
f->dirent.mtime = GetCurrentTime();
@@ -862,9 +864,9 @@ smba_lockrec (smba_file_t *f, long offset, long len, long mode, int unlocked, lo
int
smba_getattr (smba_file_t * f, smba_stat_t * data)
{
long now = GetCurrentTime();
int errnum;
int result;
ULONG now;
errnum = make_open (f, 0);
if (errnum < 0)
@@ -873,7 +875,9 @@ smba_getattr (smba_file_t * f, smba_stat_t * data)
goto out;
}
if (f->attr_time == -1 || (now - f->attr_time) > ATTR_CACHE_TIME)
now = GetCurrentTime();
if (f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
{
LOG (("file %s\n", f->dirent.complete_path));
@@ -982,11 +986,11 @@ int
smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback)
{
int cache_index, o, eof, count = 0;
long now = GetCurrentTime();
int num_entries;
smba_stat_t data;
int result;
int errnum;
ULONG now;
errnum = make_open (f, 0);
if (errnum < 0)
@@ -995,6 +999,8 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback)
goto out;
}
now = GetCurrentTime();
if (f->dircache == NULL) /* get a cache */
{
dircache_t * dircache = f->server->dircache;
@@ -1011,7 +1017,7 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback)
}
else
{
if ((now - f->dircache->created_at) >= DIR_CACHE_TIME)
if (now > f->dircache->created_at && now - f->dircache->created_at >= DIR_CACHE_TIME)
{
f->dircache->eof = f->dircache->len = f->dircache->base = 0;
@@ -1034,6 +1040,7 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback)
f->dircache->base = cache_index;
num_entries = smb_proc_readdir (&f->server->server, f->dirent.complete_path, cache_index, f->dircache->cache_size, f->dircache->cache);
/* We stop on error, or if the directory is empty. */
if (num_entries <= 0)
{
@@ -1043,12 +1050,11 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback)
/* Avoid some hits if restart/retry occured. Should fix the real root
* of this problem really, but I am not bored enough atm. -Piru
* ZZZ this needs further investigation.
*/
if (f->dircache == NULL)
{
LOG (("lost dircache due to an error, bailing out!\n"));
result = -ENOSPC;
result = -ENOMEM;
goto out;
}
+5 -5
View File
@@ -1,6 +1,6 @@
#define VERSION 1
#define REVISION 122
#define DATE "5.5.2018"
#define VERS "smbfs 1.122"
#define VSTRING "smbfs 1.122 (5.5.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.122 (5.5.2018)"
#define REVISION 124
#define DATE "6.5.2018"
#define VERS "smbfs 1.124"
#define VSTRING "smbfs 1.124 (6.5.2018)\r\n"
#define VERSTAG "\0$VER: smbfs 1.124 (6.5.2018)"
+1 -1
View File
@@ -1 +1 @@
122
124
+196 -25
View File
@@ -57,10 +57,17 @@
/* smb_receive_raw: The NetBIOS header is only stored if want_header != 0. */
static int
smb_receive_raw (const struct smb_server *server, int sock_fd, unsigned char *target, int max_raw_length, int want_header)
smb_receive_raw (
const struct smb_server * server,
int sock_fd,
unsigned char * target,
int max_raw_length,
char * input_payload,
int input_payload_size,
int want_header)
{
int len, result;
int already_read;
int num_bytes_received;
unsigned char netbios_session_buf[256];
int netbios_session_payload_size;
@@ -68,6 +75,14 @@ smb_receive_raw (const struct smb_server *server, int sock_fd, unsigned char *ta
/* Read the NetBIOS session header (rfc-1002, section 4.3.1) */
result = recv (sock_fd, netbios_session_buf, NETBIOS_HEADER_SIZE, 0);
if(result == 0)
{
LOG (("smb_receive_raw: EOF\n"));
/* End of file */
goto out;
}
if (result < 0)
{
LOG (("smb_receive_raw: recv error = %ld\n", errno));
@@ -144,7 +159,7 @@ smb_receive_raw (const struct smb_server *server, int sock_fd, unsigned char *ta
goto out;
}
/* The length in the RFC NB header is the raw data length (17 bits) */
/* The length in the NetBIOS header is the raw data length (17 bits) */
len = netbios_session_payload_size;
if (len > max_raw_length)
{
@@ -170,35 +185,190 @@ smb_receive_raw (const struct smb_server *server, int sock_fd, unsigned char *ta
target += NETBIOS_HEADER_SIZE;
}
for(already_read = 0 ; already_read < len ; already_read += result)
/* This is an optimization for the SMB_COM_READ command, which
* tries to avoid copying the received data twice. To this end
* we receive the SMB_COM_READ response up to the point at which
* the message header ends and the data returned by the server
* begins. Then we read the data, storing it directly in the
* receive buffer rather than in the packet buffer, from which
* it would have to be retrieved later.
*/
if(input_payload != NULL)
{
result = recv (sock_fd, (void *) (target + already_read), len - already_read, 0);
if (result < 0)
int buffer_format;
LOG(("input_payload=0x%08lx, payload_size=%ld\n", input_payload, input_payload_size));
/* We need to read the following data:
*
* 0: 32 bytes of SMB message header
* 32: 1 byte of word count
* 33: 2 bytes of 'count of bytes returned' (1 word)
* 35: 8 bytes of reserved data (4 words)
* 43: 2 bytes of 'byte count' (1 word)
* 45: 1 byte of 'buffer format'
* 46: 2 bytes of 'count of bytes to read' (1 word).
*
* This adds up to 48 bytes.
*/
LOG(("reading the first %ld bytes\n", 48));
for(num_bytes_received = 0 ; num_bytes_received < 48 && num_bytes_received < len ; num_bytes_received += result)
{
LOG (("smb_receive_raw: recvfrom error = %ld\n", errno));
result = recv (sock_fd, (void *)&target[num_bytes_received], 48 - num_bytes_received, 0);
if(result == 0)
{
/* End of file */
LOG (("smb_receive_raw: EOF\n"));
break;
}
result = (-errno);
if (result < 0)
{
LOG (("smb_receive_raw: recvfrom error = %ld\n", errno));
result = (-errno);
goto out;
}
}
ASSERT( num_bytes_received == 48 );
/* End of file reached? */
if(num_bytes_received < 48)
{
result = 0;
goto out;
}
/* So we read the header. Now we need to figure out if the
* data is in the expected format, and how many bytes are
* waiting to be read.
*/
/* The buffer format must be 1. */
buffer_format = BVAL(target, 45);
LOG(("buffer format = %ld, should be %ld\n", buffer_format, 1));
if(buffer_format == 1)
{
int count_of_bytes_returned;
int count_of_bytes_to_read;
int num_data_bytes_received;
count_of_bytes_returned = WVAL(target, 33);
count_of_bytes_to_read = WVAL(target, 46);
/* That should never be more data than the read buffer may hold. */
ASSERT( count_of_bytes_to_read <= input_payload_size );
ASSERT( count_of_bytes_to_read <= count_of_bytes_returned );
ASSERT( count_of_bytes_returned <= input_payload_size );
LOG(("count of bytes to read = %ld, should be <= %ld\n", count_of_bytes_to_read, input_payload_size));
for(num_data_bytes_received = 0 ;
num_data_bytes_received < count_of_bytes_to_read && num_bytes_received < len ;
num_data_bytes_received += result, num_bytes_received += result)
{
result = recv (sock_fd, (void *)&input_payload[num_data_bytes_received], count_of_bytes_to_read - num_data_bytes_received, 0);
if(result == 0)
{
/* End of file */
LOG (("smb_receive_raw: EOF\n"));
break;
}
if (result < 0)
{
LOG (("smb_receive_raw: recvfrom error = %ld\n", errno));
result = (-errno);
goto out;
}
}
ASSERT( count_of_bytes_to_read == count_of_bytes_returned );
if(count_of_bytes_to_read < count_of_bytes_returned)
{
LOG(("fewer data available than should be delivered; setting the remainder (%ld bytes) to 0.\n", count_of_bytes_returned - count_of_bytes_to_read));
memset(&input_payload[count_of_bytes_to_read],0,count_of_bytes_returned - count_of_bytes_to_read);
}
}
/* This should never happen, but then we better make sure to
* read the entire message.
*/
if(num_bytes_received < len)
{
LOG(("reading the remaining %ld bytes; this should never happen\n", len - num_bytes_received ));
for( ; num_bytes_received < len ; num_bytes_received += result)
{
result = recv (sock_fd, (void *)&target[num_bytes_received], len - num_bytes_received, 0);
if(result == 0)
{
LOG (("smb_receive_raw: EOF\n"));
/* End of file */
break;
}
if (result < 0)
{
LOG (("smb_receive_raw: recvfrom error = %ld\n", errno));
result = (-errno);
goto out;
}
}
}
}
else
{
for(num_bytes_received = 0 ; num_bytes_received < len ; num_bytes_received += result)
{
result = recv (sock_fd, (void *)&target[num_bytes_received], len - num_bytes_received, 0);
if(result == 0)
{
/* End of file */
LOG (("smb_receive_raw: EOF\n"));
break;
}
if (result < 0)
{
LOG (("smb_receive_raw: recvfrom error = %ld\n", errno));
result = (-errno);
goto out;
}
}
}
#if defined(DUMP_SMB)
{
/* If want_header==0 then this is the data returned by SMB_COM_READ_RAW. */
dump_smb(__FILE__,__LINE__,!want_header,target,already_read,smb_packet_to_consumer,server->max_recv);
dump_smb(__FILE__,__LINE__,!want_header,target,num_bytes_received,smb_packet_to_consumer,server->max_recv);
}
#endif /* defined(DUMP_SMB) */
result = len;
result = num_bytes_received;
out:
return result;
}
int
smb_receive (struct smb_server *server, int sock_fd)
static int
smb_receive (struct smb_server *server, int sock_fd, void * input_payload, int payload_size)
{
byte * packet = server->transmit_buffer;
int result;
@@ -206,15 +376,16 @@ smb_receive (struct smb_server *server, int sock_fd)
ASSERT( server->max_recv <= server->transmit_buffer_size );
result = smb_receive_raw (server, sock_fd, packet,
server->max_recv - NETBIOS_HEADER_SIZE, /* max_xmit in server includes NB header */
1); /* We want the header */
server->max_recv,
input_payload, payload_size,
TRUE); /* We want the NetBIOS frame header */
if (result < 0)
{
LOG (("smb_receive: receive error: %ld\n", result));
goto out;
}
server->rcls = *((unsigned char *) (packet + 9));
server->rcls = BVAL (packet, 9);
server->err = WVAL (packet, 11);
if (server->rcls != 0)
@@ -263,7 +434,7 @@ smb_receive_trans2 (
(*data_len_ptr) = (*param_len_ptr) = 0;
(*param_ptr) = (*data_ptr) = NULL;
result = smb_receive (server, sock_fd);
result = smb_receive (server, sock_fd, NULL, 0);
if (result < 0)
goto fail;
@@ -374,7 +545,7 @@ smb_receive_trans2 (
if (total_data <= data_len && total_param <= param_len)
break;
result = smb_receive (server, sock_fd);
result = smb_receive (server, sock_fd, NULL, 0);
if (result < 0)
goto fail;
@@ -447,7 +618,7 @@ smb_connect (struct smb_server *server)
* case of error.
*/
int
smb_request (struct smb_server *server, const void * payload, int payload_size)
smb_request (struct smb_server *server, void * input_payload, const void * output_payload, int payload_size)
{
int len, result;
int sock_fd = server->mount_data.fd;
@@ -477,7 +648,7 @@ smb_request (struct smb_server *server, const void * payload, int payload_size)
/* If there is a separate payload, only send the header
* here and take care of the payload later.
*/
if(payload != NULL && payload_size > 0)
if(output_payload != NULL && payload_size > 0)
{
ASSERT( payload_size < smb_len(buffer) );
ASSERT( len > payload_size );
@@ -485,7 +656,7 @@ smb_request (struct smb_server *server, const void * payload, int payload_size)
len -= payload_size;
}
LOG (("smb_request: len = %ld, cmd = 0x%lx, payload=0x%08lx, payload_size=%ld\n", len, buffer[8], payload, payload_size));
LOG (("smb_request: len = %ld, cmd = 0x%lx, input_payload=0x%08lx, output_payload=0x%08lx, payload_size=%ld\n", len, buffer[8], input_payload, output_payload, payload_size));
#if defined(DUMP_SMB)
dump_netbios_header(__FILE__,__LINE__,buffer,&buffer[NETBIOS_HEADER_SIZE],len);
@@ -501,9 +672,9 @@ smb_request (struct smb_server *server, const void * payload, int payload_size)
goto out;
}
if(payload != NULL && payload_size > 0)
if(output_payload != NULL && payload_size > 0)
{
result = send (sock_fd, (void *)payload, payload_size, 0);
result = send (sock_fd, (void *)output_payload, payload_size, 0);
if (result < 0)
{
LOG(("smb_request: payload send() for %ld bytes failed (errno=%ld)\n", payload_size, errno));
@@ -513,7 +684,7 @@ smb_request (struct smb_server *server, const void * payload, int payload_size)
}
}
result = smb_receive (server, sock_fd);
result = smb_receive (server, sock_fd, input_payload, payload_size);
out:
@@ -622,7 +793,7 @@ smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_
}
/* Wait for the raw data to be sent by the server. */
result = smb_receive_raw (server, sock_fd, target, max_len, 0);
result = smb_receive_raw (server, sock_fd, target, max_len, NULL, 0, FALSE);
out:
@@ -690,7 +861,7 @@ smb_request_write_raw (struct smb_server *server, unsigned const char *source, i
/* Wait for the server to respond. */
if(!server->write_behind)
{
result = smb_receive (server, sock_fd);
result = smb_receive (server, sock_fd, NULL, 0);
if(result < 0)
goto out;
}