From 12de4034c72ea5054d716bf848c2b16bef7a4d89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 Aug 1998 01:49:34 +0000 Subject: Makefile.in: Moved blocking lock code into smbd/blocking.c for link purposes. include/includes.h: Added nterr.h. locking/locking.c: Moved blocking lock code into smbd/blocking.c for link purposes. smbd/close.c: Added blocking lock removal to file close. smbd/filename.c: Tidied up unix_convert() so I could read it (:-) in preparation for the stat_cache code. smbd/nttrans.c: Added WRITE_ATTRIBUTES check. smbd/reply.c: Fixed multibyte char problem in wildcard mask. Jeremy. (This used to be commit 148eaba3dadb1d0bd3ac3ef53da3d9811636e89a) --- source3/locking/locking.c | 290 ---------------------------------------------- 1 file changed, 290 deletions(-) (limited to 'source3/locking') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 873e382b46..f5e27317b5 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -33,299 +33,9 @@ #include "includes.h" extern int DEBUGLEVEL; -extern int Client; static struct share_ops *share_ops; -#if 0 /* JRATEST - blocking lock code - under development. */ - -/**************************************************************************** - This is the structure to queue to implement blocking locks. - notify. It consists of the requesting SMB and the expiry time. -*****************************************************************************/ - -typedef struct { - ubi_slNode msg_next; - time_t expire_time; - int lock_num; - char *inbuf; - int length; -} blocking_lock_record; - -static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0}; - -/**************************************************************************** - Function to push a blocking lockingX request onto the lock queue. -****************************************************************************/ - -BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num) -{ - blocking_lock_record *blr; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - - /* - * Now queue an entry on the blocking lock queue. We setup - * the expiration time here. - */ - - if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); - return False; - } - - if((blr->inbuf = (char *)malloc(length)) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - free((char *)blr); - return False; - } - - memcpy(blr->inbuf, inbuf, length); - blr->length = length; - blr->lock_num = lock_num; - blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout; - - ubi_slAddTail(&blocking_lock_queue, blr); - - DEBUG(3,("push_blocking_lock_request: lock request blocked with expiry time %d \ -for fnum = %d, name = %s\n", blr->expire_time, fsp->fnum, fsp->name )); - - return True; -} - -/**************************************************************************** - Return a blocking lock success SMB. -*****************************************************************************/ -static void blocking_lock_reply_success(blocking_lock_record *blr) -{ - extern int chain_size; - extern char *OutBuffer; - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - int outsize = 0; - - construct_reply_common(inbuf, outbuf); - set_message(outbuf,2,0,True); - - /* - * As this message is a lockingX call we must handle - * any following chained message correctly. - * This is normally handled in construct_reply(), - * but as that calls switch_message, we can't use - * that here and must set up the chain info manually. - */ - - chain_size = 0; - - outsize = chain_reply(inbuf,outbuf,blr->length,bufsize); - - outsize += chain_size; - - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); - - send_smb(Client,outbuf); -} - -/**************************************************************************** - Return a lock fail error. Undo all the locks we have obtained first. -*****************************************************************************/ - -static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode) -{ - extern char *OutBuffer; - char *outbuf = OutBuffer; - int bufsize = BUFFER_SIZE; - char *inbuf = blr->inbuf; - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - uint32 count, offset; - int lock_num = blr->lock_num; - char *data; - int i; - - data = smb_buf(inbuf) + 10*num_ulocks; - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(i = blr->lock_num; i >= 0; i--) { - count = IVAL(data,SMB_LKLEN_OFFSET(i)); - offset = IVAL(data,SMB_LKOFF_OFFSET(i)); - do_unlock(fsp,conn,count,offset,&dummy1,&dummy2); - } - - construct_reply_common(inbuf, outbuf); - ERROR(eclass,ecode); - send_smb(Client,outbuf); -} - -/**************************************************************************** - Attempt to finish off getting all pending blocking locks. - Returns True if we want to be removed from the list. -*****************************************************************************/ - -static BOOL blocking_lock_record_process(blocking_lock_record *blr) -{ - char *inbuf = blr->inbuf; - unsigned char locktype = CVAL(inbuf,smb_vwv3); - files_struct *fsp = file_fsp(inbuf,smb_vwv2); - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); - uint32 count, offset; - int lock_num = blr->lock_num; - char *data; - int eclass=0; - uint32 ecode=0; - - data = smb_buf(inbuf) + 10*num_ulocks; - - /* - * Data now points at the beginning of the list - * of smb_lkrng structs. - */ - - for(; blr->lock_num < num_locks; blr->lock_num++) { - count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num)); - offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num)); - if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK), - &eclass, &ecode)) - break; - } - - if(blr->lock_num == num_locks) { - - /* - * Success - we got all the locks. - */ - - DEBUG(3,("blocking_lock_record_process fnum=%d type=%d num_locks=%d\n", - fsp->fnum, (unsigned int)locktype, num_locks) ); - - blocking_lock_reply_success(blr); - return True; - - } else if((errno != EACCES) && (errno != EAGAIN)) { - - /* - * We have other than a "can't get lock" POSIX - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ - - blocking_lock_reply_error(blr, eclass, ecode); - return True; - } - - /* - * Still can't get all the locks - keep waiting. - */ - - DEBUG(10,("blocking_lock_record_process: only got %d locks of %d needed for fnum = %d. \ -Waiting....\n", blr->lock_num, num_locks, fsp->fnum)); - - return False; -} - -/**************************************************************************** - Process the blocking lock queue. Note that this is only called as root. -*****************************************************************************/ - -void process_blocking_lock_queue(time_t t) -{ - blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue ); - blocking_lock_record *prev = NULL; - - if(blr == NULL) - return; - - /* - * Go through the queue and see if we can get any of the locks. - */ - - while(blr != NULL) { - files_struct *fsp = NULL; - uint16 vuid; - - /* - * Ensure we don't have any old chain_fnum values - * sitting around.... - */ - file_chain_reset(); - - fsp = file_fsp(blr->inbuf,smb_vwv2); - vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : - SVAL(blr->inbuf,smb_uid); - - DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fsp->fnum, fsp->name )); - - if((blr->expire_time != -1) && (blr->expire_time > t)) { - /* - * Lock expired - throw away all previously - * obtained locks and return lock error. - */ - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->name )); - - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - continue; - } - - if(!become_user(conn,vuid)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - continue; - } - - if(!become_service(conn,True)) { - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - /* - * Remove the entry and return an error to the client. - */ - blocking_lock_reply_error(blr,ERRSRV,ERRaccess); - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - unbecome_user(); - continue; - } - - /* - * Go through the remaining locks and try and obtain them. - * The call returns True if all locks were obtained successfully - * and False if we still need to wait. - */ - - if(blocking_lock_record_process(blr)) { - free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); - blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue)); - unbecome_user(); - continue; - } - - unbecome_user(); - - /* - * Move to the next in the list. - */ - prev = blr; - blr = (blocking_lock_record *)ubi_slNext(blr); - } -} -#endif /* JRATEST */ - /**************************************************************************** Utility function to map a lock type correctly depending on the real open mode of a file. -- cgit