diff options
author | Samba Release Account <samba-bugs@samba.org> | 1997-08-20 20:32:23 +0000 |
---|---|---|
committer | Samba Release Account <samba-bugs@samba.org> | 1997-08-20 20:32:23 +0000 |
commit | 46dbd8c06009ad9e64251ae844fb16f2a30f5ab7 (patch) | |
tree | b3665c4cdda6e60c2e85218f6778213817b4210f /source3/smbd/server.c | |
parent | c76dc7c2963d1205cf46849df6b6f0edbf63692d (diff) | |
download | samba-46dbd8c06009ad9e64251ae844fb16f2a30f5ab7.tar.gz samba-46dbd8c06009ad9e64251ae844fb16f2a30f5ab7.tar.bz2 samba-46dbd8c06009ad9e64251ae844fb16f2a30f5ab7.zip |
Changes to allow Samba to return the same error code as Windows NT.
Takes care of the cases where a Windows program is parsing a pathname
component by component and expects 2 different errors.
ERRbadpath - if a component in the path doesn't exist.
ERRbaddirectory - if a component in the path exists but is not a directory.
Extra error code added to smb.h to support this.
Code based on suggestions from "Christian Groessler" <chris@fast-ag.de>.
Jeremy (jallison@whistle.com)
(This used to be commit 28b3c6db8a81b41b448a4f3cd98e9cd2c4b5fb2e)
Diffstat (limited to 'source3/smbd/server.c')
-rw-r--r-- | source3/smbd/server.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 93d05ffab6..aaf62fdcad 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -426,14 +426,22 @@ If the saved_last_component != 0, then the unmodified last component of the pathname is returned there. This is used in an exceptional case in reply_mv (so far). If saved_last_component == 0 then nothing is returned there. + +The bad_path arg is set to True if the filename walk failed. This is +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,int cnum,pstring saved_last_component) +BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path) { struct stat st; char *start, *end; pstring dirpath; + int saved_errno; *dirpath = 0; + *bad_path = False; + if(saved_last_component) *saved_last_component = 0; @@ -480,12 +488,14 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component) if (sys_stat(name,&st) == 0) return(True); + saved_errno = errno; + DEBUG(5,("unix_convert(%s,%d)\n",name,cnum)); /* 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) + !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT)) return(False); /* now we need to recursively match the name against the real @@ -506,7 +516,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component) if (end) *end = 0; if(saved_last_component != 0) - strcpy(saved_last_component, end ? end + 1 : start); + strcpy(saved_last_component, end ? end + 1 : start); /* check if the name exists up to this point */ if (sys_stat(name, &st) == 0) @@ -540,6 +550,13 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component) /* 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); } @@ -1940,7 +1957,7 @@ struct {EPERM,ERRDOS,ERRnoaccess}, {EACCES,ERRDOS,ERRnoaccess}, {ENOENT,ERRDOS,ERRbadfile}, - {ENOTDIR,ERRDOS,ERRbadpath}, + {ENOTDIR,ERRDOS,ERRbaddirectory}, {EIO,ERRHRD,ERRgeneral}, {EBADF,ERRSRV,ERRsrverror}, {EINVAL,ERRSRV,ERRsrverror}, |