Patch 7.3.1267
Problem:    MS-Windows ACL support doesn't work well.
Solution:   Implement more ACL support. (Ken Takata)
Files:      src/os_win32.c


*** ../vim-7.3.1266/src/os_win32.c      2013-06-16 16:34:53.000000000 +0200
--- src/os_win32.c      2013-06-29 15:33:52.000000000 +0200
***************
*** 481,500 ****
  # ifndef PROTO
  #  include <aclapi.h>
  # endif
  
  /*
   * These are needed to dynamically load the ADVAPI DLL, which is not
   * implemented under Windows 95 (and causes VIM to crash)
   */
! typedef DWORD (WINAPI *PSNSECINFO) (LPTSTR, enum SE_OBJECT_TYPE,
        SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
  typedef DWORD (WINAPI *PGNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
        SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
        PSECURITY_DESCRIPTOR *);
  
  static HANDLE advapi_lib = NULL;      /* Handle for ADVAPI library */
  static PSNSECINFO pSetNamedSecurityInfo;
  static PGNSECINFO pGetNamedSecurityInfo;
  #endif
  
  typedef BOOL (WINAPI *PSETHANDLEINFORMATION)(HANDLE, DWORD, DWORD);
--- 481,514 ----
  # ifndef PROTO
  #  include <aclapi.h>
  # endif
+ # ifndef PROTECTED_DACL_SECURITY_INFORMATION
+ #  define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000L
+ # endif
  
  /*
   * These are needed to dynamically load the ADVAPI DLL, which is not
   * implemented under Windows 95 (and causes VIM to crash)
   */
! typedef DWORD (WINAPI *PSNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
        SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
  typedef DWORD (WINAPI *PGNSECINFO) (LPSTR, enum SE_OBJECT_TYPE,
        SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
        PSECURITY_DESCRIPTOR *);
+ # ifdef FEAT_MBYTE
+ typedef DWORD (WINAPI *PSNSECINFOW) (LPWSTR, enum SE_OBJECT_TYPE,
+       SECURITY_INFORMATION, PSID, PSID, PACL, PACL);
+ typedef DWORD (WINAPI *PGNSECINFOW) (LPWSTR, enum SE_OBJECT_TYPE,
+       SECURITY_INFORMATION, PSID *, PSID *, PACL *, PACL *,
+       PSECURITY_DESCRIPTOR *);
+ # endif
  
  static HANDLE advapi_lib = NULL;      /* Handle for ADVAPI library */
  static PSNSECINFO pSetNamedSecurityInfo;
  static PGNSECINFO pGetNamedSecurityInfo;
+ # ifdef FEAT_MBYTE
+ static PSNSECINFOW pSetNamedSecurityInfoW;
+ static PGNSECINFOW pGetNamedSecurityInfoW;
+ # endif
  #endif
  
  typedef BOOL (WINAPI *PSETHANDLEINFORMATION)(HANDLE, DWORD, DWORD);
***************
*** 502,507 ****
--- 516,557 ----
  static BOOL allowPiping = FALSE;
  static PSETHANDLEINFORMATION pSetHandleInformation;
  
+ #ifdef HAVE_ACL
+ /*
+  * Enables or disables the specified privilege.
+  */
+     static BOOL
+ win32_enable_privilege(LPTSTR lpszPrivilege, BOOL bEnable)
+ {
+     BOOL             bResult;
+     LUID             luid;
+     HANDLE           hToken;
+     TOKEN_PRIVILEGES tokenPrivileges;
+ 
+     if (!OpenProcessToken(GetCurrentProcess(),
+               TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+       return FALSE;
+ 
+     if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
+     {
+       CloseHandle(hToken);
+       return FALSE;
+     }
+ 
+     tokenPrivileges.PrivilegeCount           = 1;
+     tokenPrivileges.Privileges[0].Luid       = luid;
+     tokenPrivileges.Privileges[0].Attributes = bEnable ?
+                                                   SE_PRIVILEGE_ENABLED : 0;
+ 
+     bResult = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges,
+           sizeof(TOKEN_PRIVILEGES), NULL, NULL);
+ 
+     CloseHandle(hToken);
+ 
+     return bResult && GetLastError() == ERROR_SUCCESS;
+ }
+ #endif
+ 
  /*
   * Set g_PlatformId to VER_PLATFORM_WIN32_NT (NT) or
   * VER_PLATFORM_WIN32_WINDOWS (Win95).
***************
*** 541,554 ****
                                                      "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. */
                    FreeLibrary(advapi_lib);
                    advapi_lib = NULL;
                }
            }
        }
  #endif
--- 591,617 ----
                                                      "SetNamedSecurityInfoA");
                pGetNamedSecurityInfo = (PGNSECINFO)GetProcAddress(advapi_lib,
                                                      "GetNamedSecurityInfoA");
+ # ifdef FEAT_MBYTE
+               pSetNamedSecurityInfoW = (PSNSECINFOW)GetProcAddress(advapi_lib,
+                                                     "SetNamedSecurityInfoW");
+               pGetNamedSecurityInfoW = (PGNSECINFOW)GetProcAddress(advapi_lib,
+                                                     "GetNamedSecurityInfoW");
+ # endif
                if (pSetNamedSecurityInfo == NULL
!                       || pGetNamedSecurityInfo == NULL
! # ifdef FEAT_MBYTE
!                       || pSetNamedSecurityInfoW == NULL
!                       || pGetNamedSecurityInfoW == NULL
! # endif
!                       )
                {
                    /* If we can't get the function addresses, set advapi_lib
                     * to NULL so that we don't use them. */
                    FreeLibrary(advapi_lib);
                    advapi_lib = NULL;
                }
+               /* Enable privilege for getting or setting SACLs. */
+               win32_enable_privilege(SE_SECURITY_NAME, TRUE);
            }
        }
  #endif
***************
*** 3091,3096 ****
--- 3154,3160 ----
      return (vim_acl_T)NULL;
  #else
      struct my_acl   *p = NULL;
+     DWORD   err;
  
      /* This only works on Windows NT and 2000. */
      if (g_PlatformId == VER_PLATFORM_WIN32_NT && advapi_lib != NULL)
***************
*** 3098,3120 ****
        p = (struct my_acl *)alloc_clear((unsigned)sizeof(struct my_acl));
        if (p != NULL)
        {
!           if (pGetNamedSecurityInfo(
!                       (LPTSTR)fname,          // Abstract filename
!                       SE_FILE_OBJECT,         // File Object
!                       // Retrieve the entire security descriptor.
!                       OWNER_SECURITY_INFORMATION |
!                       GROUP_SECURITY_INFORMATION |
!                       DACL_SECURITY_INFORMATION |
!                       SACL_SECURITY_INFORMATION,
!                       &p->pSidOwner,          // Ownership information.
!                       &p->pSidGroup,          // Group membership.
!                       &p->pDacl,              // Discretionary information.
!                       &p->pSacl,              // For auditing purposes.
!                       &p->pSecurityDescriptor
!                                   ) != ERROR_SUCCESS)
            {
!               mch_free_acl((vim_acl_T)p);
!               p = NULL;
            }
        }
      }
--- 3162,3243 ----
        p = (struct my_acl *)alloc_clear((unsigned)sizeof(struct my_acl));
        if (p != NULL)
        {
! # ifdef FEAT_MBYTE
!           WCHAR       *wn = NULL;
! 
!           if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
!               wn = enc_to_utf16(fname, NULL);
!           if (wn != NULL)
!           {
!               /* Try to retrieve the entire security descriptor. */
!               err = pGetNamedSecurityInfoW(
!                           wn,                 // Abstract filename
!                           SE_FILE_OBJECT,     // File Object
!                           OWNER_SECURITY_INFORMATION |
!                           GROUP_SECURITY_INFORMATION |
!                           DACL_SECURITY_INFORMATION |
!                           SACL_SECURITY_INFORMATION,
!                           &p->pSidOwner,      // Ownership information.
!                           &p->pSidGroup,      // Group membership.
!                           &p->pDacl,          // Discretionary information.
!                           &p->pSacl,          // For auditing purposes.
!                           &p->pSecurityDescriptor);
!               if (err == ERROR_ACCESS_DENIED ||
!                       err == ERROR_PRIVILEGE_NOT_HELD)
!               {
!                   /* Retrieve only DACL. */
!                   (void)pGetNamedSecurityInfoW(
!                           wn,
!                           SE_FILE_OBJECT,
!                           DACL_SECURITY_INFORMATION,
!                           NULL,
!                           NULL,
!                           &p->pDacl,
!                           NULL,
!                           &p->pSecurityDescriptor);
!               }
!               if (p->pSecurityDescriptor == NULL)
!               {
!                   mch_free_acl((vim_acl_T)p);
!                   p = NULL;
!               }
!               vim_free(wn);
!           }
!           else
! # endif
            {
!               /* Try to retrieve the entire security descriptor. */
!               err = pGetNamedSecurityInfo(
!                           (LPSTR)fname,       // Abstract filename
!                           SE_FILE_OBJECT,     // File Object
!                           OWNER_SECURITY_INFORMATION |
!                           GROUP_SECURITY_INFORMATION |
!                           DACL_SECURITY_INFORMATION |
!                           SACL_SECURITY_INFORMATION,
!                           &p->pSidOwner,      // Ownership information.
!                           &p->pSidGroup,      // Group membership.
!                           &p->pDacl,          // Discretionary information.
!                           &p->pSacl,          // For auditing purposes.
!                           &p->pSecurityDescriptor);
!               if (err == ERROR_ACCESS_DENIED ||
!                       err == ERROR_PRIVILEGE_NOT_HELD)
!               {
!                   /* Retrieve only DACL. */
!                   (void)pGetNamedSecurityInfo(
!                           (LPSTR)fname,
!                           SE_FILE_OBJECT,
!                           DACL_SECURITY_INFORMATION,
!                           NULL,
!                           NULL,
!                           &p->pDacl,
!                           NULL,
!                           &p->pSecurityDescriptor);
!               }
!               if (p->pSecurityDescriptor == NULL)
!               {
!                   mch_free_acl((vim_acl_T)p);
!                   p = NULL;
!               }
            }
        }
      }
***************
*** 3123,3128 ****
--- 3246,3274 ----
  #endif
  }
  
+ #ifdef HAVE_ACL
+ /*
+  * Check if "acl" contains inherited ACE.
+  */
+     static BOOL
+ is_acl_inherited(PACL acl)
+ {
+     DWORD   i;
+     ACL_SIZE_INFORMATION    acl_info;
+     PACCESS_ALLOWED_ACE           ace;
+ 
+     acl_info.AceCount = 0;
+     GetAclInformation(acl, &acl_info, sizeof(acl_info), AclSizeInformation);
+     for (i = 0; i < acl_info.AceCount; i++)
+     {
+       GetAce(acl, i, (LPVOID *)&ace);
+       if (ace->Header.AceFlags & INHERITED_ACE)
+           return TRUE;
+     }
+     return FALSE;
+ }
+ #endif
+ 
  /*
   * Set the ACL of file "fname" to "acl" (unless it's NULL).
   * Errors are ignored.
***************
*** 3133,3153 ****
  {
  #ifdef HAVE_ACL
      struct my_acl   *p = (struct my_acl *)acl;
  
      if (p != NULL && advapi_lib != NULL)
!       (void)pSetNamedSecurityInfo(
!                   (LPTSTR)fname,              // Abstract filename
!                   SE_FILE_OBJECT,             // File Object
!                   // Retrieve the entire security descriptor.
!                   OWNER_SECURITY_INFORMATION |
!                       GROUP_SECURITY_INFORMATION |
!                       DACL_SECURITY_INFORMATION |
!                       SACL_SECURITY_INFORMATION,
!                   p->pSidOwner,               // Ownership information.
!                   p->pSidGroup,               // Group membership.
!                   p->pDacl,                   // Discretionary information.
!                   p->pSacl                    // For auditing purposes.
!                   );
  #endif
  }
  
--- 3279,3339 ----
  {
  #ifdef HAVE_ACL
      struct my_acl   *p = (struct my_acl *)acl;
+     SECURITY_INFORMATION    sec_info = 0;
  
      if (p != NULL && advapi_lib != NULL)
!     {
! # ifdef FEAT_MBYTE
!       WCHAR   *wn = NULL;
! # endif
! 
!       /* Set security flags */
!       if (p->pSidOwner)
!           sec_info |= OWNER_SECURITY_INFORMATION;
!       if (p->pSidGroup)
!           sec_info |= GROUP_SECURITY_INFORMATION;
!       if (p->pDacl)
!       {
!           sec_info |= DACL_SECURITY_INFORMATION;
!           /* Do not inherit its parent's DACL.
!            * If the DACL is inherited, Cygwin permissions would be changed.
!            */
!           if (!is_acl_inherited(p->pDacl))
!               sec_info |= PROTECTED_DACL_SECURITY_INFORMATION;
!       }
!       if (p->pSacl)
!           sec_info |= SACL_SECURITY_INFORMATION;
! 
! # ifdef FEAT_MBYTE
!       if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
!           wn = enc_to_utf16(fname, NULL);
!       if (wn != NULL)
!       {
!           (void)pSetNamedSecurityInfoW(
!                       wn,                     // Abstract filename
!                       SE_FILE_OBJECT,         // File Object
!                       sec_info,
!                       p->pSidOwner,           // Ownership information.
!                       p->pSidGroup,           // Group membership.
!                       p->pDacl,               // Discretionary information.
!                       p->pSacl                // For auditing purposes.
!                       );
!           vim_free(wn);
!       }
!       else
! # endif
!       {
!           (void)pSetNamedSecurityInfo(
!                       (LPSTR)fname,           // Abstract filename
!                       SE_FILE_OBJECT,         // File Object
!                       sec_info,
!                       p->pSidOwner,           // Ownership information.
!                       p->pSidGroup,           // Group membership.
!                       p->pDacl,               // Discretionary information.
!                       p->pSacl                // For auditing purposes.
!                       );
!       }
!     }
  #endif
  }
  
*** ../vim-7.3.1266/src/version.c       2013-06-29 15:19:17.000000000 +0200
--- src/version.c       2013-06-29 15:35:23.000000000 +0200
***************
*** 730,731 ****
--- 730,733 ----
  {   /* Add new patch number below this line */
+ /**/
+     1267,
  /**/

-- 
We do not stumble over mountains, but over molehills.
                                Confucius

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Raspunde prin e-mail lui