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.255 < prev    next >
Encoding:
Internet Message Format  |  2002-02-20  |  9.4 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.0.255 (extra)
  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.255 (extra) (depends on patch 6.0.116 and 6.0.121)
  11. Problem:    Win32: ACL support doesn't work well on Samba drives.
  12. Solution:   Add a check for working ACL support. (Mike Williams)
  13. Files:        src/os_win32.c
  14.  
  15.  
  16. *** ../vim60.254/src/os_win32.c    Thu Jan 10 21:23:57 2002
  17. --- src/os_win32.c    Thu Feb 21 20:29:28 2002
  18. ***************
  19. *** 4035,4063 ****
  20.       return psz;
  21.   }
  22.   
  23.   /* NB: Not SACL_SECURITY_INFORMATION since we don't have enough privilege */
  24.   #define MCH_ACCESS_SEC  (OWNER_SECURITY_INFORMATION \
  25.                |GROUP_SECURITY_INFORMATION \
  26.                |DACL_SECURITY_INFORMATION)
  27.   
  28.   /*
  29. !  * mch_access() extends access() to support ACLs under Windows NT/2K/XP(?)
  30.    * Does not support ACLs on NT 3.1/5 since the key function
  31.    * GetEffectiveRightsFromAcl() does not exist and implementing its
  32.    * functionality is a pain.
  33. !  * Written by Mike Williams.
  34. !  * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
  35.    */
  36. !     int
  37. ! mch_access(char *n, int p)
  38.   {
  39.       BOOL            aclpresent;
  40.       BOOL            aclDefault;
  41.       HANDLE            hToken;
  42.       DWORD            bytes;
  43. - #ifdef HAVE_ACL
  44.       TRUSTEE            t;
  45. - #endif
  46.       ACCESS_MASK            am;
  47.       ACCESS_MASK            cm;
  48.       PACL            pacl;
  49. --- 4035,4122 ----
  50.       return psz;
  51.   }
  52.   
  53. + #ifdef HAVE_ACL
  54. + /*
  55. +  * Code to support ACLs on Windows based on hints and tips from Corinna
  56. +  * Vinschen.
  57. +  */
  58. + /*
  59. +  * do_acl_check() provides an initial check to see if the file system the file
  60. +  * lives on supports ACLs at all.  This is primarily for handlng network drives
  61. +  * - one of Win9x/ME, NT/2K/XP, or Samba.
  62. +  * If the network drive is invalid Check #1 fails.
  63. +  * Win9X/ME and some Samba do not support ACLs at all and fail Check #2.
  64. +  * Samba does not provide full ACL support - we detect them as case preserving
  65. +  * but no supporting unicode file names, Check #3.
  66. +  * NT/2K/XP support ACLs.
  67. +  * Remark: NT 4 SP 4 (and other versions) has a broken
  68. +  * GetEffectiveRightsFromAcl() (Vince Negri)
  69. +  */
  70. +     static int
  71. + do_acl_check(char* n)
  72. + {
  73. +     DWORD   max_comp_len;
  74. +     DWORD   file_sys_flags;
  75. +     static char* file_root = NULL;
  76. +     static int file_root_len = 0;
  77. +     int     new_file_root_len;
  78. +     char*   file_root_end;
  79. +     /* Extract file root path */
  80. +     file_root_end = vim_strrchr(n, '\\');
  81. +     new_file_root_len = file_root_end - n + 1;
  82. +     if (new_file_root_len > file_root_len)
  83. +     {
  84. +         vim_free(file_root);
  85. +         file_root = (char*)alloc(new_file_root_len + 1);
  86. +         file_root_len = new_file_root_len;
  87. +     }
  88. +     STRNCPY(file_root, n, new_file_root_len);
  89. +     file_root[new_file_root_len] = '\0';
  90. +     /* Check #1 - can we get volume information in the first place? */
  91. +     if (!GetVolumeInformation(file_root, NULL, 0, NULL, &max_comp_len,
  92. +                                                       &file_sys_flags, NULL, 0))
  93. +         return FALSE;
  94. +     /* Check #2 - does the file system support ACLs at all? */
  95. +     if (!(file_sys_flags&FS_PERSISTENT_ACLS))
  96. +         return FALSE;
  97. +     /* Check #3 - does it look like a Samba file system?  Current guess is that
  98. +      * they are the only ones that are case sensitive/preserving but do not
  99. +      * support Unicode file names. */
  100. +     if ((file_sys_flags&
  101. +              (FS_CASE_IS_PRESERVED|FS_CASE_SENSITIVE|FS_UNICODE_STORED_ON_DISK))
  102. +                                     == (FS_CASE_IS_PRESERVED|FS_CASE_SENSITIVE))
  103. +         return FALSE;
  104. +     /* The file system supports ACLs - do the check */
  105. +     return TRUE;
  106. + }
  107.   /* NB: Not SACL_SECURITY_INFORMATION since we don't have enough privilege */
  108.   #define MCH_ACCESS_SEC  (OWNER_SECURITY_INFORMATION \
  109.                |GROUP_SECURITY_INFORMATION \
  110.                |DACL_SECURITY_INFORMATION)
  111.   
  112.   /*
  113. !  * acl_check() implements ACL support under Windows NT/2K/XP(?)
  114.    * Does not support ACLs on NT 3.1/5 since the key function
  115.    * GetEffectiveRightsFromAcl() does not exist and implementing its
  116.    * functionality is a pain.
  117. !  * Returns TRUE if file "n" has access rights according to "p" FALSE otherwise.
  118.    */
  119. !     static int
  120. ! acl_check(char* n, int p)
  121.   {
  122. +     DWORD                       error;
  123.       BOOL            aclpresent;
  124.       BOOL            aclDefault;
  125.       HANDLE            hToken;
  126.       DWORD            bytes;
  127.       TRUSTEE            t;
  128.       ACCESS_MASK            am;
  129.       ACCESS_MASK            cm;
  130.       PACL            pacl;
  131. ***************
  132. *** 4066,4114 ****
  133.       static DWORD        tu_bytes = 0;
  134.       static TOKEN_USER*        ptu = NULL;
  135.   
  136. ! #ifdef HAVE_ACL
  137. !     /* Only check ACLs if on WinNT 4.0 or later - GetEffectiveRightsFromAcl()
  138. !      * does not exist on NT before 4.0 */
  139. !     if (!mch_windows95()
  140. !         && advapi_lib != NULL
  141.           && pGetEffectiveRightsFromAcl != NULL)
  142.       {
  143.       /* Get file ACL info */
  144.       if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  145.       {
  146. !         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  147. !         return -1;
  148.           vim_free(psd);
  149.           psd = (SECURITY_DESCRIPTOR *)alloc(bytes);
  150.           if (psd == NULL)
  151.           {
  152.           sd_bytes = 0;
  153. !         return -1;
  154.           }
  155.           sd_bytes = bytes;
  156.           if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  157. !         return -1;
  158.       }
  159.       if (!pGetSecurityDescriptorDacl(psd, &aclpresent, &pacl, &aclDefault))
  160. !         return -1;
  161.   
  162.       /* Get user security info */
  163.       if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  164. !         return -1;
  165.       if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  166.       {
  167.           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  168. !         return -1;
  169.           vim_free(ptu);
  170.           ptu = (TOKEN_USER *)alloc(bytes);
  171.           if (ptu == NULL)
  172.           {
  173.           tu_bytes = 0;
  174. !         return -1;
  175.           }
  176.           tu_bytes = bytes;
  177.           if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  178. !         return -1;
  179.       }
  180.   
  181.       /* Lets see what user can do based on ACL */
  182. --- 4125,4172 ----
  183.       static DWORD        tu_bytes = 0;
  184.       static TOKEN_USER*        ptu = NULL;
  185.   
  186. !     if (advapi_lib != NULL
  187.           && pGetEffectiveRightsFromAcl != NULL)
  188.       {
  189.       /* Get file ACL info */
  190.       if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  191.       {
  192. !             error = GetLastError();
  193. !             if (error == ERROR_NOT_SUPPORTED)
  194. !                 return TRUE; /* Should be filtered by do_acl_check() but ... */
  195. !         if (error != ERROR_INSUFFICIENT_BUFFER)
  196. !         return FALSE;
  197.           vim_free(psd);
  198.           psd = (SECURITY_DESCRIPTOR *)alloc(bytes);
  199.           if (psd == NULL)
  200.           {
  201.           sd_bytes = 0;
  202. !         return FALSE;
  203.           }
  204.           sd_bytes = bytes;
  205.           if (!pGetFileSecurity(n, MCH_ACCESS_SEC, psd, sd_bytes, &bytes))
  206. !         return FALSE;
  207.       }
  208.       if (!pGetSecurityDescriptorDacl(psd, &aclpresent, &pacl, &aclDefault))
  209. !         return FALSE;
  210.   
  211.       /* Get user security info */
  212.       if (!pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  213. !         return FALSE;
  214.       if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  215.       {
  216.           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  217. !         return FALSE;
  218.           vim_free(ptu);
  219.           ptu = (TOKEN_USER *)alloc(bytes);
  220.           if (ptu == NULL)
  221.           {
  222.           tu_bytes = 0;
  223. !         return FALSE;
  224.           }
  225.           tu_bytes = bytes;
  226.           if (!pGetTokenInformation(hToken, TokenUser, ptu, tu_bytes, &bytes))
  227. !         return FALSE;
  228.       }
  229.   
  230.       /* Lets see what user can do based on ACL */
  231. ***************
  232. *** 4118,4124 ****
  233.       t.TrusteeType = TRUSTEE_IS_USER;
  234.       t.ptstrName = ptu->User.Sid;
  235.       if (pGetEffectiveRightsFromAcl(pacl, &t, &am) != ERROR_SUCCESS)
  236. !         return -1;
  237.   
  238.       cm = 0;
  239.       cm |= (p & W_OK) ? FILE_WRITE_DATA : 0;
  240. --- 4176,4182 ----
  241.       t.TrusteeType = TRUSTEE_IS_USER;
  242.       t.ptstrName = ptu->User.Sid;
  243.       if (pGetEffectiveRightsFromAcl(pacl, &t, &am) != ERROR_SUCCESS)
  244. !         return FALSE;
  245.   
  246.       cm = 0;
  247.       cm |= (p & W_OK) ? FILE_WRITE_DATA : 0;
  248. ***************
  249. *** 4126,4133 ****
  250.   
  251.       /* Check access mask against modes requested */
  252.       if ((am & cm) != cm)
  253. !         return -1;
  254.       }
  255.   #endif /* HAVE_ACL */
  256.       return access(n, p);
  257.   }
  258. --- 4184,4207 ----
  259.   
  260.       /* Check access mask against modes requested */
  261.       if ((am & cm) != cm)
  262. !         return FALSE;
  263.       }
  264. +     return TRUE;
  265. + }
  266. + #endif /* HAVE_ACL */
  267. + /*
  268. +  * mch_access() extends access() to support ACLs under Windows NT/2K/XP(?)
  269. +  * Returns 0 if file "n" has access rights according to "p", -1 otherwise.
  270. +  */
  271. +     int
  272. + mch_access(char *n, int p)
  273. + {
  274. + #ifdef HAVE_ACL
  275. +     /* Only do ACL check if not on Win 9x/ME - GetEffectiveRightsFromAcl()
  276. +      * does not exist on NT before 4.0 */
  277. +     if (!mch_windows95() && do_acl_check(n) && !acl_check(n, p))
  278. +         return -1;
  279.   #endif /* HAVE_ACL */
  280.       return access(n, p);
  281.   }
  282. *** ../vim60.254/src/version.c    Thu Feb 21 20:20:08 2002
  283. --- src/version.c    Thu Feb 21 20:29:33 2002
  284. ***************
  285. *** 608,609 ****
  286. --- 608,611 ----
  287.   {   /* Add new patch number below this line */
  288. + /**/
  289. +     255,
  290.   /**/
  291.  
  292. -- 
  293. An alien life briefly visits earth.  Just before departing it leaves a
  294. message in the dust on the back of a white van.  The world is shocked
  295. and wants to know what it means.  After months of studies the worlds
  296. best linguistic scientists are able to decipher the message: "Wash me!".
  297.  
  298.  ///  Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net  \\\
  299. ///   Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim   \\\
  300. \\\           Project leader for A-A-P -- http://www.a-a-p.org           ///
  301.  \\\  Help me helping AIDS orphans in Uganda - http://iccf-holland.org  ///
  302.