summaryrefslogtreecommitdiff
path: root/source3/smbd/open.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-01-16 12:26:42 +0000
committerAndrew Tridgell <tridge@samba.org>2000-01-16 12:26:42 +0000
commit446f2aef8326f41a0f56c9f2d8229413a61f1d81 (patch)
treebcccb70abd4899990229c5dc687bf5afca240e61 /source3/smbd/open.c
parent2513cd5f17f7d1d40cbf8afc816b8a3994712bef (diff)
downloadsamba-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/smbd/open.c')
-rw-r--r--source3/smbd/open.c99
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);