417 lines
12 KiB
Plaintext
417 lines
12 KiB
Plaintext
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 ///
|