- Timestamp:
- Dec 6, 2010 2:37:17 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp
r34737 r34753 53 53 # include <Objbase.h> /* CoInitializeEx */ 54 54 # include <Windows.h> /* ShellExecuteEx, ++ */ 55 # ifdef DEBUG 56 # include <Sddl.h> 57 # endif 55 58 #endif 56 59 … … 1718 1721 * Checks if the process is elevated or not. 1719 1722 * 1720 * @returns true/false. 1721 */ 1722 static bool IsElevated(void) 1723 { 1723 * @returns RTEXITCODE_SUCCESS if preconditions are fine, 1724 * otherwise error message + RTEXITCODE_FAILURE. 1725 * @param pfElevated Where to store the elevation indicator. 1726 */ 1727 static RTEXITCODE ElevationCheck(bool *pfElevated) 1728 { 1729 *pfElevated = false; 1730 1724 1731 # if defined(RT_OS_WINDOWS) 1725 /*1726 * Check if we are elevated.1727 */1728 1732 /** @todo This should probably check if UAC is diabled and if we are 1729 1733 * Administrator first. Also needs to check for Vista+ first, probably. 1730 1734 */ 1731 HANDLE hToken; 1732 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) 1733 { 1734 RTMsgError("OpenProcessToken failed: %u (%#x)", GetLastError(), GetLastError()); 1735 return false; 1736 } 1737 1738 bool fElevated = true; 1739 DWORD cb; 1740 DWORD TokenIsElevated = 0; 1741 if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)/*TokenElevation*/ 20, &TokenIsElevated, sizeof(TokenIsElevated), &cb)) 1742 { 1743 fElevated = TokenIsElevated != 0; 1744 if (fElevated) 1745 { 1746 enum 1735 DWORD cb; 1736 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 1737 HANDLE hToken; 1738 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) 1739 return RTMsgErrorExit(RTEXITCODE_FAILURE, "OpenProcessToken failed: %u (%#x)", GetLastError(), GetLastError()); 1740 1741 /* 1742 * Check if we're member of the Administrators group. If we aren't, there 1743 * is no way to elevate ourselves to system admin. 1744 * N.B. CheckTokenMembership does not do the job here (due to attributes?). 1745 */ 1746 BOOL fIsAdmin = FALSE; 1747 SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 1748 PSID pAdminGrpSid; 1749 if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminGrpSid)) 1750 { 1751 # ifdef DEBUG 1752 char *pszAdminGrpSid = NULL; 1753 ConvertSidToStringSid(pAdminGrpSid, &pszAdminGrpSid); 1754 # endif 1755 1756 if ( !GetTokenInformation(hToken, TokenGroups, NULL, 0, &cb) 1757 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1758 { 1759 PTOKEN_GROUPS pTokenGroups = (PTOKEN_GROUPS)RTMemAllocZ(cb); 1760 if (GetTokenInformation(hToken, TokenGroups, pTokenGroups, cb, &cb)) 1747 1761 { 1748 MY_TokenElevationTypeDefault = 1, 1749 MY_TokenElevationTypeFull, 1750 MY_TokenElevationTypeLimited 1751 } enmType; 1752 if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)/*TokenElevationType*/ 18, &enmType, sizeof(enmType), &cb)) 1753 { 1754 fElevated = enmType == MY_TokenElevationTypeFull; 1762 for (DWORD iGrp = 0; iGrp < pTokenGroups->GroupCount; iGrp++) 1763 { 1764 # ifdef DEBUG 1765 char *pszGrpSid = NULL; 1766 ConvertSidToStringSid(pTokenGroups->Groups[iGrp].Sid, &pszGrpSid); 1767 # endif 1768 if (EqualSid(pAdminGrpSid, pTokenGroups->Groups[iGrp].Sid)) 1769 { 1770 /* That it's listed is enough I think, ignore attributes. */ 1771 fIsAdmin = TRUE; 1772 break; 1773 } 1774 } 1755 1775 } 1756 1776 else 1777 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation(TokenGroups,cb) failed: %u (%#x)", GetLastError(), GetLastError()); 1778 RTMemFree(pTokenGroups); 1779 } 1780 else 1781 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation(TokenGroups,0) failed: %u (%#x)", GetLastError(), GetLastError()); 1782 1783 FreeSid(pAdminGrpSid); 1784 } 1785 else 1786 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "AllocateAndInitializeSid failed: %u (%#x)", GetLastError(), GetLastError()); 1787 if (fIsAdmin) 1788 { 1789 # if 1 1790 /* 1791 * Check the integrity level (Vista / UAC). 1792 */ 1793 # define MY_SECURITY_MANDATORY_HIGH_RID 0x00003000L 1794 # define MY_TokenIntegrityLevel ((TOKEN_INFORMATION_CLASS)25) 1795 if ( !GetTokenInformation(hToken, MY_TokenIntegrityLevel, NULL, 0, &cb) 1796 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 1797 { 1798 PSID_AND_ATTRIBUTES pSidAndAttr = (PSID_AND_ATTRIBUTES)RTMemAlloc(cb); 1799 if (GetTokenInformation(hToken, MY_TokenIntegrityLevel, pSidAndAttr, cb, &cb)) 1757 1800 { 1758 RTMsgError("GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1759 fElevated = false; 1801 DWORD dwIntegrityLevel = *GetSidSubAuthority(pSidAndAttr->Sid, *GetSidSubAuthorityCount(pSidAndAttr->Sid) - 1U); 1802 1803 if (dwIntegrityLevel >= MY_SECURITY_MANDATORY_HIGH_RID) 1804 *pfElevated = true; 1760 1805 } 1761 } 1762 } 1763 else if ( GetLastError() != ERROR_INVALID_PARAMETER 1764 && GetLastError() != ERROR_NOT_SUPPORTED) 1765 { 1766 RTMsgError("GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1767 fElevated = false; 1768 } 1806 else 1807 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1808 RTMemFree(pSidAndAttr); 1809 } 1810 else if ( GetLastError() == ERROR_INVALID_PARAMETER 1811 && GetLastError() == ERROR_NOT_SUPPORTED) 1812 *pfElevated = true; /* Older Windows version. */ 1813 else 1814 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1815 1816 # else 1817 /* 1818 * Check elevation (Vista / UAC). 1819 */ 1820 DWORD TokenIsElevated = 0; 1821 if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)/*TokenElevation*/ 20, &TokenIsElevated, sizeof(TokenIsElevated), &cb)) 1822 { 1823 fElevated = TokenIsElevated != 0; 1824 if (fElevated) 1825 { 1826 enum 1827 { 1828 MY_TokenElevationTypeDefault = 1, 1829 MY_TokenElevationTypeFull, 1830 MY_TokenElevationTypeLimited 1831 } enmType; 1832 if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)/*TokenElevationType*/ 18, &enmType, sizeof(enmType), &cb)) 1833 *pfElevated = enmType == MY_TokenElevationTypeFull; 1834 else 1835 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1836 } 1837 } 1838 else if ( GetLastError() == ERROR_INVALID_PARAMETER 1839 && GetLastError() == ERROR_NOT_SUPPORTED) 1840 *pfElevated = true; /* Older Windows version. */ 1841 else if ( GetLastError() != ERROR_INVALID_PARAMETER 1842 && GetLastError() != ERROR_NOT_SUPPORTED) 1843 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "GetTokenInformation failed: %u (%#x)", GetLastError(), GetLastError()); 1844 # endif 1845 } 1846 else 1847 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Membership in the Administrators group is required to perform this action"); 1848 1769 1849 CloseHandle(hToken); 1770 1771 return fElevated; 1850 return rcExit; 1772 1851 1773 1852 # else … … 1779 1858 char szExecPath[RTPATH_MAX]; 1780 1859 if (RTProcGetExecutablePath(szExecPath, sizeof(szExecPath)) == NULL) 1781 { 1782 RTMsgError("RTProcGetExecutablePath failed"); 1783 return false; 1784 } 1860 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcGetExecutablePath failed"); 1785 1861 1786 1862 RTFSOBJINFO ObjInfo; 1787 1863 int rc = RTPathQueryInfoEx(szExecPath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK); 1788 1864 if (RT_FAILURE(rc)) 1789 { 1790 RTMsgError("RTProcGetExecutablePath failed: %Rrc", rc); 1791 return false; 1792 } 1793 1794 return ObjInfo.Attr.u.Unix.uid == geteuid() 1795 || ObjInfo.Attr.u.Unix.uid == getuid(); 1865 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathQueryInfoEx failed"); 1866 1867 *pfElevated = ObjInfo.Attr.u.Unix.uid == geteuid() 1868 || ObjInfo.Attr.u.Unix.uid == getuid(); 1869 return RTEXITCODE_SUCCESS; 1796 1870 # endif 1797 1871 } … … 1812 1886 if (RT_FAILURE(rc)) 1813 1887 return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s", szErr); 1888 1889 #ifdef WITH_ELEVATION 1890 /* 1891 * Elevation check. 1892 */ 1893 bool fElevated; 1894 RTEXITCODE rcExit = ElevationCheck(&fElevated); 1895 if (rcExit != RTEXITCODE_SUCCESS) 1896 return rcExit; 1897 #endif 1814 1898 1815 1899 /* … … 1837 1921 if (RT_FAILURE(rc)) 1838 1922 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc); 1839 #ifdef WITH_ELEVATION1840 bool fElevated = IsElevated();1841 #endif1842 1923 for (;;) 1843 1924 { … … 1857 1938 return RelaunchElevated(argc, argv); 1858 1939 #endif 1859 RTEXITCODE rcExit;1860 1940 int cCmdargs = argc - GetState.iNext; 1861 1941 char **papszCmdArgs = argv + GetState.iNext;
Note:
See TracChangeset
for help on using the changeset viewer.