To: vim_dev@googlegroups.com
Subject: Patch 7.3.1267
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------
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 -- Bram@Moolenaar.net -- 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 ///