diff options
author | Andrew Tridgell <tridge@samba.org> | 2000-01-16 12:26:42 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2000-01-16 12:26:42 +0000 |
commit | 446f2aef8326f41a0f56c9f2d8229413a61f1d81 (patch) | |
tree | bcccb70abd4899990229c5dc687bf5afca240e61 /source3 | |
parent | 2513cd5f17f7d1d40cbf8afc816b8a3994712bef (diff) | |
download | samba-446f2aef8326f41a0f56c9f2d8229413a61f1d81.tar.gz samba-446f2aef8326f41a0f56c9f2d8229413a61f1d81.tar.bz2 samba-446f2aef8326f41a0f56c9f2d8229413a61f1d81.zip |
as obelix would say "these romans are crazy"
I've finally got the access table code right for the case where the
two opens are on the same connection. It is _incredibly_ complex, but
now all 1296 test cases pass.
I'll be very surprised if anyone by MS and us gets this right at
CIFS2000
(This used to be commit 31a5857ce4f03eb53ff8ea96c5f1ce335941336d)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/open.c | 99 |
1 files changed, 59 insertions, 40 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7558954ec6..d0a48ced4b 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -623,15 +623,49 @@ reproduce the share mode access table static int access_table(int new_deny,int old_deny,int old_mode, pid_t share_pid,char *fname) { - if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL); - - if (old_deny == DENY_DOS || new_deny == DENY_DOS || - old_deny == DENY_FCB || new_deny == DENY_FCB) { + pid_t pid = getpid(); + BOOL isexe = False; + if ((fname = strrchr(fname,'.'))) { if (strequal(fname,".com") || strequal(fname,".dll") || strequal(fname,".exe") || strequal(fname,".sym")) { + isexe = True; + } + } + + if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL); + + if (share_pid == pid) { + if (isexe && old_mode == O_RDONLY && + old_deny == DENY_DOS && new_deny == DENY_READ) { + return AFAIL; + } + if (!isexe && old_mode == O_RDONLY && + old_deny == DENY_DOS && new_deny == DENY_DOS) { + return AREAD; + } + if (new_deny == DENY_FCB && old_deny == DENY_DOS) { + if (isexe) return AFAIL; + if (old_mode == DOS_OPEN_RDONLY) return AFAIL; + return AALL; + } + if (old_mode == O_RDONLY && old_deny == DENY_DOS) { + if (new_deny == DENY_FCB || new_deny == DENY_READ) { + if (isexe) return AREAD; + return AFAIL; + } + } + if (old_deny == DENY_FCB) { + if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL; + return AFAIL; + } + } + + if (old_deny == DENY_DOS || new_deny == DENY_DOS || + old_deny == DENY_FCB || new_deny == DENY_FCB) { + if (isexe) { if (old_deny == DENY_FCB || new_deny == DENY_FCB) { return AFAIL; } @@ -652,10 +686,7 @@ static int access_table(int new_deny,int old_deny,int old_mode, if (old_deny == DENY_READ) return AWRITE; if (old_deny == DENY_WRITE) return AREAD; } - } - /* it isn't a exe, dll, sym or com file */ - { - pid_t pid = getpid(); + /* it isn't a exe, dll, sym or com file */ if (old_deny == new_deny && share_pid == pid) return(AALL); @@ -664,27 +695,26 @@ static int access_table(int new_deny,int old_deny,int old_mode, return(AFAIL); } - } - - switch (new_deny) - { - case DENY_WRITE: - if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD); - if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE); - if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL); - return(AFAIL); - case DENY_READ: - if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD); - if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE); - if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL); - return(AFAIL); - case DENY_NONE: - if (old_deny==DENY_WRITE) return(AREAD); - if (old_deny==DENY_READ) return(AWRITE); - if (old_deny==DENY_NONE) return(AALL); - return(AFAIL); - } - return(AFAIL); + + switch (new_deny) + { + case DENY_WRITE: + if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD); + if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE); + if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL); + return(AFAIL); + case DENY_READ: + if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD); + if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE); + if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL); + return(AFAIL); + case DENY_NONE: + if (old_deny==DENY_WRITE) return(AREAD); + if (old_deny==DENY_READ) return(AWRITE); + if (old_deny==DENY_NONE) return(AALL); + return(AFAIL); + } + return(AFAIL); } /**************************************************************************** @@ -712,17 +742,6 @@ static int check_share_mode( share_mode_entry *share, int deny_mode, return False; } - if (old_deny_mode > 4 || old_open_mode > 2) - { - DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n", - deny_mode,old_deny_mode,old_open_mode,fname)); - - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadshare; - - return False; - } - { int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode, share->pid,fname); |