mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
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)
This commit is contained in:
parent
041204d1a4
commit
cc6a41017c
@ -686,6 +686,10 @@ struct smb_request {
|
||||
uint16 smbpid;
|
||||
uint16 mid;
|
||||
uint16 vuid;
|
||||
uint16 tid;
|
||||
uint8 wct;
|
||||
const uint8 *inbuf;
|
||||
uint8 *outbuf;
|
||||
};
|
||||
|
||||
/* Defines for the sent_oplock_break field above. */
|
||||
|
@ -169,6 +169,10 @@
|
||||
#define ERROR_FORCE_NT(status) error_packet(inbuf,outbuf,-1,-1,status,__LINE__,__FILE__)
|
||||
#define ERROR_BOTH(status,class,code) error_packet(inbuf,outbuf,class,code,status,__LINE__,__FILE__)
|
||||
|
||||
#define reply_nterror(req,status) reply_nt_error(req,status,__LINE__,__FILE__)
|
||||
#define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__)
|
||||
#define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__)
|
||||
|
||||
/* this is how errors are generated */
|
||||
#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
|
||||
|
||||
|
@ -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.
|
||||
****************************************************************************/
|
||||
|
@ -286,7 +286,7 @@ static void reply_lockingX_success(blocking_lock_record *blr)
|
||||
* that here and must set up the chain info manually.
|
||||
*/
|
||||
|
||||
outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
|
||||
outsize = chain_reply(inbuf,&outbuf,blr->length,bufsize);
|
||||
|
||||
outsize += chain_size;
|
||||
|
||||
|
@ -131,3 +131,29 @@ int error_packet(const char *inbuf, char *outbuf, uint8 eclass, uint32 ecode, NT
|
||||
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
|
||||
return outsize;
|
||||
}
|
||||
|
||||
void reply_nt_error(struct smb_request *req, NTSTATUS ntstatus,
|
||||
int line, const char *file)
|
||||
{
|
||||
TALLOC_FREE(req->outbuf);
|
||||
reply_outbuf(req, 0, 0);
|
||||
error_packet_set((char *)req->outbuf, 0, 0, ntstatus, line, file);
|
||||
}
|
||||
|
||||
void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode,
|
||||
int line, const char *file)
|
||||
{
|
||||
TALLOC_FREE(req->outbuf);
|
||||
reply_outbuf(req, 0, 0);
|
||||
error_packet_set((char *)req->outbuf, eclass, ecode, NT_STATUS_OK, line,
|
||||
file);
|
||||
}
|
||||
|
||||
void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode,
|
||||
NTSTATUS status, int line, const char *file)
|
||||
{
|
||||
TALLOC_FREE(req->outbuf);
|
||||
reply_outbuf(req, 0, 0);
|
||||
error_packet_set((char *)req->outbuf, eclass, ecode, status,
|
||||
line, file);
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
|
||||
|
||||
DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
|
||||
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -471,7 +471,7 @@ int reply_ntcreate_and_X_quota(connection_struct *conn,
|
||||
|
||||
DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
|
||||
|
||||
result = chain_reply(inbuf,outbuf,length,bufsize);
|
||||
result = chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -987,7 +987,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
||||
|
||||
DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
|
||||
|
||||
result = chain_reply(inbuf,outbuf,length,bufsize);
|
||||
result = chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return result;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
||||
SSVAL(outbuf,smb_vwv8,rmode);
|
||||
SSVAL(outbuf,smb_vwv11,0x0001);
|
||||
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -231,7 +231,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
|
||||
DEBUG(3,("writeX-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten));
|
||||
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -278,7 +278,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
|
||||
/* Ensure we set up the message length to include the data length read. */
|
||||
set_message_bcc(inbuf,outbuf,nread);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -284,22 +284,28 @@ size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Reply to a special message.
|
||||
Reply to a (netbios-level) special message.
|
||||
****************************************************************************/
|
||||
|
||||
int reply_special(char *inbuf,char *outbuf)
|
||||
void reply_special(char *inbuf)
|
||||
{
|
||||
int outsize = 4;
|
||||
int msg_type = CVAL(inbuf,0);
|
||||
int msg_flags = CVAL(inbuf,1);
|
||||
fstring name1,name2;
|
||||
char name_type = 0;
|
||||
|
||||
/*
|
||||
* We only really use 4 bytes of the outbuf, but for the smb_setlen
|
||||
* calculation & friends (send_smb uses that) we need the full smb
|
||||
* header.
|
||||
*/
|
||||
char outbuf[smb_size];
|
||||
|
||||
static BOOL already_got_session = False;
|
||||
|
||||
*name1 = *name2 = 0;
|
||||
|
||||
memset(outbuf,'\0',smb_size);
|
||||
memset(outbuf, '\0', sizeof(outbuf));
|
||||
|
||||
smb_setlen(inbuf,outbuf,0);
|
||||
|
||||
@ -315,7 +321,7 @@ int reply_special(char *inbuf,char *outbuf)
|
||||
if (name_len(inbuf+4) > 50 ||
|
||||
name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
|
||||
DEBUG(0,("Invalid name length in session request\n"));
|
||||
return(0);
|
||||
return;
|
||||
}
|
||||
name_extract(inbuf,4,name1);
|
||||
name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
|
||||
@ -363,13 +369,14 @@ int reply_special(char *inbuf,char *outbuf)
|
||||
|
||||
case SMBkeepalive: /* session keepalive */
|
||||
default:
|
||||
return(0);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
|
||||
msg_type, msg_flags));
|
||||
|
||||
return(outsize);
|
||||
|
||||
send_smb(smbd_server_fd(), outbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -613,7 +620,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
|
||||
TALLOC_FREE(ctx);
|
||||
END_PROFILE(SMBtconX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -631,6 +638,14 @@ int reply_unknown(char *inbuf,char *outbuf)
|
||||
return(ERROR_DOS(ERRSRV,ERRunknownsmb));
|
||||
}
|
||||
|
||||
void reply_unknown_new(struct smb_request *req, uint8 type)
|
||||
{
|
||||
DEBUG(0, ("unknown command type (%s): type=%d (0x%X)\n",
|
||||
smb_fn_name(type), type, type));
|
||||
reply_doserror(req, ERRSRV, ERRunknownsmb);
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Reply to an ioctl.
|
||||
conn POINTER CAN BE NULL HERE !
|
||||
@ -1582,7 +1597,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
}
|
||||
|
||||
END_PROFILE(SMBopenX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1611,7 +1626,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
|
||||
DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
|
||||
|
||||
END_PROFILE(SMBulogoffX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -2813,7 +2828,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
|
||||
/* Only call chain_reply if not an error. */
|
||||
if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) {
|
||||
nread = chain_reply(inbuf,outbuf,length,bufsize);
|
||||
nread = chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
END_PROFILE(SMBreadX);
|
||||
@ -3254,7 +3269,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
|
||||
}
|
||||
|
||||
END_PROFILE(SMBwriteX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -5722,7 +5737,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
|
||||
fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
|
||||
|
||||
END_PROFILE(SMBlockingX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
||||
#undef DBGC_CLASS
|
||||
|
@ -1582,5 +1582,5 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
|
||||
done_sesssetup = True;
|
||||
|
||||
END_PROFILE(SMBsesssetupX);
|
||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
||||
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user