diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-07-23 09:36:09 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:28:53 -0500 |
commit | cc6a41017c577742af73b4bc60993d8d415ea580 (patch) | |
tree | a1705a0b1dedc300c7c728fd4fad6fe53192bf10 /source3/lib | |
parent | 041204d1a4ec9b19287ca92fa5b291a8eb5ff10b (diff) | |
download | samba-cc6a41017c577742af73b4bc60993d8d415ea580.tar.gz samba-cc6a41017c577742af73b4bc60993d8d415ea580.tar.bz2 samba-cc6a41017c577742af73b4bc60993d8d415ea580.zip |
r23997: Check in the infrastructure for getting rid of the global InBuffer/OutBuffer
The complete history of this patch can be found under
http://www.samba.org/~vlendec/inbuf-checkin/.
Jeremy, Jerry: If possible I would like to see this in 3.2.0. I'm only
checking into 3_2 at the moment, as it currently will slow down operations for
all non-converted (i.e. all at this moment) operations, as it will copy the
talloc'ed inbuf over the global InBuffer. It will need quite a bit of effort
to convert everything necessary for the normal operations an XP box does.
I have patches for negprot, session setup, tcon_and_X, open_and_X, close. More
to come, but I would appreciate some help here.
Volker
(This used to be commit 5594af2b208c860d3f4b453af6a649d9e4295d1c)
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/util_sock.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 46d640cd55..9dcbdd9f02 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -730,6 +730,85 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle return len; } +static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, + char **buffer, unsigned int timeout) +{ + char lenbuf[4]; + ssize_t len,ret; + + smb_read_error = 0; + + len = read_smb_length_return_keepalive(fd, lenbuf, timeout); + if (len < 0) { + DEBUG(10,("receive_smb_raw: length < 0!\n")); + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + + /* + * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes + * of header. Don't print the error if this fits.... JRA. + */ + + if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) { + DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { + + /* + * Correct fix. smb_read_error may have already been + * set. Only set it here if not already set. Global + * variables still suck :-). JRA. + */ + + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + } + + /* + * The +4 here can't wrap, we've checked the length above already. + */ + + *buffer = TALLOC_ARRAY(mem_ctx, char, len+4); + + if (*buffer == NULL) { + DEBUG(0, ("Could not allocate inbuf of length %d\n", + (int)len+4)); + if (smb_read_error == 0) + smb_read_error = READ_ERROR; + return -1; + } + + memcpy(*buffer, lenbuf, sizeof(lenbuf)); + + if(len > 0) { + if (timeout > 0) { + ret = read_socket_with_timeout(fd,(*buffer)+4, len, + len, timeout); + } else { + ret = read_data(fd, (*buffer)+4, len); + } + + if (ret != len) { + if (smb_read_error == 0) { + smb_read_error = READ_ERROR; + } + return -1; + } + } + + return len + 4; +} + /**************************************************************************** Wrapper for receive_smb_raw(). Checks the MAC on signed packets. @@ -765,6 +844,43 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout) return True; } +ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, + unsigned int timeout) +{ + ssize_t len; + + len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout); + + if (len < 0) { + return -1; + } + + if (srv_encryption_on()) { + NTSTATUS status = srv_decrypt_buffer(*buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed on " + "incoming packet! Error %s\n", + nt_errstr(status) )); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_DECRYPT; + } + return -1; + } + } + + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(*buffer, True)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on " + "incoming packet!\n")); + if (smb_read_error == 0) { + smb_read_error = READ_BAD_SIG; + } + return -1; + } + + return len; +} + /**************************************************************************** Send an smb to a fd. ****************************************************************************/ |