home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 6.0.116 < prev    next >
Encoding:
Internet Message Format  |  2001-12-31  |  9.9 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.0.116
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.0.116 (extra)
  11. Problem:    MS-Windows NT/2000/XP: filewritable() doesn't work correctly for
  12.             filesystems that use ACLs.
  13. Solution:   Use ACL functions to check if a file is writable. (Mike Williams)
  14. Files:      src/eval.c, src/macros.h, src/os_win32.c, src/proto/os_win32.pro
  15.  
  16.  
  17. *** ../vim60.115/src/eval.c    Tue Jan  1 15:16:42 2002
  18. --- src/eval.c    Tue Jan  1 20:50:07 2002
  19. ***************
  20. *** 3412,3432 ****
  21.   #endif
  22.   
  23.       p = get_var_string(&argvars[0]);
  24. ! #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
  25. ! #ifdef WIN3264
  26. !     if (mch_writable(p))
  27. ! #else
  28. ! # ifdef UNIX
  29.       perm = mch_getperm(p);
  30. ! # endif
  31.       if (
  32. ! # ifdef UNIX
  33. !         (perm & 0222) &&
  34.   # endif
  35. !         mch_access((char *)p, W_OK) == 0
  36.          )
  37.   #endif
  38. - #endif
  39.       {
  40.       ++retval;
  41.       if (mch_isdir(p))
  42. --- 3412,3432 ----
  43.   #endif
  44.   
  45.       p = get_var_string(&argvars[0]);
  46. ! #ifdef UNIX
  47.       perm = mch_getperm(p);
  48. ! #endif
  49. ! #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
  50.       if (
  51. ! # ifdef WIN3264
  52. !         mch_writable(p)
  53. ! # else
  54. ! #  ifdef UNIX
  55. !         (perm & 0222)
  56. ! #  endif
  57.   # endif
  58. !         && mch_access((char *)p, W_OK) == 0
  59.          )
  60.   #endif
  61.       {
  62.       ++retval;
  63.       if (mch_isdir(p))
  64. *** ../vim60.115/src/macros.h    Sat Jul 28 22:50:57 2001
  65. --- src/macros.h    Tue Jan  1 20:52:19 2002
  66. ***************
  67. *** 136,142 ****
  68.       /* VMS does not have lstat() */
  69.   # define mch_stat(n, p)        stat(vms_fixfilename(n), (p))
  70.   #else
  71. ! # define mch_access(n, p)    access((n), (p))
  72.   # define mch_fopen(n, p)    fopen((n), (p))
  73.   # define mch_fstat(n, p)    fstat((n), (p))
  74.   # define mch_lstat(n, p)    lstat((n), (p))
  75. --- 136,144 ----
  76.       /* VMS does not have lstat() */
  77.   # define mch_stat(n, p)        stat(vms_fixfilename(n), (p))
  78.   #else
  79. ! # ifndef WIN32
  80. ! #   define mch_access(n, p)    access((n), (p))
  81. ! # endif
  82.   # define mch_fopen(n, p)    fopen((n), (p))
  83.   # define mch_fstat(n, p)    fstat((n), (p))
  84.   # define mch_lstat(n, p)    lstat((n), (p))
  85. *** ../vim60.115/src/os_win32.c    Sun Nov  4 14:31:23 2001
  86. --- src/os_win32.c    Tue Jan  1 21:06:01 2002
  87. ***************
  88. *** 90,103 ****
  89. --- 90,109 ----
  90.    */
  91.   #ifdef PROTO
  92.   # define HANDLE int
  93. + # define PHANDLE int
  94.   # define SMALL_RECT int
  95.   # define COORD int
  96.   # define SHORT int
  97.   # define WORD int
  98.   # define DWORD int
  99. + # define PDWORD int
  100.   # define BOOL int
  101. + # define LPBOOL int
  102.   # define LPSTR int
  103.   # define LPTSTR int
  104. + # define LPCTSTR int
  105. + # define LPDWORD int
  106. + # define LPVOID int
  107.   # define KEY_EVENT_RECORD int
  108.   # define MOUSE_EVENT_RECORD int
  109.   # define WINAPI
  110. ***************
  111. *** 119,124 ****
  112. --- 125,133 ----
  113.   # define COLORREF int
  114.   # define HDC int
  115.   # define LOGFONT int
  116. + # define TOKEN_INFORMATION_CLASS int
  117. + # define TRUSTEE int
  118. + # define ACCESS_MASK int
  119.   #endif
  120.   
  121.   #ifndef FEAT_GUI_W32
  122. ***************
  123. *** 317,322 ****
  124. --- 326,332 ----
  125.   DWORD g_PlatformId;
  126.   
  127.   #ifdef HAVE_ACL
  128. + # include <aclapi.h>
  129.   /*
  130.    * These are needed to dynamically load the ADVAPI DLL, which is not
  131.    * implemented under Windows 95 (and causes VIM to crash)
  132. ***************
  133. *** 326,334 ****
  134. --- 336,358 ----
  135.   typedef DWORD (WINAPI *PGNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
  136.       SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
  137.       PSECURITY_DESCRIPTOR *);
  138. + typedef BOOL (WINAPI *PGFILESEC) (LPCTSTR, SECURITY_INFORMATION,
  139. +         PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
  140. + typedef BOOL (WINAPI *PGSECDESCDACL) (PSECURITY_DESCRIPTOR,
  141. +         LPBOOL, PACL *, LPBOOL);
  142. + typedef BOOL (WINAPI *POPENPROCTOK) (HANDLE, DWORD, PHANDLE);
  143. + typedef BOOL (WINAPI *PGTOKINFO) (HANDLE, TOKEN_INFORMATION_CLASS,
  144. +         LPVOID, DWORD, PDWORD);
  145. + typedef DWORD (WINAPI *PGEFFRIGHTACL) (PACL, TRUSTEE *, ACCESS_MASK *);
  146.   static HANDLE advapi_lib = NULL;    /* Handle for ADVAPI library */
  147.   static PSNSECINFO pSetNamedSecurityInfo;
  148.   static PGNSECINFO pGetNamedSecurityInfo;
  149. + static PGFILESEC pGetFileSecurity;
  150. + static PGSECDESCDACL pGetSecurityDescriptorDacl;
  151. + static POPENPROCTOK pOpenProcessToken;
  152. + static PGTOKINFO pGetTokenInformation;
  153. + static PGEFFRIGHTACL pGetEffectiveRightsFromAcl;
  154.   #endif
  155.   
  156.   /*
  157. ***************
  158. *** 370,377 ****
  159.                                 "SetNamedSecurityInfoA");
  160.           pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
  161.                                 "GetNamedSecurityInfoA");
  162.           if (pSetNamedSecurityInfo == NULL
  163. !             || pGetNamedSecurityInfo == NULL)
  164.           {
  165.               /* If we can't get the function addresses, set advapi_lib
  166.                * to NULL so that we don't use them. */
  167. --- 394,415 ----
  168.                                 "SetNamedSecurityInfoA");
  169.           pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
  170.                                 "GetNamedSecurityInfoA");
  171. +         pGetFileSecurity = (PGFILESEC)GetProcAddress(advapi_lib,
  172. +                               "GetFileSecurityA");
  173. +         pGetSecurityDescriptorDacl = (PGSECDESCDACL)GetProcAddress(advapi_lib,
  174. +                               "GetSecurityDescriptorDacl");
  175. +         pOpenProcessToken = (POPENPROCTOK)GetProcAddress(advapi_lib,
  176. +                               "OpenProcessToken");
  177. +         pGetTokenInformation = (PGTOKINFO)GetProcAddress(advapi_lib,
  178. +                               "GetTokenInformation");
  179. +         pGetEffectiveRightsFromAcl = (PGEFFRIGHTACL)GetProcAddress(advapi_lib,
  180. +                               "GetEffectiveRightsFromAclA");
  181.           if (pSetNamedSecurityInfo == NULL
  182. !             || pGetNamedSecurityInfo == NULL
  183. !             || pGetFileSecurity == NULL
  184. !             || pGetSecurityDescriptorDacl == NULL
  185. !             || pOpenProcessToken == NULL
  186. !             || pGetTokenInformation == NULL)
  187.           {
  188.               /* If we can't get the function addresses, set advapi_lib
  189.                * to NULL so that we don't use them. */
  190. ***************
  191. *** 2368,2375 ****
  192.   }
  193.   
  194.   #ifdef HAVE_ACL
  195. - # include <aclapi.h>
  196.   struct my_acl
  197.   {
  198.       PSECURITY_DESCRIPTOR    pSecurityDescriptor;
  199. --- 2406,2411 ----
  200. ***************
  201. *** 4000,4003 ****
  202. --- 4036,4134 ----
  203.       psz = "command.com";
  204.   
  205.       return psz;
  206. + }
  207. + /* NB: Not SACL_SECURITY_INFORMATION since we don't have enough privilege */
  208. + #define MCH_ACCESS_SEC  (OWNER_SECURITY_INFORMATION \
  209. +              |GROUP_SECURITY_INFORMATION \
  210. +              |DACL_SECURITY_INFORMATION)
  211. + /*
  212. +  * mch_access() extends access() to support ACLs under Windows NT/2K/XP(?)
  213. +  * Does not support ACLs on NT 3.1/5 since the key function
  214. +  * GetEffectiveRightsFromAcl() does not exist and implementing its
  215. +  * functionality is a pain.
  216. +  * Written by Mike Williams.
  217. +  * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
  218. +  */
  219. +     int
  220. + mch_access(char *n, int p)
  221. + {
  222. +     BOOL            aclpresent;
  223. +     BOOL            aclDefault;
  224. +     HANDLE            hToken;
  225. +     DWORD            bytes;
  226. +     TRUSTEE            t;
  227. +     ACCESS_MASK            am;
  228. +     ACCESS_MASK            cm;
  229. +     PACL            pacl;
  230. +     static DWORD        sd_bytes = 0;
  231. +     static SECURITY_DESCRIPTOR* psd = NULL;
  232. +     static DWORD        tu_bytes = 0;
  233. +     static TOKEN_USER*        ptu = NULL;
  234. + #ifdef HAVE_ACL
  235. +     /* Only check ACLs if on WinNT 4.0 or later - GetEffectiveRightsFromAcl()
  236. +      * does not exist on NT before 4.0 */
  237. +     if (!mch_windows95()
  238. +         && advapi_lib != NULL
  239. +         && pGetEffectiveRightsFromAcl != NULL)
  240. +     {
  241. +     /* Get file ACL info */
  242. +     if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  243. +     {
  244. +         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  245. +         return -1;
  246. +         vim_free(psd);
  247. +         psd = (SECURITY_DESCRIPTOR *)alloc(bytes);
  248. +         if (psd == NULL)
  249. +         {
  250. +         sd_bytes = 0;
  251. +         return -1;
  252. +         }
  253. +         sd_bytes = bytes;
  254. +         if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  255. +         return -1;
  256. +     }
  257. +     if (!pGetSecurityDescriptorDacl(psd, &aclpresent, &pacl, &aclDefault))
  258. +         return -1;
  259. +     /* Get user security info */
  260. +     if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  261. +         return -1;
  262. +     if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  263. +     {
  264. +         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  265. +         return -1;
  266. +         vim_free(ptu);
  267. +         ptu = (TOKEN_USER *)alloc(bytes);
  268. +         if (ptu == NULL)
  269. +         {
  270. +         tu_bytes = 0;
  271. +         return -1;
  272. +         }
  273. +         tu_bytes = bytes;
  274. +         if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  275. +         return -1;
  276. +     }
  277. +     /* Lets see what user can do based on ACL */
  278. +     t.pMultipleTrustee = NULL;
  279. +     t.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  280. +     t.TrusteeForm = TRUSTEE_IS_SID;
  281. +     t.TrusteeType = TRUSTEE_IS_USER;
  282. +     t.ptstrName = ptu->User.Sid;
  283. +     if (pGetEffectiveRightsFromAcl(pacl, &t, &am) != ERROR_SUCCESS)
  284. +         return -1;
  285. +     cm = 0;
  286. +     cm |= (p & W_OK) ? FILE_WRITE_DATA : 0;
  287. +     cm |= (p & R_OK) ? FILE_READ_DATA : 0;
  288. +     /* Check access mask against modes requested */
  289. +     if ((am & cm) != cm)
  290. +         return -1;
  291. +     }
  292. + #endif /* HAVE_ACL */
  293. +     return access(n, p);
  294.   }
  295. *** ../vim60.115/src/proto/os_win32.pro    Tue Sep 25 21:49:34 2001
  296. --- src/proto/os_win32.pro    Tue Jan  1 21:03:23 2002
  297. ***************
  298. *** 42,45 ****
  299. --- 42,46 ----
  300.   long_u mch_avail_mem __ARGS((int special));
  301.   int mch_rename __ARGS((const char *pszOldFile, const char *pszNewFile));
  302.   char *default_shell __ARGS((void));
  303. + int mch_access __ARGS((char *n, int p));
  304.   /* vim: set ft=c : */
  305. *** ../vim60.115/src/version.c    Tue Jan  1 20:29:44 2002
  306. --- src/version.c    Tue Jan  1 21:07:53 2002
  307. ***************
  308. *** 608,609 ****
  309. --- 608,611 ----
  310.   {   /* Add new patch number below this line */
  311. + /**/
  312. +     116,
  313.   /**/
  314.  
  315. -- 
  316. ZOOT:  I'm afraid our life must seem very dull and quiet compared to yours.
  317.        We are but eightscore young blondes, all between sixteen and
  318.        nineteen-and-a-half, cut off in this castle, with no one to protect us.
  319.        Oooh.  It is a lonely life ... bathing ...  dressing ... undressing ...
  320.        making exciting underwear....
  321.                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
  322.  
  323.  ///  Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net  \\\
  324. (((   Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim   )))
  325.  \\\  Help me helping AIDS orphans in Uganda - http://iccf-holland.org  ///
  326.