From ae74aa9993863be8f75f203201b338e98824ce06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Nov 2007 21:47:00 -0800 Subject: Constrain "min receivefile size" to max of BUFFER_SIZE (128k). Add debug error messages so we can see why writeX large is denied. Ensure we don't allow recvfile writes on IPC$. Jeremy. (This used to be commit 6bf053a6a17749a3bc73c8cc5fd490aa5f93b763) --- source3/param/loadparm.c | 9 ++++++++- source3/smbd/reply.c | 22 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 19af6aa3cf..07f8dc4144 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -2169,7 +2169,6 @@ FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase) FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout) FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing) FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing) -FN_GLOBAL_INTEGER(lp_min_receive_file_size, &Globals.iminreceivefile); FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping) /* local prototypes */ @@ -6242,3 +6241,11 @@ void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val) posix_default_lock_was_set = True; posix_cifsx_locktype = val; } + +int lp_min_receive_file_size(void) +{ + if (Globals.iminreceivefile < 0) { + return 0; + } + return MIN(Globals.iminreceivefile, BUFFER_SIZE); +} diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 1b36fb1e44..45081808e1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3856,16 +3856,24 @@ bool is_valid_writeX_buffer(const char *inbuf) unsigned int doff = 0; size_t len = smb_len_large(inbuf); - if (CVAL(inbuf,smb_com) != SMBwriteX || - CVAL(inbuf,smb_vwv0) != 0xFF || + if (CVAL(inbuf,smb_com) != SMBwriteX) { + return false; + } + + if (CVAL(inbuf,smb_vwv0) != 0xFF || CVAL(inbuf,smb_wct) != 14) { + DEBUG(10,("is_valid_writeX_buffer: chained or " + "invalid word length.\n")); return false; } + conn = conn_find(SVAL(inbuf, smb_tid)); if (conn == NULL) { + DEBUG(10,("is_valid_writeX_buffer: bad tid\n")); return false; } if (IS_IPC(conn)) { + DEBUG(10,("is_valid_writeX_buffer: IPC$ tid\n")); return false; } doff = SVAL(inbuf,smb_vwv11); @@ -3877,12 +3885,16 @@ bool is_valid_writeX_buffer(const char *inbuf) } if (numtowrite == 0) { + DEBUG(10,("is_valid_writeX_buffer: zero write\n")); return false; } /* Ensure the sizes match up. */ if (doff < STANDARD_WRITE_AND_X_HEADER_SIZE) { /* no pad byte...old smbclient :-( */ + DEBUG(10,("is_valid_writeX_buffer: small doff %u (min %u)\n", + (unsigned int)doff, + (unsigned int)STANDARD_WRITE_AND_X_HEADER_SIZE)); return false; } @@ -3939,6 +3951,12 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req) } if (req->unread_bytes) { + /* Can't do a recvfile write on IPC$ */ + if (IS_IPC(conn)) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + END_PROFILE(SMBwriteX); + return; + } if (numtowrite != req->unread_bytes) { reply_doserror(req, ERRDOS, ERRbadmem); END_PROFILE(SMBwriteX); -- cgit