1
0
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:
Volker Lendecke 2007-07-23 09:36:09 +00:00 committed by Gerald (Jerry) Carter
parent 041204d1a4
commit cc6a41017c
10 changed files with 785 additions and 398 deletions

View File

@ -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. */

View File

@ -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__)

View 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.
****************************************************************************/

View File

@ -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;

View File

@ -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);
}

View 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;
}

View File

@ -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

View File

@ -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

View File

@ -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);
}