VirtualBox

Changeset 34753 in vbox for trunk/src


Ignore:
Timestamp:
Dec 6, 2010 2:37:17 PM (14 years ago)
Author:
vboxsync
Message:

VBoxExtPackHelperApp: changed the elevation checks for windows. Require membership in the Administrators group.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp

    r34737 r34753  
    5353# include <Objbase.h>                   /* CoInitializeEx */
    5454# include <Windows.h>                   /* ShellExecuteEx, ++ */
     55# ifdef DEBUG
     56#  include <Sddl.h>
     57# endif
    5558#endif
    5659
     
    17181721 * Checks if the process is elevated or not.
    17191722 *
    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 */
     1727static RTEXITCODE ElevationCheck(bool *pfElevated)
     1728{
     1729    *pfElevated = false;
     1730
    17241731# if defined(RT_OS_WINDOWS)
    1725     /*
    1726      * Check if we are elevated.
    1727      */
    17281732    /** @todo This should probably check if UAC is diabled and if we are
    17291733     *  Administrator first. Also needs to check for Vista+ first, probably.
    17301734     */
    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))
    17471761            {
    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                }
    17551775            }
    17561776            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))
    17571800            {
    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;
    17601805            }
    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
    17691849    CloseHandle(hToken);
    1770 
    1771     return fElevated;
     1850    return rcExit;
    17721851
    17731852# else
     
    17791858    char szExecPath[RTPATH_MAX];
    17801859    if (RTProcGetExecutablePath(szExecPath, sizeof(szExecPath)) == NULL)
    1781     {
    1782         RTMsgError("RTProcGetExecutablePath failed");
    1783         return false;
    1784     }
     1860        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcGetExecutablePath failed");
    17851861
    17861862    RTFSOBJINFO ObjInfo;
    17871863    int rc = RTPathQueryInfoEx(szExecPath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);
    17881864    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;
    17961870# endif
    17971871}
     
    18121886    if (RT_FAILURE(rc))
    18131887        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
    18141898
    18151899    /*
     
    18371921    if (RT_FAILURE(rc))
    18381922        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc);
    1839 #ifdef WITH_ELEVATION
    1840     bool fElevated = IsElevated();
    1841 #endif
    18421923    for (;;)
    18431924    {
     
    18571938                    return RelaunchElevated(argc, argv);
    18581939#endif
    1859                 RTEXITCODE  rcExit;
    18601940                int         cCmdargs     = argc - GetState.iNext;
    18611941                char      **papszCmdArgs = argv + GetState.iNext;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette