From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: 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) --- source3/smbd/reply.c | 133 +++++++++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 56 deletions(-) (limited to 'source3/smbd/reply.c') 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); -- cgit