diff --git a/7.3.1267 b/7.3.1267 new file mode 100644 index 0000000..63fddc2 --- /dev/null +++ b/7.3.1267 @@ -0,0 +1,416 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.1267 +Fcc: outbox +From: Bram Moolenaar +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 + # 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 + # 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 ///