To: [email protected]
Subject: Patch 6.1a.034 (extra)
Fcc: outbox
From: Bram Moolenaar <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------

Patch 6.1a.034 (extra)
Problem:    Win32: The ACL checks for a readonly file still don't work well.
Solution:   Remove the ACL checks, go back to how it worked in Vim 6.0.
Files:      src/os_win32.c


*** ../vim61a.033/src/os_win32.c        Wed Feb 27 17:26:22 2002
--- src/os_win32.c      Thu Mar  7 20:10:13 2002
***************
*** 336,358 ****
 typedef DWORD (WINAPI *PGNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
       SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
       PSECURITY_DESCRIPTOR *);
- typedef BOOL (WINAPI *PGFILESEC) (LPCTSTR, SECURITY_INFORMATION,
-         PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
- typedef BOOL (WINAPI *PGSECDESCDACL) (PSECURITY_DESCRIPTOR,
-         LPBOOL, PACL *, LPBOOL);
- typedef BOOL (WINAPI *POPENPROCTOK) (HANDLE, DWORD, PHANDLE);
- typedef BOOL (WINAPI *PGTOKINFO) (HANDLE, TOKEN_INFORMATION_CLASS,
-         LPVOID, DWORD, PDWORD);
- typedef DWORD (WINAPI *PGEFFRIGHTACL) (PACL, TRUSTEE *, ACCESS_MASK *);

 static HANDLE advapi_lib = NULL;      /* Handle for ADVAPI library */
 static PSNSECINFO pSetNamedSecurityInfo;
 static PGNSECINFO pGetNamedSecurityInfo;
- static PGFILESEC pGetFileSecurity;
- static PGSECDESCDACL pGetSecurityDescriptorDacl;
- static POPENPROCTOK pOpenProcessToken;
- static PGTOKINFO pGetTokenInformation;
- static PGEFFRIGHTACL pGetEffectiveRightsFromAcl;
 #endif

 /*
--- 336,345 ----
***************
*** 394,415 ****
                                                     "SetNamedSecurityInfoA");
               pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
                                                     "GetNamedSecurityInfoA");
-               pGetFileSecurity = (PGFILESEC)GetProcAddress(advapi_lib,
-                                                     "GetFileSecurityA");
-               pGetSecurityDescriptorDacl = (PGSECDESCDACL)GetProcAddress(advapi_lib,
-                                                     "GetSecurityDescriptorDacl");
-               pOpenProcessToken = (POPENPROCTOK)GetProcAddress(advapi_lib,
-                                                     "OpenProcessToken");
-               pGetTokenInformation = (PGTOKINFO)GetProcAddress(advapi_lib,
-                                                     "GetTokenInformation");
-               pGetEffectiveRightsFromAcl = (PGEFFRIGHTACL)GetProcAddress(advapi_lib,
-                                                     "GetEffectiveRightsFromAclA");
               if (pSetNamedSecurityInfo == NULL
!                       || pGetNamedSecurityInfo == NULL
!                       || pGetFileSecurity == NULL
!                       || pGetSecurityDescriptorDacl == NULL
!                       || pOpenProcessToken == NULL
!                       || pGetTokenInformation == NULL)
               {
                   /* If we can't get the function addresses, set advapi_lib
                    * to NULL so that we don't use them. */
--- 381,388 ----
                                                     "SetNamedSecurityInfoA");
               pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
                                                     "GetNamedSecurityInfoA");
               if (pSetNamedSecurityInfo == NULL
!                       || pGetNamedSecurityInfo == NULL)
               {
                   /* If we can't get the function addresses, set advapi_lib
                    * to NULL so that we don't use them. */
***************
*** 4035,4234 ****
     return psz;
 }

- #ifdef HAVE_ACL
- /*
-  * Code to support ACLs on Windows based on hints and tips from Corinna
-  * Vinschen.
-  */
-
- /*
-  * do_acl_check() provides an initial check to see if the file system the file
-  * lives on supports ACLs at all.  This is primarily for handlng network drives
-  * - one of Win9x/ME, NT/2K/XP, or Samba.
-  * If the network drive is invalid Check #1 fails.
-  * Win9X/ME and some Samba do not support ACLs at all and fail Check #2.
-  * Samba does not provide full ACL support - we detect them as case preserving
-  * but no supporting unicode file names, Check #3.
-  * NT/2K/XP support ACLs.
-  * Remark: NT 4 SP 4 (and other versions) has a broken
-  * GetEffectiveRightsFromAcl() (Vince Negri)
-  */
-     static int
- do_acl_check(char *n)
- {
-     char_u    buf[MAXPATHL];
-     DWORD     max_comp_len;
-     DWORD     file_sys_flags;
-     int               i;
-     int               first;
-
-     /* Expand "n" to full path, use current dir if this fails. */
-     if (mch_isFullName(n))
-     {
-       STRNCPY(buf, n, MAXPATHL);
-       buf[MAXPATHL - 1] = NUL;
-     }
-     else if (mch_FullName((char_u *)n, buf, MAXPATHL, FALSE) == FAIL
-               && mch_dirname(buf, MAXPATHL) == FAIL)
-       return FALSE;
-
-     /* Extract file root path */
-     if ((buf[0] == '/' || buf[0] == '\\') && (buf[1] == '/' || buf[1] == '\\'))
-     {
-       /* "//computer/share" kind of name, truncate after "share". */
-       first = TRUE;
-       for (i = 2; buf[i] != NUL; ++i)
-       {
-           if (buf[i] == '/' || buf[i] == '\\')
-           {
-               if (first)
-                   first = FALSE;
-               else
-               {
-                   ++i;        /* include the trailing (back)slash */
-                   break;
-               }
-           }
- #ifdef FEAT_MBYTE
-           if (has_mbyte)
-               i += (*mb_ptr2len_check)(buf + i) - 1;
- #endif
-       }
-     }
-     else
-     {
-       /* "c:/dir" kind of name, truncate after first slash. */
-       i = 3;
-     }
-     buf[i] = NUL;
-
-     /* Check #1 - can we get volume information in the first place? */
-     if (!GetVolumeInformation((char *)buf, NULL, 0, NULL, &max_comp_len,
-                                                   &file_sys_flags, NULL, 0))
-         return FALSE;
-
-     /* Check #2 - does the file system support ACLs at all? */
-     if (!(file_sys_flags & FS_PERSISTENT_ACLS))
-         return FALSE;
-
-     /* Check #3 - does it look like a Samba file system?  Current guess is that
-      * they are the only ones that are case sensitive/preserving but do not
-      * support Unicode file names. */
-     if ((file_sys_flags
-        & (FS_CASE_IS_PRESERVED|FS_CASE_SENSITIVE|FS_UNICODE_STORED_ON_DISK))
-                                 == (FS_CASE_IS_PRESERVED|FS_CASE_SENSITIVE))
-         return FALSE;
-
-     /* The file system supports ACLs - do the check */
-     return TRUE;
- }
-
- /* NB: Not SACL_SECURITY_INFORMATION since we don't have enough privilege */
- #define MCH_ACCESS_SEC  (OWNER_SECURITY_INFORMATION \
-                        |GROUP_SECURITY_INFORMATION \
-                        |DACL_SECURITY_INFORMATION)
-
- /*
-  * acl_check() implements ACL support under Windows NT/2K/XP(?)
-  * Does not support ACLs on NT 3.1/5 since the key function
-  * GetEffectiveRightsFromAcl() does not exist and implementing its
-  * functionality is a pain.
-  * Returns TRUE if file "n" has access rights according to "p" FALSE otherwise.
-  */
-     static int
- acl_check(char* n, int p)
- {
-     DWORD                       error;
-     BOOL                      aclpresent;
-     BOOL                      aclDefault;
-     HANDLE                    hToken;
-     DWORD                     bytes;
-     TRUSTEE                   t;
-     ACCESS_MASK                       am;
-     ACCESS_MASK                       cm;
-     PACL                      pacl;
-     static DWORD              sd_bytes = 0;
-     static SECURITY_DESCRIPTOR* psd = NULL;
-     static DWORD              tu_bytes = 0;
-     static TOKEN_USER*                ptu = NULL;
-
-     if (advapi_lib != NULL
-           && pGetEffectiveRightsFromAcl != NULL)
-     {
-       /* Get file ACL info */
-       if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
-       {
-             error = GetLastError();
-             if (error == ERROR_NOT_SUPPORTED)
-                 return TRUE; /* Should be filtered by do_acl_check() but ... */
-           if (error != ERROR_INSUFFICIENT_BUFFER)
-               return FALSE;
-           vim_free(psd);
-           psd = (SECURITY_DESCRIPTOR *)alloc(bytes);
-           if (psd == NULL)
-           {
-               sd_bytes = 0;
-               return FALSE;
-           }
-           sd_bytes = bytes;
-           if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
-               return FALSE;
-       }
-       if (!pGetSecurityDescriptorDacl(psd, &aclpresent, &pacl, &aclDefault))
-           return FALSE;
-
-       /* Get user security info */
-       if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
-           return FALSE;
-       if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
-       {
-           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-               return FALSE;
-           vim_free(ptu);
-           ptu = (TOKEN_USER *)alloc(bytes);
-           if (ptu == NULL)
-           {
-               tu_bytes = 0;
-               return FALSE;
-           }
-           tu_bytes = bytes;
-           if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
-               return FALSE;
-       }
-
-       /* Lets see what user can do based on ACL */
-       t.pMultipleTrustee = NULL;
-       t.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
-       t.TrusteeForm = TRUSTEE_IS_SID;
-       t.TrusteeType = TRUSTEE_IS_USER;
-       t.ptstrName = ptu->User.Sid;
-       if (pGetEffectiveRightsFromAcl(pacl, &t, &am) != ERROR_SUCCESS)
-           return FALSE;
-
-       cm = 0;
-       cm |= (p & W_OK) ? FILE_WRITE_DATA : 0;
-       cm |= (p & R_OK) ? FILE_READ_DATA : 0;
-
-       /* Check access mask against modes requested */
-       if ((am & cm) != cm)
-           return FALSE;
-     }
-     return TRUE;
- }
- #endif /* HAVE_ACL */
-
 /*
!  * mch_access() extends access() to support ACLs under Windows NT/2K/XP(?)
  * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
  */
     int
 mch_access(char *n, int p)
 {
- #ifdef HAVE_ACL
-     /* Only do ACL check if not on Win 9x/ME - GetEffectiveRightsFromAcl()
-      * does not exist on NT before 4.0 */
-     if (!mch_windows95() && do_acl_check(n) && !acl_check(n, p))
-         return -1;
- #endif /* HAVE_ACL */
     return access(n, p);
 }
--- 4008,4021 ----
     return psz;
 }

 /*
!  * mch_access() was used to support ACLs under Windows NT/2K/XP(?).
!  * Unfortunately the ACL system functions are buggy, we couldn't make it work,
!  * removed for now.
  * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
  */
     int
 mch_access(char *n, int p)
 {
     return access(n, p);
 }
*** ../vim61a.033/src/version.c Thu Mar  7 20:01:53 2002
--- src/version.c       Thu Mar  7 20:10:27 2002
***************
*** 608,609 ****
--- 608,611 ----
 {   /* Add new patch number below this line */
+ /**/
+     34,
 /**/

--
Wizards had always known that the act of observation changed the thing that
was observed, and sometimes forgot that it also changed the observer too.
                       Terry Pratchett  -  Interesting times

///  Bram Moolenaar -- [email protected] -- http://www.moolenaar.net  \\\
///   Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim   \\\
\\\           Project leader for A-A-P -- http://www.a-a-p.org           ///
\\\  Help me helping AIDS orphans in Uganda - http://iccf-holland.org  ///