summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-08-19 01:49:34 +0000
committerJeremy Allison <jra@samba.org>1998-08-19 01:49:34 +0000
commit148eaba3dadb1d0bd3ac3ef53da3d9811636e89a (patch)
treee80e82d7f295219bee894bede47cf9d79eadb3b5
parent2ca4fc95a4227645f1009a057d46b58508846a92 (diff)
downloadsamba-148eaba3dadb1d0bd3ac3ef53da3d9811636e89a.tar.gz
samba-148eaba3dadb1d0bd3ac3ef53da3d9811636e89a.tar.xz
samba-148eaba3dadb1d0bd3ac3ef53da3d9811636e89a.zip
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.
-rw-r--r--source/Makefile.in2
-rw-r--r--source/include/includes.h2
-rw-r--r--source/include/proto.h9
-rw-r--r--source/locking/locking.c290
-rw-r--r--source/smbd/close.c6
-rw-r--r--source/smbd/filename.c254
-rw-r--r--source/smbd/nttrans.c5
-rw-r--r--source/smbd/reply.c28
8 files changed, 186 insertions, 410 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index dfb2d0e80b5..b9fd30d9ba5 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -126,7 +126,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/groupname.o smbd/ipc.o smbd/mangle.o smbd/negprot.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
smbd/quotas.o smbd/reply.o smbd/ssl.o smbd/trans2.o smbd/uid.o \
- smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
+ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
diff --git a/source/include/includes.h b/source/include/includes.h
index 3fd5f7be087..a2419bc42c1 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -329,6 +329,8 @@ extern int errno;
#include "kanji.h"
#include "charset.h"
+#include "nterr.h"
+
#ifndef MAXCODEPAGELINES
#define MAXCODEPAGELINES 256
#endif
diff --git a/source/include/proto.h b/source/include/proto.h
index 07e3b70dbac..9b7267658d3 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -480,8 +480,6 @@ char *smb_errstr(char *inbuf);
/*The following definitions come from locking/locking.c */
-BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
-void process_blocking_lock_queue(time_t t);
BOOL is_locked(files_struct *fsp,connection_struct *conn,
uint32 count,uint32 offset, int lock_type);
BOOL do_lock(files_struct *fsp,connection_struct *conn,
@@ -1899,6 +1897,13 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid);
BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
+/*The following definitions come from smbd/blocking.c */
+
+BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
+void remove_pending_lock_requests_by_fid(files_struct *fsp);
+void remove_pending_lock_requests_by_mid(int mid);
+void process_blocking_lock_queue(time_t t);
+
/*The following definitions come from smbd/chgpasswd.c */
BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root);
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 873e382b469..f5e27317b5c 100644
--- a/source/locking/locking.c
+++ b/source/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.
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 9bc0a89338f..b8063ca3f42 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -142,6 +142,8 @@ void close_file(files_struct *fsp, BOOL normal_close)
string_free(&fsp->fsp_name);
}
+ remove_pending_lock_requests_by_fid(fsp);
+
file_free(fsp);
}
@@ -151,10 +153,6 @@ void close_file(files_struct *fsp, BOOL normal_close)
void close_directory(files_struct *fsp)
{
- /* TODO - walk the list of pending
- change notify requests and free
- any pertaining to this fsp. */
-
remove_pending_change_notify_requests_by_fid(fsp);
/*
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index a6a9e7e7f01..ab5851fb5e4 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -102,6 +102,7 @@ used to pick the correct error code to return between ENOENT and ENOTDIR
as Windows applications depend on ERRbadpath being returned if a component
of a pathname does not exist.
****************************************************************************/
+
BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component, BOOL *bad_path)
{
struct stat st;
@@ -115,17 +116,24 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
if(saved_last_component)
*saved_last_component = 0;
- /* convert to basic unix format - removing \ chars and cleaning it up */
+ /*
+ * Convert to basic unix format - removing \ chars and cleaning it up.
+ */
+
unix_format(name);
unix_clean_name(name);
- /* names must be relative to the root of the service - trim any leading /.
- also trim trailing /'s */
+ /*
+ * Names must be relative to the root of the service - trim any leading /.
+ * also trim trailing /'s.
+ */
+
trim_string(name,"/","/");
/*
* Ensure saved_last_component is valid even if file exists.
*/
+
if(saved_last_component) {
end = strrchr(name, '/');
if(end)
@@ -138,23 +146,30 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
(!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
strnorm(name);
- /* check if it's a printer file */
- if (conn->printer)
- {
- if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
- {
- char *s;
- fstring name2;
- slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
- /* sanitise the name */
- for (s=name2 ; *s ; s++)
- if (!issafe(*s)) *s = '_';
- pstrcpy(name,(char *)mktemp(name2));
- }
- return(True);
- }
+ /*
+ * Check if it's a printer file.
+ */
+ if (conn->printer) {
+ if ((! *name) || strchr(name,'/') || !is_8_3(name, True)) {
+ char *s;
+ fstring name2;
+ slprintf(name2,sizeof(name2)-1,"%.6s.XXXXXX",remote_machine);
+
+ /*
+ * Sanitise the name.
+ */
+
+ for (s=name2 ; *s ; s++)
+ if (!issafe(*s)) *s = '_';
+ pstrcpy(name,(char *)mktemp(name2));
+ }
+ return(True);
+ }
+
+ /*
+ * stat the name - if it exists then we are all done!
+ */
- /* stat the name - if it exists then we are all done! */
if (sys_stat(name,&st) == 0)
return(True);
@@ -162,109 +177,144 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
DEBUG(5,("unix_convert(%s)\n",name));
- /* a special case - if we don't have any mangling chars and are case
- sensitive then searching won't help */
+ /*
+ * A special case - if we don't have any mangling chars and are case
+ * sensitive then searching won't help.
+ */
+
if (case_sensitive && !is_mangled(name) &&
!lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
return(False);
- /* now we need to recursively match the name against the real
- directory structure */
+ /*
+ * Now we need to recursively match the name against the real
+ * directory structure.
+ */
start = name;
while (strncmp(start,"./",2) == 0)
start += 2;
- /* now match each part of the path name separately, trying the names
- as is first, then trying to scan the directory for matching names */
- for (;start;start = (end?end+1:(char *)NULL))
- {
- /* pinpoint the end of this section of the filename */
+ /*
+ * Match each part of the path name separately, trying the names
+ * as is first, then trying to scan the directory for matching names.
+ */
+
+ for (;start;start = (end?end+1:(char *)NULL)) {
+ /*
+ * Pinpoint the end of this section of the filename.
+ */
end = strchr(start, '/');
- /* chop the name at this point */
- if (end) *end = 0;
+ /*
+ * Chop the name at this point.
+ */
+ if (end)
+ *end = 0;
if(saved_last_component != 0)
pstrcpy(saved_last_component, end ? end + 1 : start);
- /* check if the name exists up to this point */
- if (sys_stat(name, &st) == 0)
- {
- /* it exists. it must either be a directory or this must be
- the last part of the path for it to be OK */
- if (end && !(st.st_mode & S_IFDIR))
- {
- /* an intermediate part of the name isn't a directory */
- DEBUG(5,("Not a dir %s\n",start));
- *end = '/';
- return(False);
- }
- }
- else
- {
- pstring rest;
-
- *rest = 0;
-
- /* remember the rest of the pathname so it can be restored
- later */
- if (end) pstrcpy(rest,end+1);
-
- /* try to find this part of the path in the directory */
- if (strchr(start,'?') || strchr(start,'*') ||
- !scan_directory(dirpath, start, conn, end?True:False))
- {
- if (end)
- {
- /* an intermediate part of the name can't be found */
- DEBUG(5,("Intermediate not found %s\n",start));
- *end = '/';
- /* We need to return the fact that the intermediate
- name resolution failed. This is used to return an
- error of ERRbadpath rather than ERRbadfile. Some
- Windows applications depend on the difference between
- these two errors.
- */
- *bad_path = True;
- return(False);
- }
+ /*
+ * Check if the name exists up to this point.
+ */
+ if (sys_stat(name, &st) == 0) {
+ /*
+ * It exists. it must either be a directory or this must be
+ * the last part of the path for it to be OK.
+ */
+ if (end && !(st.st_mode & S_IFDIR)) {
+ /*
+ * An intermediate part of the name isn't a directory.
+ */
+ DEBUG(5,("Not a dir %s\n",start));
+ *end = '/';
+ return(False);
+ }
+ } else {
+ pstring rest;
+
+ *rest = 0;
+
+ /*
+ * Remember the rest of the pathname so it can be restored
+ * later.
+ */
+
+ if (end)
+ pstrcpy(rest,end+1);
+
+ /*
+ * Try to find this part of the path in the directory.
+ */
+ if (strchr(start,'?') || strchr(start,'*') ||
+ !scan_directory(dirpath, start, conn, end?True:False)) {
+ if (end) {
+ /*
+ * An intermediate part of the name can't be found.
+ */
+ DEBUG(5,("Intermediate not found %s\n",start));
+ *end = '/';
+
+ /*
+ * We need to return the fact that the intermediate
+ * name resolution failed. This is used to return an
+ * error of ERRbadpath rather than ERRbadfile. Some
+ * Windows applications depend on the difference between
+ * these two errors.
+ */
+ *bad_path = True;
+ return(False);
+ }
- /* just the last part of the name doesn't exist */
- /* we may need to strupper() or strlower() it in case
- this conversion is being used for file creation
- purposes */
- /* if the filename is of mixed case then don't normalise it */
- if (!case_preserve &&
- (!strhasupper(start) || !strhaslower(start)))
- strnorm(start);
-
- /* check on the mangled stack to see if we can recover the
- base of the filename */
- if (is_mangled(start))
- check_mangled_cache( start );
-
- DEBUG(5,("New file %s\n",start));
- return(True);
- }
-
- /* restore the rest of the string */
- if (end)
- {
- pstrcpy(start+strlen(start)+1,rest);
- end = start + strlen(start);
- }
- }
+ /*
+ * Just the last part of the name doesn't exist.
+ * We may need to strupper() or strlower() it in case
+ * this conversion is being used for file creation
+ * purposes. If the filename is of mixed case then
+ * don't normalise it.
+ */
+
+ if (!case_preserve && (!strhasupper(start) || !strhaslower(start)))
+ strnorm(start);
+
+ /*
+ * check on the mangled stack to see if we can recover the
+ * base of the filename.
+ */
+
+ if (is_mangled(start))
+ check_mangled_cache( start );
+
+ DEBUG(5,("New file %s\n",start));
+ return(True);
+ }
- /* add to the dirpath that we have resolved so far */
- if (*dirpath) pstrcat(dirpath,"/");
+ /*
+ * Restore the rest of the string.
+ */
+ if (end) {
+ pstrcpy(start+strlen(start)+1,rest);
+ end = start + strlen(start);
+ }
+ } /* end else */
+
+ /*
+ * Add to the dirpath that we have resolved so far.
+ */
+ if (*dirpath) pstrcat(dirpath,"/");
pstrcat(dirpath,start);
- /* restore the / that we wiped out earlier */
- if (end) *end = '/';
- }
+ /*
+ * Restore the / that we wiped out earlier.
+ */
+ if (end)
+ *end = '/';
+ }
- /* the name has been resolved */
+ /*
+ * The name has been resolved.
+ */
DEBUG(5,("conversion finished %s\n",name));
return(True);
}
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index b5ed42fbb3c..9a9fc51d36e 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -321,7 +321,7 @@ static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 fi
}
if (smb_open_mode == -1) {
- if(desired_access & DELETE_ACCESS)
+ if(desired_access & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES))
smb_open_mode = 2;
else if( desired_access & FILE_EXECUTE)
smb_open_mode = 0;
@@ -909,12 +909,11 @@ int reply_ntcancel(connection_struct *conn,
{
/*
* Go through and cancel any pending change notifies.
- * TODO: When we add blocking locks we will add cancel
- * for them here too.
*/
int mid = SVAL(inbuf,smb_mid);
remove_pending_change_notify_requests_by_mid(mid);
+ remove_pending_lock_requests_by_mid(mid);
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 6b91d9d152a..28fed8bc043 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1051,14 +1051,24 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
mask_convert(mask);
{
- for (p=mask; *p; p++)
+ int skip;
+ p = mask;
+ while(*p)
+ {
+ if((skip = skip_multibyte_char( *p )) != 0 )
{
- if (*p != '?' && *p != '*' && !isdoschar(*p))
- {
- DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
- *p = '?';
- }
+ p += skip;
}
+ else
+ {
+ if (*p != '?' && *p != '*' && !isdoschar(*p))
+ {
+ DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
+ *p = '?';
+ }
+ p++;
+ }
+ }
}
if (!strchr(mask,'.') && strlen(mask)>8)
@@ -3569,8 +3579,8 @@ dev = %x, inode = %x\n",
count = IVAL(data,SMB_LKLEN_OFFSET(i));
offset = IVAL(data,SMB_LKOFF_OFFSET(i));
if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
- &eclass, &ecode))
-#if 0 /* JRATEST - blocking lock code. */
+ &eclass, &ecode)) {
+#if 0 /* JRATEST */
if((ecode == ERRlock) && (lock_timeout != 0)) {
/*
* A blocking lock was requested. Package up
@@ -3579,8 +3589,10 @@ dev = %x, inode = %x\n",
*/
if(push_blocking_lock_request(inbuf, length, lock_timeout, i))
return -1;
+ }
#endif /* JRATEST */
break;
+ }
}
/* If any of the above locks failed, then we must unlock