summaryrefslogtreecommitdiff
path: root/source3/lib/util_sock.c
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-07-23 09:36:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:28:53 -0500
commitcc6a41017c577742af73b4bc60993d8d415ea580 (patch)
treea1705a0b1dedc300c7c728fd4fad6fe53192bf10 /source3/lib/util_sock.c
parent041204d1a4ec9b19287ca92fa5b291a8eb5ff10b (diff)
downloadsamba-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/util_sock.c')
-rw-r--r--source3/lib/util_sock.c116
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.
****************************************************************************/