From d76e724b1029f840c947859ba5354fa171a2b383 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Aug 2007 20:49:09 +0000 Subject: r24791: Fix logic error in timeout of blocking lock processing found by Ronnie. If a lock timeout expires, we must check we can get the lock before responding with failure. Volker is writing a torture test. Jeremy. (This used to be commit 45380f356b99d575645873b05af17c504b091dc8) --- source3/smbd/blocking.c | 51 ++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 86cf315930..3bf6e0f99a 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -702,18 +702,14 @@ static void process_blocking_lock_queue(void) DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", fsp->fnum, fsp->fsp_name )); - if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { + if(!change_to_user(conn,vuid)) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* - * Lock expired - throw away all previously - * obtained locks and return lock error. + * Remove the entry and return an error to the client. */ if (br_lck) { - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); - brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), @@ -723,14 +719,16 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", + vuid )); + blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; continue; } - if(!change_to_user(conn,vuid)) { + if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); /* @@ -747,21 +745,23 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); + DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; + change_to_root_user(); continue; } - if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* + * 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. + */ - /* - * Remove the entry and return an error to the client. - */ + if(blocking_lock_record_process(blr)) { + struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); if (br_lck) { brl_lock_cancel(br_lck, @@ -773,8 +773,6 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; @@ -782,16 +780,25 @@ static void process_blocking_lock_queue(void) continue; } + change_to_root_user(); + /* - * 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. + * We couldn't get the locks for this record on the list. + * If the time has expired, return a lock error. */ - if(blocking_lock_record_process(blr)) { + if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp); + /* + * Lock expired - throw away all previously + * obtained locks and return lock error. + */ + if (br_lck) { + DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", + fsp->fnum, fsp->fsp_name )); + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), @@ -801,11 +808,11 @@ static void process_blocking_lock_queue(void) TALLOC_FREE(br_lck); } + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); free_blocking_lock_record(blr); recalc_timeout = True; } - change_to_root_user(); } if (recalc_timeout) { -- cgit