home *** CD-ROM | disk | FTP | other *** search
- To: vim-dev@vim.org
- Subject: Patch 6.0.116
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- MIME-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- ------------
-
- 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@moolenaar.net -- 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 ///
-