Loading ...
Sorry, an error occurred while loading the content.

Patch 6.0.116

Expand Messages
  • Bram Moolenaar
    Patch 6.0.116 (extra) Problem: MS-Windows NT/2000/XP: filewritable() doesn t work correctly for filesystems that use ACLs. Solution: Use ACL functions to
    Message 1 of 1 , Jan 1, 2002
    • 0 Attachment
      Patch 6.0.116 (extra)
      Problem: MS-Windows NT/2000/XP: filewritable() doesn't work correctly for
      filesystems that use ACLs.
      Solution: Use ACL functions to check if a file is writable. (Mike Williams)
      Files: src/eval.c, src/macros.h, src/os_win32.c, src/proto/os_win32.pro


      *** ../vim60.115/src/eval.c Tue Jan 1 15:16:42 2002
      --- src/eval.c Tue Jan 1 20:50:07 2002
      ***************
      *** 3412,3432 ****
      #endif

      p = get_var_string(&argvars[0]);
      ! #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
      ! #ifdef WIN3264
      ! if (mch_writable(p))
      ! #else
      ! # ifdef UNIX
      perm = mch_getperm(p);
      ! # endif
      if (
      ! # ifdef UNIX
      ! (perm & 0222) &&
      # endif
      ! mch_access((char *)p, W_OK) == 0
      )
      #endif
      - #endif
      {
      ++retval;
      if (mch_isdir(p))
      --- 3412,3432 ----
      #endif

      p = get_var_string(&argvars[0]);
      ! #ifdef UNIX
      perm = mch_getperm(p);
      ! #endif
      ! #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
      if (
      ! # ifdef WIN3264
      ! mch_writable(p)
      ! # else
      ! # ifdef UNIX
      ! (perm & 0222)
      ! # endif
      # endif
      ! && mch_access((char *)p, W_OK) == 0
      )
      #endif
      {
      ++retval;
      if (mch_isdir(p))
      *** ../vim60.115/src/macros.h Sat Jul 28 22:50:57 2001
      --- src/macros.h Tue Jan 1 20:52:19 2002
      ***************
      *** 136,142 ****
      /* VMS does not have lstat() */
      # define mch_stat(n, p) stat(vms_fixfilename(n), (p))
      #else
      ! # define mch_access(n, p) access((n), (p))
      # define mch_fopen(n, p) fopen((n), (p))
      # define mch_fstat(n, p) fstat((n), (p))
      # define mch_lstat(n, p) lstat((n), (p))
      --- 136,144 ----
      /* VMS does not have lstat() */
      # define mch_stat(n, p) stat(vms_fixfilename(n), (p))
      #else
      ! # ifndef WIN32
      ! # define mch_access(n, p) access((n), (p))
      ! # endif
      # define mch_fopen(n, p) fopen((n), (p))
      # define mch_fstat(n, p) fstat((n), (p))
      # define mch_lstat(n, p) lstat((n), (p))
      *** ../vim60.115/src/os_win32.c Sun Nov 4 14:31:23 2001
      --- src/os_win32.c Tue Jan 1 21:06:01 2002
      ***************
      *** 90,103 ****
      --- 90,109 ----
      */
      #ifdef PROTO
      # define HANDLE int
      + # define PHANDLE int
      # define SMALL_RECT int
      # define COORD int
      # define SHORT int
      # define WORD int
      # define DWORD int
      + # define PDWORD int
      # define BOOL int
      + # define LPBOOL int
      # define LPSTR int
      # define LPTSTR int
      + # define LPCTSTR int
      + # define LPDWORD int
      + # define LPVOID int
      # define KEY_EVENT_RECORD int
      # define MOUSE_EVENT_RECORD int
      # define WINAPI
      ***************
      *** 119,124 ****
      --- 125,133 ----
      # define COLORREF int
      # define HDC int
      # define LOGFONT int
      + # define TOKEN_INFORMATION_CLASS int
      + # define TRUSTEE int
      + # define ACCESS_MASK int
      #endif

      #ifndef FEAT_GUI_W32
      ***************
      *** 317,322 ****
      --- 326,332 ----
      DWORD g_PlatformId;

      #ifdef HAVE_ACL
      + # include <aclapi.h>
      /*
      * These are needed to dynamically load the ADVAPI DLL, which is not
      * implemented under Windows 95 (and causes VIM to crash)
      ***************
      *** 326,334 ****
      --- 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

      /*
      ***************
      *** 370,377 ****
      "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. */
      --- 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. */
      ***************
      *** 2368,2375 ****
      }

      #ifdef HAVE_ACL
      - # include <aclapi.h>
      -
      struct my_acl
      {
      PSECURITY_DESCRIPTOR pSecurityDescriptor;
      --- 2406,2411 ----
      ***************
      *** 4000,4003 ****
      --- 4036,4134 ----
      psz = "command.com";

      return psz;
      + }
      +
      + /* 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)
      +
      + /*
      + * mch_access() extends access() to support ACLs 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.
      + * Written by Mike Williams.
      + * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
      + */
      + int
      + mch_access(char *n, int p)
      + {
      + 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;
      +
      + #ifdef HAVE_ACL
      + /* Only check ACLs if on WinNT 4.0 or later - GetEffectiveRightsFromAcl()
      + * does not exist on NT before 4.0 */
      + if (!mch_windows95()
      + && advapi_lib != NULL
      + && pGetEffectiveRightsFromAcl != NULL)
      + {
      + /* Get file ACL info */
      + if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
      + {
      + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
      + return -1;
      + vim_free(psd);
      + psd = (SECURITY_DESCRIPTOR *)alloc(bytes);
      + if (psd == NULL)
      + {
      + sd_bytes = 0;
      + return -1;
      + }
      + sd_bytes = bytes;
      + if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
      + return -1;
      + }
      + if (!pGetSecurityDescriptorDacl(psd, &aclpresent, &pacl, &aclDefault))
      + return -1;
      +
      + /* Get user security info */
      + if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
      + return -1;
      + if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
      + {
      + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
      + return -1;
      + vim_free(ptu);
      + ptu = (TOKEN_USER *)alloc(bytes);
      + if (ptu == NULL)
      + {
      + tu_bytes = 0;
      + return -1;
      + }
      + tu_bytes = bytes;
      + if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
      + return -1;
      + }
      +
      + /* 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 -1;
      +
      + 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 -1;
      + }
      + #endif /* HAVE_ACL */
      + return access(n, p);
      }
      *** ../vim60.115/src/proto/os_win32.pro Tue Sep 25 21:49:34 2001
      --- src/proto/os_win32.pro Tue Jan 1 21:03:23 2002
      ***************
      *** 42,45 ****
      --- 42,46 ----
      long_u mch_avail_mem __ARGS((int special));
      int mch_rename __ARGS((const char *pszOldFile, const char *pszNewFile));
      char *default_shell __ARGS((void));
      + int mch_access __ARGS((char *n, int p));
      /* vim: set ft=c : */
      *** ../vim60.115/src/version.c Tue Jan 1 20:29:44 2002
      --- src/version.c Tue Jan 1 21:07:53 2002
      ***************
      *** 608,609 ****
      --- 608,611 ----
      { /* Add new patch number below this line */
      + /**/
      + 116,
      /**/

      --
      ZOOT: I'm afraid our life must seem very dull and quiet compared to yours.
      We are but eightscore young blondes, all between sixteen and
      nineteen-and-a-half, cut off in this castle, with no one to protect us.
      Oooh. It is a lonely life ... bathing ... dressing ... undressing ...
      making exciting underwear....
      "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

      /// Bram Moolenaar -- Bram@... -- http://www.moolenaar.net \\\
      ((( Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim )))
      \\\ Help me helping AIDS orphans in Uganda - http://iccf-holland.org ///
    Your message has been successfully submitted and would be delivered to recipients shortly.