From 290b05b6b6e13fd93d40a8c021f0d8fdf697f7af Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 5 Jan 2007 17:13:11 +0000 Subject: [PATCH] windows-unix-mode-bit-enforcement-20070105 modify the write-lock permission test so that the UnixMode bits do not subtract PRSFS_WRITE from the rights when testing PRSFS_WRITE | PRSFS_LOCK. PRSFS_WRITE implies PRSFS_LOCK so add it Add new registry value "DeleteReadOnly" to permit deletion of read-only files. The default is 0. Set to non-zero value to activate. --- src/WINNT/afsd/afsd_init.c | 10 ++++++++++ src/WINNT/afsd/cm_access.c | 12 ++++++++++-- src/WINNT/afsd/cm_vnodeops.c | 11 +++++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 1dc22c6d4..629915f1c 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -39,6 +39,7 @@ extern int RXSTATS_ExecuteRequest(struct rx_call *z_call); extern afs_int32 cryptall; extern int cm_enableServerLocks; +extern int cm_deleteReadOnly; osi_log_t *afsd_logp; @@ -1067,6 +1068,15 @@ int afsd_InitCM(char **reasonP) afsi_log("EnableServerLocks: server requested"); break; } + + dummyLen = sizeof(DWORD); + code = RegQueryValueEx(parmKey, "DeleteReadOnly", NULL, NULL, + (BYTE *) &dwValue, &dummyLen); + if (code == ERROR_SUCCESS) { + cm_deleteReadOnly = (unsigned short) dwValue; + } + afsi_log("CM DeleteReadOnly is %u", cm_deleteReadOnly); + RegCloseKey (parmKey); /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */ diff --git a/src/WINNT/afsd/cm_access.c b/src/WINNT/afsd/cm_access.c index e1aeeba36..5b9d6bd88 100644 --- a/src/WINNT/afsd/cm_access.c +++ b/src/WINNT/afsd/cm_access.c @@ -20,6 +20,8 @@ #include "afsd.h" +int cm_deleteReadOnly = 0; + /* called with scp write-locked, check to see if we have the ACL info we need * and can get it w/o blocking for any locks. * @@ -89,8 +91,14 @@ int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32 /* check mode bits */ if (!(scp->unixModeBits & 0400)) *outRightsp &= ~PRSFS_READ; - if (!(scp->unixModeBits & 0200)) - *outRightsp &= ~(PRSFS_WRITE|PRSFS_DELETE); + if (!(scp->unixModeBits & 0200) && !(rights == (PRSFS_WRITE | PRSFS_LOCK))) + *outRightsp &= ~PRSFS_WRITE; + if (!(scp->unixModeBits & 0200) && !cm_deleteReadOnly) + *outRightsp &= ~PRSFS_DELETE; + + /* if the user can obtain a write-lock, read-locks are implied */ + if (*outRightsp & PRSFS_WRITE) + *outRightsp |= PRSFS_LOCK; code = 1; /* fall through */ diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 97a4e0d18..d302fe593 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -185,7 +185,8 @@ void cm_Gen8Dot3NameInt(const char * longname, cm_dirFid_t * pfid, int vnode = ntohl(pfid->vnode); char *lastDot; int validExtension = 0; - char tc, *temp, *name; + char tc, *temp; + const char *name; /* Unparse the file's vnode number to get a "uniquifier" */ do { @@ -256,8 +257,10 @@ long cm_CheckOpen(cm_scache_t *scp, int openMode, int trunc, cm_user_t *userp, long code; rights = 0; - if (openMode != 1) rights |= PRSFS_READ; - if (openMode == 1 || openMode == 2 || trunc) rights |= PRSFS_WRITE; + if (openMode != 1) + rights |= PRSFS_READ; + if (openMode == 1 || openMode == 2 || trunc) + rights |= PRSFS_WRITE; lock_ObtainMutex(&scp->mx); @@ -3570,7 +3573,7 @@ long cm_LockCheckPerms(cm_scache_t * scp, if (lock_type == LockRead) rights |= PRSFS_LOCK; else if (lock_type == LockWrite) - rights |= PRSFS_WRITE; + rights |= PRSFS_WRITE | PRSFS_LOCK; else { /* hmmkay */ osi_assert(FALSE); -- 2.39.5