diff options
author | Jeremy Allison <jra@samba.org> | 1998-08-19 01:49:34 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-08-19 01:49:34 +0000 |
commit | 12de4034c72ea5054d716bf848c2b16bef7a4d89 (patch) | |
tree | 55a877cb872f4c2584905f02ba2f42d3bbddb9b1 /source3/smbd | |
parent | 1e6837837ac402702ccadcbcfd853b8c673c783a (diff) | |
download | samba-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.c | 6 | ||||
-rw-r--r-- | source3/smbd/filename.c | 254 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 5 | ||||
-rw-r--r-- | source3/smbd/reply.c | 28 |
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 |