summaryrefslogtreecommitdiff
path: root/source3/smbd
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
commit12de4034c72ea5054d716bf848c2b16bef7a4d89 (patch)
tree55a877cb872f4c2584905f02ba2f42d3bbddb9b1 /source3/smbd
parent1e6837837ac402702ccadcbcfd853b8c673c783a (diff)
downloadsamba-12de4034c72ea5054d716bf848c2b16bef7a4d89.tar.gz
samba-12de4034c72ea5054d716bf848c2b16bef7a4d89.tar.bz2
samba-12de4034c72ea5054d716bf848c2b16bef7a4d89.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. (This used to be commit 148eaba3dadb1d0bd3ac3ef53da3d9811636e89a)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c6
-rw-r--r--source3/smbd/filename.c254
-rw-r--r--source3/smbd/nttrans.c5
-rw-r--r--source3/smbd/reply.c28
4 files changed, 176 insertions, 117 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 9bc0a89338..b8063ca3f4 100644
--- a/source3/smbd/close.c
+++ b/source3/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/source3/smbd/filename.c b/source3/smbd/filename.c
index a6a9e7e7f0..ab5851fb5e 100644
--- a/source3/smbd/filename.c
+++ b/source3/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/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b5ed42fbb3..9a9fc51d36 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/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/source3/smbd/reply.c b/source3/smbd/reply.c
index 6b91d9d152..28fed8bc04 100644
--- a/source3/smbd/reply.c
+++ b/source3/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