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 ///