summaryrefslogtreecommitdiff
path: root/source3/smbd/reply.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-09-30 17:13:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:48 -0500
commit54abd2aa66069e6baf7769c496f46d9dba18db39 (patch)
tree9cf8e88168011797319ba9e9866749201b1eac1e /source3/smbd/reply.c
parent4a2cc231d22a82ed21771a72508f15d21ed63227 (diff)
downloadsamba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r--source3/smbd/reply.c133
1 files changed, 77 insertions, 56 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 5572f47e42..ba22a56cfb 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -30,7 +30,6 @@
extern enum protocol_types Protocol;
extern int max_send;
extern int max_recv;
-extern int global_oplock_break;
unsigned int smb_echo_count = 0;
extern uint32 global_client_caps;
@@ -1779,7 +1778,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
}
/* We need a better way to return NT status codes from open... */
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
fsp = open_file_ntcreate(conn, fname, pst,
DELETE_ACCESS,
@@ -1791,12 +1790,12 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
NULL);
if (!fsp) {
- NTSTATUS ret;
- if (get_saved_error_triple(NULL, NULL, &ret)) {
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ NTSTATUS ret = get_saved_ntstatus();
+ if (!NT_STATUS_IS_OK(ret)) {
+ set_saved_ntstatus(NT_STATUS_OK);
return ret;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
@@ -1860,7 +1859,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
don't do it here as we'll get it wrong. */
/* We need a better way to return NT status codes from open... */
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
fsp = open_file_ntcreate(conn, fname, &sbuf,
DELETE_ACCESS,
@@ -1872,12 +1871,12 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
NULL);
if (!fsp) {
- NTSTATUS ret;
- if (get_saved_error_triple(NULL, NULL, &ret)) {
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ NTSTATUS ret = get_saved_ntstatus();
+ if (!NT_STATUS_IS_OK(ret)) {
+ set_saved_ntstatus(NT_STATUS_OK);
return ret;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
@@ -2209,15 +2208,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
* return a zero length response here.
*/
- if(global_oplock_break) {
- _smb_setlen(header,0);
- if (write_data(smbd_server_fd(),header,4) != 4)
- fail_readraw();
- DEBUG(5,("readbraw - oplock break finished\n"));
- END_PROFILE(SMBreadbraw);
- return -1;
- }
-
fsp = file_fsp(inbuf,smb_vwv0);
if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
@@ -2298,8 +2288,8 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
nread = 0;
#endif
- DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
- (int)maxcount, (int)mincount, (int)nread ) );
+ DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
+ (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
@@ -3744,7 +3734,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if( is_ntfs_stream_name(directory)) {
DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
END_PROFILE(SMBmkdir);
- return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
+ return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
}
status = mkdir_internal(conn, directory,bad_path);
@@ -5084,7 +5074,8 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma
Reply to a lockingX request.
****************************************************************************/
-int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
+ int length, int bufsize)
{
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
unsigned char locktype = CVAL(inbuf,smb_vwv3);
@@ -5096,7 +5087,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
int32 lock_timeout = IVAL(inbuf,smb_vwv4);
int i;
char *data;
- BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+ BOOL large_file_format =
+ (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
BOOL err;
BOOL my_lock_ctx = False;
NTSTATUS status;
@@ -5125,19 +5117,25 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
/* Client can insist on breaking to none. */
BOOL break_to_none = (oplocklevel == 0);
-
- DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
- (unsigned int)oplocklevel, fsp->fnum ));
+ BOOL result;
+
+ DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
+ "for fnum = %d\n", (unsigned int)oplocklevel,
+ fsp->fnum ));
/*
- * Make sure we have granted an exclusive or batch oplock on this file.
+ * Make sure we have granted an exclusive or batch oplock on
+ * this file.
*/
- if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
- DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
-
- /* if this is a pure oplock break request then don't send a reply */
+ if (fsp->oplock_type == 0) {
+ DEBUG(0,("reply_lockingX: Error : oplock break from "
+ "client for fnum = %d (oplock=%d) and no "
+ "oplock granted on this file (%s).\n",
+ fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+
+ /* if this is a pure oplock break request then don't
+ * send a reply */
if (num_locks == 0 && num_ulocks == 0) {
END_PROFILE(SMBlockingX);
return -1;
@@ -5147,17 +5145,30 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
}
}
- if (remove_oplock(fsp, break_to_none) == False) {
- DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
- fsp->fsp_name ));
+ if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
+ (break_to_none)) {
+ result = remove_oplock(fsp);
+ } else {
+ result = downgrade_oplock(fsp);
}
- /* if this is a pure oplock break request then don't send a reply */
+ if (!result) {
+ DEBUG(0, ("reply_lockingX: error in removing "
+ "oplock on file %s\n", fsp->fsp_name));
+ /* Hmmm. Is this panic justified? */
+ smb_panic("internal tdb error");
+ }
+
+ reply_to_oplock_break_requests(fsp);
+
+ /* if this is a pure oplock break request then don't send a
+ * reply */
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
if(CVAL(inbuf,smb_vwv0) != 0xff)
- DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ DEBUG(0,("reply_lockingX: Error : pure oplock "
+ "break is a chained %d request !\n",
(unsigned int)CVAL(inbuf,smb_vwv0) ));
END_PROFILE(SMBlockingX);
return -1;
@@ -5186,8 +5197,9 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
- (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
+ DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
+ "pid %u, file %s\n", (double)offset, (double)count,
+ (unsigned int)lock_pid, fsp->fsp_name ));
status = do_unlock(fsp,conn,lock_pid,count,offset);
if (NT_STATUS_V(status)) {
@@ -5219,27 +5231,34 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
- (double)offset, (double)count, (unsigned int)lock_pid,
- fsp->fsp_name, (int)lock_timeout ));
+ DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
+ "%u, file %s timeout = %d\n", (double)offset,
+ (double)count, (unsigned int)lock_pid,
+ fsp->fsp_name, (int)lock_timeout ));
status = do_lock_spin(fsp,conn,lock_pid, count,offset,
- ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
+ ((locktype & 1) ? READ_LOCK:WRITE_LOCK),
+ &my_lock_ctx);
if (NT_STATUS_V(status)) {
/*
- * Interesting fact found by IFSTEST /t LockOverlappedTest...
- * Even if it's our own lock context, we need to wait here as
- * there may be an unlock on the way.
- * So I removed a "&& !my_lock_ctx" from the following
- * if statement. JRA.
+ * Interesting fact found by IFSTEST /t
+ * LockOverlappedTest... Even if it's our own lock
+ * context, we need to wait here as there may be an
+ * unlock on the way. So I removed a "&&
+ * !my_lock_ctx" from the following if statement. JRA.
*/
- if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ if ((lock_timeout != 0) &&
+ lp_blocking_locks(SNUM(conn)) &&
+ ERROR_WAS_LOCK_DENIED(status)) {
/*
* 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, lock_timeout, i, lock_pid, offset, count)) {
+ if(push_blocking_lock_request(inbuf, length,
+ lock_timeout, i,
+ lock_pid, offset,
+ count)) {
END_PROFILE(SMBlockingX);
return -1;
}
@@ -5259,10 +5278,12 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
for(i--; i >= 0; i--) {
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ offset = get_lock_offset( data, i, large_file_format,
+ &err);
/*
- * There is no error code marked "stupid client bug".... :-).
+ * There is no error code marked "stupid client
+ * bug".... :-).
*/
if(err) {
END_PROFILE(SMBlockingX);
@@ -5277,8 +5298,8 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
set_message(outbuf,2,0,True);
- DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
+ DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+ fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
END_PROFILE(SMBlockingX);
return chain_reply(inbuf,outbuf,length,bufsize);