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 smbpid;
|
||||||
uint16 mid;
|
uint16 mid;
|
||||||
uint16 vuid;
|
uint16 vuid;
|
||||||
|
uint16 tid;
|
||||||
|
uint8 wct;
|
||||||
|
const uint8 *inbuf;
|
||||||
|
uint8 *outbuf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Defines for the sent_oplock_break field above. */
|
/* 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_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 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 */
|
/* this is how errors are generated */
|
||||||
#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
|
#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;
|
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().
|
Wrapper for receive_smb_raw().
|
||||||
Checks the MAC on signed packets.
|
Checks the MAC on signed packets.
|
||||||
@ -765,6 +844,43 @@ BOOL receive_smb(int fd, char *buffer, unsigned int timeout)
|
|||||||
return True;
|
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.
|
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.
|
* 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;
|
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);
|
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
|
||||||
return outsize;
|
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));
|
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));
|
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;
|
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));
|
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);
|
END_PROFILE(SMBntcreateX);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
|
|||||||
SSVAL(outbuf,smb_vwv8,rmode);
|
SSVAL(outbuf,smb_vwv8,rmode);
|
||||||
SSVAL(outbuf,smb_vwv11,0x0001);
|
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));
|
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. */
|
/* Ensure we set up the message length to include the data length read. */
|
||||||
set_message_bcc(inbuf,outbuf,nread);
|
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_type = CVAL(inbuf,0);
|
||||||
int msg_flags = CVAL(inbuf,1);
|
int msg_flags = CVAL(inbuf,1);
|
||||||
fstring name1,name2;
|
fstring name1,name2;
|
||||||
char name_type = 0;
|
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;
|
static BOOL already_got_session = False;
|
||||||
|
|
||||||
*name1 = *name2 = 0;
|
*name1 = *name2 = 0;
|
||||||
|
|
||||||
memset(outbuf,'\0',smb_size);
|
memset(outbuf, '\0', sizeof(outbuf));
|
||||||
|
|
||||||
smb_setlen(inbuf,outbuf,0);
|
smb_setlen(inbuf,outbuf,0);
|
||||||
|
|
||||||
@ -315,7 +321,7 @@ int reply_special(char *inbuf,char *outbuf)
|
|||||||
if (name_len(inbuf+4) > 50 ||
|
if (name_len(inbuf+4) > 50 ||
|
||||||
name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
|
name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
|
||||||
DEBUG(0,("Invalid name length in session request\n"));
|
DEBUG(0,("Invalid name length in session request\n"));
|
||||||
return(0);
|
return;
|
||||||
}
|
}
|
||||||
name_extract(inbuf,4,name1);
|
name_extract(inbuf,4,name1);
|
||||||
name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
|
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 */
|
case SMBkeepalive: /* session keepalive */
|
||||||
default:
|
default:
|
||||||
return(0);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
|
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
|
||||||
msg_type, msg_flags));
|
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);
|
TALLOC_FREE(ctx);
|
||||||
END_PROFILE(SMBtconX);
|
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));
|
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.
|
Reply to an ioctl.
|
||||||
conn POINTER CAN BE NULL HERE !
|
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);
|
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 ) );
|
DEBUG( 3, ( "ulogoffX vuid=%d\n", vuid ) );
|
||||||
|
|
||||||
END_PROFILE(SMBulogoffX);
|
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);
|
nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
|
||||||
/* Only call chain_reply if not an error. */
|
/* Only call chain_reply if not an error. */
|
||||||
if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) {
|
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);
|
END_PROFILE(SMBreadX);
|
||||||
@ -3254,7 +3269,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
|
|||||||
}
|
}
|
||||||
|
|
||||||
END_PROFILE(SMBwriteX);
|
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));
|
fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
|
||||||
|
|
||||||
END_PROFILE(SMBlockingX);
|
END_PROFILE(SMBlockingX);
|
||||||
return chain_reply(inbuf,outbuf,length,bufsize);
|
return chain_reply(inbuf,&outbuf,length,bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef DBGC_CLASS
|
#undef DBGC_CLASS
|
||||||
|
@ -1582,5 +1582,5 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
|
|||||||
done_sesssetup = True;
|
done_sesssetup = True;
|
||||||
|
|
||||||
END_PROFILE(SMBsesssetupX);
|
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