diff options
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r-- | source3/smbd/reply.c | 547 |
1 files changed, 214 insertions, 333 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a881e135c0..c6a082d7d8 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -23,6 +23,7 @@ makes to handle specific protocols */ + #include "includes.h" /* look in server.c for some explanation of these variables */ @@ -39,8 +40,9 @@ unsigned int smb_echo_count = 0; extern BOOL global_encrypted_passwords_negotiated; + /**************************************************************************** - Reply to an special message. + reply to an special message ****************************************************************************/ int reply_special(char *inbuf,char *outbuf) @@ -111,7 +113,7 @@ int reply_special(char *inbuf,char *outbuf) reload_services(True); reopen_logs(); - claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD); + claim_connection(NULL,"",MAXSTATUS,True); already_got_session = True; break; @@ -139,6 +141,7 @@ int reply_special(char *inbuf,char *outbuf) return(outsize); } + /**************************************************************************** Reply to a tcon. ****************************************************************************/ @@ -304,10 +307,10 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return chain_reply(inbuf,outbuf,length,bufsize); } + /**************************************************************************** - Reply to an unknown type. + reply to an unknown type ****************************************************************************/ - int reply_unknown(char *inbuf,char *outbuf) { int type; @@ -319,10 +322,10 @@ int reply_unknown(char *inbuf,char *outbuf) return(ERROR_DOS(ERRSRV,ERRunknownsmb)); } + /**************************************************************************** - Reply to an ioctl. + reply to an ioctl ****************************************************************************/ - int reply_ioctl(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -336,7 +339,8 @@ int reply_ioctl(connection_struct *conn, DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code)); - switch (ioctl_code) { + switch (ioctl_code) + { case IOCTL_QUERY_JOB_INFO: replysize = 32; break; @@ -351,15 +355,16 @@ int reply_ioctl(connection_struct *conn, SSVAL(outbuf,smb_vwv6,52); /* Offset to data */ p = smb_buf(outbuf) + 1; /* Allow for alignment */ - switch (ioctl_code) { - case IOCTL_QUERY_JOB_INFO: - { - uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); - SSVAL(p,0,rap_jobid); /* Job number */ - srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII); - srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); - break; - } + switch (ioctl_code) + { + case IOCTL_QUERY_JOB_INFO: + { + uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); + SSVAL(p,0,rap_jobid); /* Job number */ + srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII); + srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); + break; + } } END_PROFILE(SMBioctl); @@ -367,56 +372,56 @@ int reply_ioctl(connection_struct *conn, } /**************************************************************************** - Reply to a chkpth. + reply to a chkpth ****************************************************************************/ - int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { - int outsize = 0; - int mode; - pstring name; - BOOL ok = False; - BOOL bad_path = False; - SMB_STRUCT_STAT sbuf; - START_PROFILE(SMBchkpth); + int outsize = 0; + int mode; + pstring name; + BOOL ok = False; + BOOL bad_path = False; + SMB_STRUCT_STAT sbuf; + START_PROFILE(SMBchkpth); - srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE); + srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE); - RESOLVE_DFSPATH(name, conn, inbuf, outbuf); + RESOLVE_DFSPATH(name, conn, inbuf, outbuf); - unix_convert(name,conn,0,&bad_path,&sbuf); + unix_convert(name,conn,0,&bad_path,&sbuf); - mode = SVAL(inbuf,smb_vwv0); + mode = SVAL(inbuf,smb_vwv0); - if (check_name(name,conn)) { - if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) - ok = S_ISDIR(sbuf.st_mode); - } + if (check_name(name,conn)) { + if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) + ok = S_ISDIR(sbuf.st_mode); + } - if (!ok) { - /* We special case this - as when a Windows machine - is parsing a path is steps through the components - one at a time - if a component fails it expects - ERRbadpath, not ERRbadfile. - */ - if(errno == ENOENT) - return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); + if (!ok) { + /* We special case this - as when a Windows machine + is parsing a path is steps through the components + one at a time - if a component fails it expects + ERRbadpath, not ERRbadfile. + */ + if(errno == ENOENT) { + return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND); + } - return(UNIXERROR(ERRDOS,ERRbadpath)); - } + return(UNIXERROR(ERRDOS,ERRbadpath)); + } - outsize = set_message(outbuf,0,0,True); + outsize = set_message(outbuf,0,0,True); - DEBUG(3,("chkpth %s mode=%d\n", name, mode)); + DEBUG(3,("chkpth %s mode=%d\n", name, mode)); - END_PROFILE(SMBchkpth); - return(outsize); + END_PROFILE(SMBchkpth); + return(outsize); } + /**************************************************************************** - Reply to a getatr. + reply to a getatr ****************************************************************************/ - int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -489,10 +494,10 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } + /**************************************************************************** - Reply to a setatr. + reply to a setatr ****************************************************************************/ - int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -538,10 +543,10 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } + /**************************************************************************** - Reply to a dskattr. + reply to a dskattr ****************************************************************************/ - int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -586,11 +591,11 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz return(outsize); } + /**************************************************************************** - Reply to a search. - Can be called from SMBsearch, SMBffirst or SMBfunique. + reply to a search + Can be called from SMBsearch, SMBffirst or SMBfunique. ****************************************************************************/ - int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring mask; @@ -668,16 +673,12 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size if (strlen(directory) == 0) pstrcpy(directory,"./"); memset((char *)status,'\0',21); - SCVAL(status,0,(dirtype & 0x1F)); + SCVAL(status,0,dirtype); } else { - int status_dirtype; memcpy(status,p,21); - status_dirtype = CVAL(status,0) & 0x1F; - if (status_dirtype != (dirtype & 0x1F)) - dirtype = status_dirtype; - + dirtype = CVAL(status,0) & 0x1F; conn->dirptr = dptr_fetch(status+12,&dptr_num); if (!conn->dirptr) goto SearchEmpty; @@ -795,10 +796,10 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } + /**************************************************************************** - Reply to a fclose (stop directory search). + reply to a fclose (stop directory search) ****************************************************************************/ - int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -837,8 +838,9 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size return(outsize); } + /**************************************************************************** - Reply to an open. + reply to an open ****************************************************************************/ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) @@ -908,10 +910,10 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } + /**************************************************************************** - Reply to an open and X. + reply to an open and X ****************************************************************************/ - int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { pstring fname; @@ -1017,10 +1019,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt return chain_reply(inbuf,outbuf,length,bufsize); } + /**************************************************************************** - Reply to a SMBulogoffX. + reply to a SMBulogoffX ****************************************************************************/ - int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { uint16 vuid = SVAL(inbuf,smb_uid); @@ -1047,10 +1049,10 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length, return chain_reply(inbuf,outbuf,length,bufsize); } + /**************************************************************************** - Reply to a mknew or a create. + reply to a mknew or a create ****************************************************************************/ - int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -1120,10 +1122,10 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } + /**************************************************************************** - Reply to a create temporary file. + reply to a create temporary file ****************************************************************************/ - int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { pstring fname; @@ -1432,59 +1434,6 @@ void fail_readraw(void) } /**************************************************************************** - Use sendfile in readbraw. -****************************************************************************/ - -void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread, - ssize_t mincount, char *outbuf) -{ - ssize_t ret=0; - -#if defined(WITH_SENDFILE) - /* - * We can only use sendfile on a non-chained packet and on a file - * that is exclusively oplocked. reply_readbraw has already checked the length. - */ - - if ((nread > 0) && (lp_write_cache_size(SNUM(conn)) == 0) && - EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_use_sendfile(SNUM(conn)) ) { - DATA_BLOB header; - - _smb_setlen(outbuf,nread); - header.data = outbuf; - header.length = 4; - header.free = NULL; - - if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) { - /* - * Special hack for broken Linux with no 64 bit clean sendfile. If we - * return ENOSYS then pretend we just got a normal read. - */ - if (errno == ENOSYS) - goto normal_read; - - DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); - exit_server("send_file_readbraw sendfile failed"); - } - - } - - normal_read: -#endif - - if (nread > 0) { - ret = read_file(fsp,outbuf+4,startpos,nread); - if (ret < mincount) - ret = 0; - } - - _smb_setlen(outbuf,ret); - if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret) - fail_readraw(); -} - -/**************************************************************************** Reply to a readbraw (core+ protocol). ****************************************************************************/ @@ -1494,6 +1443,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s size_t nread = 0; SMB_OFF_T startpos; char *header = outbuf; + ssize_t ret=0; files_struct *fsp; START_PROFILE(SMBreadbraw); @@ -1597,7 +1547,15 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos, (int)maxcount, (int)mincount, (int)nread ) ); - send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf); + if (nread > 0) { + ret = read_file(fsp,header+4,startpos,nread); + if (ret < mincount) + ret = 0; + } + + _smb_setlen(header,ret); + if (write_data(smbd_server_fd(),header,4+ret) != 4+ret) + fail_readraw(); DEBUG(5,("readbraw finished\n")); END_PROFILE(SMBreadbraw); @@ -1605,9 +1563,8 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s } /**************************************************************************** - Reply to a lockread (core+ protocol). + reply to a lockread (core+ protocol) ****************************************************************************/ - int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz) { ssize_t nread = -1; @@ -1642,16 +1599,15 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK); if (NT_STATUS_V(status)) { - if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { + if (lp_blocking_locks(SNUM(conn))) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it * onto the blocking lock queue. */ - if(push_blocking_lock_request(inbuf, length, -1, 0)) { + if(push_blocking_lock_request(inbuf, length, -1, 0)) END_PROFILE(SMBlockread); - return -1; - } + return -1; } END_PROFILE(SMBlockread); return ERROR_NT(status); @@ -1676,209 +1632,132 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length return(outsize); } + /**************************************************************************** - Reply to a read. + reply to a read ****************************************************************************/ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { - size_t numtoread; - ssize_t nread = 0; - char *data; - SMB_OFF_T startpos; - int outsize = 0; - files_struct *fsp = file_fsp(inbuf,smb_vwv0); - START_PROFILE(SMBread); - - CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + size_t numtoread; + ssize_t nread = 0; + char *data; + SMB_OFF_T startpos; + int outsize = 0; + files_struct *fsp = file_fsp(inbuf,smb_vwv0); + START_PROFILE(SMBread); - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL(inbuf,smb_vwv2); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); - outsize = set_message(outbuf,5,3,True); - numtoread = MIN(BUFFER_SIZE-outsize,numtoread); - data = smb_buf(outbuf) + 3; - - if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { - END_PROFILE(SMBread); - return ERROR_DOS(ERRDOS,ERRlock); - } + numtoread = SVAL(inbuf,smb_vwv1); + startpos = IVAL(inbuf,smb_vwv2); - if (numtoread > 0) - nread = read_file(fsp,data,startpos,numtoread); - if (nread < 0) { - END_PROFILE(SMBread); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - SCVAL(smb_buf(outbuf),0,1); - SSVAL(smb_buf(outbuf),1,nread); + outsize = set_message(outbuf,5,3,True); + numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + data = smb_buf(outbuf) + 3; - DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", - fsp->fnum, (int)numtoread, (int)nread ) ); - - END_PROFILE(SMBread); - return(outsize); -} - -/**************************************************************************** - Reply to a read and X - possibly using sendfile. -****************************************************************************/ - -int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, - files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt) -{ - ssize_t nread = -1; - char *data = smb_buf(outbuf); - -#if defined(WITH_SENDFILE) - /* - * We can only use sendfile on a non-chained packet and on a file - * that is exclusively oplocked. - */ - - if ((CVAL(inbuf,smb_vwv0) == 0xFF) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && - lp_use_sendfile(SNUM(conn)) && (lp_write_cache_size(SNUM(conn)) == 0) ) { - SMB_STRUCT_STAT sbuf; - DATA_BLOB header; - - if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) - return(UNIXERROR(ERRDOS,ERRnoaccess)); - - if (startpos > sbuf.st_size) - goto normal_read; - - if (smb_maxcnt > (sbuf.st_size - startpos)) - smb_maxcnt = (sbuf.st_size - startpos); - - if (smb_maxcnt == 0) - goto normal_read; - - /* - * Set up the packet header before send. We - * assume here the sendfile will work (get the - * correct amount of data). - */ - - SSVAL(outbuf,smb_vwv5,smb_maxcnt); - SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); - SSVAL(smb_buf(outbuf),-2,smb_maxcnt); - SCVAL(outbuf,smb_vwv0,0xFF); - set_message(outbuf,12,smb_maxcnt,False); - header.data = outbuf; - header.length = data - outbuf; - header.free = NULL; - - if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) { - /* - * Special hack for broken Linux with no 64 bit clean sendfile. If we - * return ENOSYS then pretend we just got a normal read. - */ - if (errno == ENOSYS) - goto normal_read; - - DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n", - fsp->fsp_name, strerror(errno) )); - exit_server("send_file_readX sendfile failed"); - } - - DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n", - fsp->fnum, (int)smb_maxcnt, (int)nread ) ); - return -1; - } - - normal_read: + if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { + END_PROFILE(SMBread); + return ERROR_DOS(ERRDOS,ERRlock); + } -#endif + if (numtoread > 0) + nread = read_file(fsp,data,startpos,numtoread); - nread = read_file(fsp,data,startpos,smb_maxcnt); + if (nread < 0) { + END_PROFILE(SMBread); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } - if (nread < 0) { - END_PROFILE(SMBreadX); - return(UNIXERROR(ERRDOS,ERRnoaccess)); - } - - SSVAL(outbuf,smb_vwv5,nread); - SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); - SSVAL(smb_buf(outbuf),-2,nread); + outsize += nread; + SSVAL(outbuf,smb_vwv0,nread); + SSVAL(outbuf,smb_vwv5,nread+3); + SCVAL(smb_buf(outbuf),0,1); + SSVAL(smb_buf(outbuf),1,nread); - DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n", - fsp->fnum, (int)smb_maxcnt, (int)nread ) ); + DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", + fsp->fnum, (int)numtoread, (int)nread ) ); - return nread; + END_PROFILE(SMBread); + return(outsize); } + /**************************************************************************** - Reply to a read and X. + reply to a read and X ****************************************************************************/ - int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3); - ssize_t nread = -1; - size_t smb_maxcnt = SVAL(inbuf,smb_vwv5); -#if 0 - size_t smb_mincnt = SVAL(inbuf,smb_vwv6); -#endif - - START_PROFILE(SMBreadX); + files_struct *fsp = file_fsp(inbuf,smb_vwv2); + SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3); + size_t smb_maxcnt = SVAL(inbuf,smb_vwv5); + size_t smb_mincnt = SVAL(inbuf,smb_vwv6); + ssize_t nread = -1; + char *data; + START_PROFILE(SMBreadX); - /* If it's an IPC, pass off the pipe handler. */ - if (IS_IPC(conn)) { - END_PROFILE(SMBreadX); - return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); - } + /* If it's an IPC, pass off the pipe handler. */ + if (IS_IPC(conn)) { + END_PROFILE(SMBreadX); + return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize); + } - CHECK_FSP(fsp,conn); - CHECK_READ(fsp); + CHECK_FSP(fsp,conn); + CHECK_READ(fsp); - set_message(outbuf,12,0,True); + set_message(outbuf,12,0,True); + data = smb_buf(outbuf); - if(CVAL(inbuf,smb_wct) == 12) { + if(CVAL(inbuf,smb_wct) == 12) { #ifdef LARGE_SMB_OFF_T - /* - * This is a large offset (64 bit) read. - */ - startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32); + /* + * This is a large offset (64 bit) read. + */ + startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32); #else /* !LARGE_SMB_OFF_T */ - /* - * Ensure we haven't been sent a >32 bit offset. - */ + /* + * Ensure we haven't been sent a >32 bit offset. + */ - if(IVAL(inbuf,smb_vwv10) != 0) { - DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ + if(IVAL(inbuf,smb_vwv10) != 0) { + DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \ 64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) )); - END_PROFILE(SMBreadX); - return ERROR_DOS(ERRDOS,ERRbadaccess); - } + END_PROFILE(SMBreadX); + return ERROR_DOS(ERRDOS,ERRbadaccess); + } #endif /* LARGE_SMB_OFF_T */ - } + } - if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { - END_PROFILE(SMBreadX); - return ERROR_DOS(ERRDOS,ERRlock); - } + if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) { + END_PROFILE(SMBreadX); + return ERROR_DOS(ERRDOS,ERRlock); + } + nread = read_file(fsp,data,startpos,smb_maxcnt); - nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt); - if (nread != -1) - nread = chain_reply(inbuf,outbuf,length,bufsize); + if (nread < 0) { + END_PROFILE(SMBreadX); + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + SSVAL(outbuf,smb_vwv5,nread); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,nread); + + DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n", + fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) ); - END_PROFILE(SMBreadX); - return nread; + END_PROFILE(SMBreadX); + return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** - Reply to a writebraw (core+ or LANMAN1.0 protocol). + reply to a writebraw (core+ or LANMAN1.0 protocol) ****************************************************************************/ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -2009,7 +1888,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, } /**************************************************************************** - Reply to a writeunlock (core+). + reply to a writeunlock (core+) ****************************************************************************/ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, @@ -2071,6 +1950,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, return outsize; } + /**************************************************************************** Reply to a write. ****************************************************************************/ @@ -2149,10 +2029,10 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d return(outsize); } + /**************************************************************************** - Reply to a write and X. + reply to a write and X ****************************************************************************/ - int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { files_struct *fsp = file_fsp(inbuf,smb_vwv2); @@ -2249,8 +2129,9 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng return chain_reply(inbuf,outbuf,length,bufsize); } + /**************************************************************************** - Reply to a lseek. + reply to a lseek ****************************************************************************/ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -2331,7 +2212,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int } /**************************************************************************** - Reply to a flush. + reply to a flush ****************************************************************************/ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) @@ -2353,10 +2234,10 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int return(outsize); } + /**************************************************************************** - Reply to a exit. + reply to a exit ****************************************************************************/ - int reply_exit(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2370,10 +2251,10 @@ int reply_exit(connection_struct *conn, return(outsize); } + /**************************************************************************** Reply to a close - has to deal with closing a directory opened by NT SMB's. ****************************************************************************/ - int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { @@ -2455,8 +2336,9 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size, return(outsize); } + /**************************************************************************** - Reply to a writeclose (Core+ protocol). + reply to a writeclose (Core+ protocol) ****************************************************************************/ int reply_writeclose(connection_struct *conn, @@ -2513,10 +2395,10 @@ int reply_writeclose(connection_struct *conn, return(outsize); } + /**************************************************************************** - Reply to a lock. + reply to a lock ****************************************************************************/ - int reply_lock(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsize) { @@ -2538,7 +2420,7 @@ int reply_lock(connection_struct *conn, status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK); if (NT_STATUS_V(status)) { - if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { + if (lp_blocking_locks(SNUM(conn))) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it @@ -2557,10 +2439,10 @@ int reply_lock(connection_struct *conn, return(outsize); } + /**************************************************************************** - Reply to a unlock. + reply to a unlock ****************************************************************************/ - int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) { @@ -2588,10 +2470,10 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, return(outsize); } + /**************************************************************************** - Reply to a tdis. + reply to a tdis ****************************************************************************/ - int reply_tdis(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2615,10 +2497,11 @@ int reply_tdis(connection_struct *conn, return outsize; } + + /**************************************************************************** - Reply to a echo. + reply to a echo ****************************************************************************/ - int reply_echo(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2656,10 +2539,10 @@ int reply_echo(connection_struct *conn, return -1; } + /**************************************************************************** - Reply to a printopen. + reply to a printopen ****************************************************************************/ - int reply_printopen(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2690,8 +2573,9 @@ int reply_printopen(connection_struct *conn, return(outsize); } + /**************************************************************************** - Reply to a printclose. + reply to a printclose ****************************************************************************/ int reply_printclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) @@ -2723,10 +2607,10 @@ int reply_printclose(connection_struct *conn, return(outsize); } + /**************************************************************************** - Reply to a printqueue. + reply to a printqueue ****************************************************************************/ - int reply_printqueue(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { @@ -2794,10 +2678,10 @@ int reply_printqueue(connection_struct *conn, return(outsize); } + /**************************************************************************** - Reply to a printwrite. + reply to a printwrite ****************************************************************************/ - int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int numtowrite; @@ -2828,11 +2712,11 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_ return(outsize); } + /**************************************************************************** The guts of the mkdir command, split out so it may be called by the NT SMB code. ****************************************************************************/ - NTSTATUS mkdir_internal(connection_struct *conn, pstring directory) { BOOL bad_path = False; @@ -3055,10 +2939,10 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, return(outsize); } + /******************************************************************* - Resolve wildcards in a filename rename. +resolve wildcards in a filename rename ********************************************************************/ - static BOOL resolve_wildcards(char *name1,char *name2) { fstring root1,root2; @@ -3494,9 +3378,8 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun, } /**************************************************************************** - Reply to a file copy. -****************************************************************************/ - + reply to a file copy. + ****************************************************************************/ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int outsize = 0; @@ -3659,9 +3542,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } /**************************************************************************** - Reply to a setdir. + reply to a setdir ****************************************************************************/ - int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) { int snum; @@ -3755,7 +3637,6 @@ SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format /**************************************************************************** Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-). ****************************************************************************/ - static uint32 map_lock_offset(uint32 high, uint32 low) { unsigned int i; @@ -3835,7 +3716,7 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma } /**************************************************************************** - Reply to a lockingX request. + reply to a lockingX request ****************************************************************************/ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) @@ -3946,7 +3827,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); /* Setup the timeout in seconds. */ - lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000); + lock_timeout = ((lock_timeout == -1) ? -1 : lock_timeout/1000); /* Now do any requested locks */ data += ((large_file_format ? 20 : 10)*num_ulocks); @@ -3974,7 +3855,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name)); status = do_lock_spin(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK)); if (NT_STATUS_V(status)) { - if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) { + if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) { /* * A blocking lock was requested. Package up * this smb into a queued request and push it |