VirtualBox

Changeset 44530 in vbox for trunk


Ignore:
Timestamp:
Feb 4, 2013 4:15:22 PM (12 years ago)
Author:
vboxsync
Message:

VBoxServiceVMInfo-win: More user enumeration fixes: Use the process' SID for determining user ownership. Tested on Windows XP and Vista/8. More guest property debugging information on verbose level 4+.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp

    r44528 r44530  
    5757    /** Number of assigned user processes. */
    5858    ULONG ulNumProcs;
    59     /** Last (highest) session number. This
     59    /** Last (highest) session ID. This
    6060     *  is needed for distinguishing old session
    6161     *  process counts from new (current) session
    6262     *  ones. */
    63     ULONG ulSession;
     63    ULONG ulLastSession;
    6464} VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER;
    6565
     
    7676    /** The PID. */
    7777    DWORD id;
     78    /** The SID. */
     79    PSID pSid;
    7880    /** The LUID. */
    7981    LUID luid;
     
    8991bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession);
    9092int  VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount);
    91 void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
     93void VBoxServiceVMInfoWinProcessesFree(DWORD cProcs, PVBOXSERVICEVMINFOPROC paProcs);
    9294
    9395typedef BOOL WINAPI FNQUERYFULLPROCESSIMAGENAME(HANDLE,  DWORD, LPTSTR, PDWORD);
     
    238240            case TokenGroups:
    239241                dwTokenInfoSize = 0;
    240                 /* Allocating will follow in a second step. */
     242                /* Allocation will follow in a second step. */
    241243                break;
    242244
    243             /** @todo Implement more token classes here. */
     245            case TokenUser:
     246                dwTokenInfoSize = 0;
     247                /* Allocation will follow in a second step. */
     248                break;
    244249
    245250            default:
     
    269274                            break;
    270275
     276                        case TokenUser:
     277                            pvTokenInfo = (PTOKEN_USER)HeapAlloc(GetProcessHeap(),
     278                                                                 HEAP_ZERO_MEMORY, dwRetLength);
     279                            if (!pvTokenInfo)
     280                                dwErr = GetLastError();
     281                            dwTokenInfoSize = dwRetLength;
     282                            break;
     283
    271284                        default:
    272285                            AssertMsgFailed(("Re-allocating of token information for token class not implemented\n"));
     
    291304                    {
    292305                        PTOKEN_STATISTICS pStats = (PTOKEN_STATISTICS)pvTokenInfo;
     306                        AssertPtr(pStats);
    293307                        memcpy(&pProc->luid, &pStats->AuthenticationId, sizeof(LUID));
    294308                        /** @todo Add more information of TOKEN_STATISTICS as needed. */
     
    336350                    }
    337351
     352                    case TokenUser:
     353                    {
     354                        PTOKEN_USER pUser = (PTOKEN_USER)pvTokenInfo;
     355                        AssertPtr(pUser);
     356
     357                        DWORD dwLength = GetLengthSid(pUser->User.Sid);
     358                        Assert(dwLength);
     359                        if (dwLength)
     360                        {
     361                            pProc->pSid = (PSID)RTMemAlloc(dwLength);
     362                            AssertPtr(pProc->pSid);
     363                            if (CopySid(dwLength, pProc->pSid, pUser->User.Sid))
     364                            {
     365                                if (!IsValidSid(pProc->pSid))
     366                                    dwErr = ERROR_INVALID_NAME;
     367                            }
     368                            else
     369                                dwErr = GetLastError();
     370                        }
     371                        else
     372                            dwErr = ERROR_NO_DATA;
     373
     374                        if (dwErr != ERROR_SUCCESS)
     375                            VBoxServiceError("Error retrieving SID of process PID=%ld: %ld\n",
     376                                             pProc->id, dwErr);
     377                        break;
     378                    }
     379
    338380                    default:
    339381                        AssertMsgFailed(("Unhandled token information class\n"));
     
    423465            {
    424466                paProcs[i].id = paPID[i];
    425                 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups);
    426                 if (RT_FAILURE(rc))
    427                 {
    428                     /* Because some processes cannot be opened/parsed on
    429                            Windows, we should not consider to be this an error here. */
    430                     rc = VINF_SUCCESS;
    431                 }
    432                 else
    433                 {
    434                     rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics);
    435                     if (RT_FAILURE(rc))
    436                     {
    437                         /* Because some processes cannot be opened/parsed on
    438                            Windows, we should not consider to be this an error here. */
    439                         rc = VINF_SUCCESS;
    440                     }
    441                 }
     467                paProcs[i].pSid = NULL;
     468
     469                int rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenUser);
     470                if (RT_FAILURE(rc2) && g_cVerbosity)
     471                    VBoxServiceError("Get token class \"user\" for process %ld failed, rc=%Rrc\n",
     472                                     paProcs[i].id, rc2);
     473
     474                rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups);
     475                if (RT_FAILURE(rc2) && g_cVerbosity)
     476                    VBoxServiceError("Get token class \"groups\" for process %ld failed, rc=%Rrc\n",
     477                                     paProcs[i].id, rc2);
     478
     479                rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics);
     480                if (RT_FAILURE(rc2) && g_cVerbosity)
     481                    VBoxServiceError("Get token class \"statistics\" for process %ld failed, rc=%Rrc\n",
     482                                     paProcs[i].id, rc2);
    442483            }
    443484
     
    465506 * @param   paProcs     What
    466507 */
    467 void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs)
    468 {
     508void VBoxServiceVMInfoWinProcessesFree(DWORD cProcs, PVBOXSERVICEVMINFOPROC paProcs)
     509{
     510    for (DWORD i = 0; i < cProcs; i++)
     511    {
     512        if (paProcs[i].pSid)
     513            RTMemFree(paProcs[i].pSid);
     514    }
    469515    RTMemFree(paProcs);
    470516}
     
    474520 *
    475521 * @returns Number of processes found for a specified session.
    476  * @param   pSession        The session.
     522 * @param   pSession        The current user's SID.
    477523 * @param   paProcs         The process snapshot.
    478524 * @param   cProcs          The number of processes in the snaphot.
     
    493539    if (rcNt != STATUS_SUCCESS)
    494540    {
    495         VBoxServiceError("Could not get logon session data! rcNt=%#x", rcNt);
     541        VBoxServiceError("Could not get logon session data! rcNt=%#x\n", rcNt);
    496542        return 0;
    497543    }
     544
     545    if (!IsValidSid(pSessionData->Sid))
     546    {
     547       VBoxServiceError("User SID=%p is not valid\n", pSessionData->Sid);
     548       return 0;
     549    }
     550
     551    int rc = VINF_SUCCESS;
    498552
    499553    /*
     
    505559    for (DWORD i = 0; i < cProcs; i++)
    506560    {
    507         VBoxServiceVerbose(4, "PID=%ld: (Interactive: %RTbool) %ld:%ld <-> %ld:%ld\n",
    508                            paProcs[i].id,                  paProcs[i].fInteractive,
    509                            paProcs[i].luid.HighPart,       paProcs[i].luid.LowPart,
    510                            pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);
    511561        if (g_cVerbosity)
    512562        {
    513563            TCHAR szModule[_1K];
    514             int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));
    515             if (RT_SUCCESS(rc2))
     564            rc = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));
     565            if (RT_SUCCESS(rc))
    516566                VBoxServiceVerbose(4, "PID=%ld: %s\n",
    517567                                   paProcs[i].id, szModule);
    518568        }
    519569
    520         if (   paProcs[i].fInteractive
    521             && (   paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart
    522                 && paProcs[i].luid.LowPart  == pSessionData->LogonId.LowPart))
    523         {
    524             cNumProcs++;
    525             if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */
    526                 break;
    527         }
    528     }
    529 
    530     if (g_cVerbosity)
    531         VBoxServiceVerbose(3, "Session has %u processes total\n", cNumProcs);
    532     else
    533         VBoxServiceVerbose(3, "Session has at least one process\n");
     570        PSID pProcSID = paProcs[i].pSid;
     571        if (   RT_SUCCESS(rc)
     572            && pProcSID
     573            && IsValidSid(pProcSID))
     574        {
     575            if (   EqualSid(pSessionData->Sid, paProcs[i].pSid)
     576                && paProcs[i].fInteractive)
     577            {
     578                cNumProcs++;
     579                if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */
     580                    break;
     581            }
     582        }
     583    }
    534584
    535585    if (puTerminalSession)
     
    537587
    538588    LsaFreeReturnBuffer(pSessionData);
     589
    539590    return cNumProcs;
    540591}
     
    611662    }
    612663
    613     VBoxServiceVerbose(3, "Session data: Name=%ls, Session=%u, LogonID=%ld,%ld, LogonType=%ld\n",
     664    VBoxServiceVerbose(3, "Session data: Name=%ls, SessionID=%RU32, LogonID=%ld,%ld, LogonType=%ld\n",
    614665                       pSessionData->UserName.Buffer,
    615666                       pSessionData->Session,
     
    749800    }
    750801
     802    if (fFoundUser)
     803        pUserInfo->ulLastSession = pSessionData->Session;
     804
    751805    LsaFreeReturnBuffer(pSessionData);
    752806    return fFoundUser;
     
    823877        {
    824878            ULONG cUniqueUsers = 0;
     879
     880            /**
     881             * Note: The cSessions loop variable does *not* correlate with
     882             *       the Windows session ID!
     883             */
    825884            for (ULONG i = 0; i < cSessions; i++)
    826885            {
    827                 VBoxServiceVerbose(3, "Handling session %u\n", i);
    828 
    829                 VBOXSERVICEVMINFOUSER UserInfo;
    830                 if (VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i]))
     886                VBoxServiceVerbose(3, "Handling session %RU32 (of %RU32)\n", i + 1, cSessions);
     887
     888                VBOXSERVICEVMINFOUSER userSession;
     889                if (VBoxServiceVMInfoWinIsLoggedIn(&userSession, &paSessions[i]))
    831890                {
    832                     VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls\n",
    833                                        UserInfo.wszUser, UserInfo.wszLogonDomain, UserInfo.wszAuthenticationPackage);
     891                    VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls, session=%RU32\n",
     892                                       userSession.wszUser, userSession.wszLogonDomain, userSession.wszAuthenticationPackage,
     893                                       userSession.ulLastSession);
    834894
    835895                    /* Retrieve assigned processes of current session. */
    836                     uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs,
    837                                                                                      NULL /* Terminal session ID */);
     896                    uint32_t cCurSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs,
     897                                                                                        NULL /* Terminal session ID */);
    838898                    /* Don't return here when current session does not have assigned processes
    839899                     * anymore -- in that case we have to search through the unique users list below
    840900                     * and see if got a stale user/session entry. */
    841901
    842 #ifdef DEBUG
    843                     char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath,  sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32", i);
    844                     VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath,
    845                                           "%RU32: cSessionProcs=%RU32 (%RU32 total)", s_uIter, cSessionProcs, cProcs);
    846 #endif
     902                    if (g_cVerbosity > 3)
     903                    {
     904                        char szDebugSessionPath[255]; RTStrPrintf(szDebugSessionPath,  sizeof(szDebugSessionPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32",
     905                                                                  userSession.ulLastSession);
     906                        VBoxServiceWritePropF(s_uGuestPropClientID, szDebugSessionPath,
     907                                              "#%RU32: cSessionProcs=%RU32 (of %RU32 procs total)", s_uIter, cCurSessionProcs, cProcs);
     908                    }
     909
    847910                    bool fFoundUser = false;
    848911                    for (ULONG a = 0; a < cUniqueUsers; a++)
     
    851914                        AssertPtr(pCurUser);
    852915
    853                         if (   !wcscmp(UserInfo.wszUser, pCurUser->wszUser)
    854                             && !wcscmp(UserInfo.wszLogonDomain, pCurUser->wszLogonDomain)
    855                             && !wcscmp(UserInfo.wszAuthenticationPackage, pCurUser->wszAuthenticationPackage))
     916                        if (   !wcscmp(userSession.wszUser, pCurUser->wszUser)
     917                            && !wcscmp(userSession.wszLogonDomain, pCurUser->wszLogonDomain)
     918                            && !wcscmp(userSession.wszAuthenticationPackage, pCurUser->wszAuthenticationPackage))
    856919                        {
    857920                            /*
    858921                             * Only respect the highest session for the current user.
    859922                             */
    860                             if (i > pCurUser->ulSession)
     923                            if (userSession.ulLastSession > pCurUser->ulLastSession)
    861924                            {
    862                                 VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last session=%RU32)\n",
    863                                                    pCurUser->wszUser, cSessionProcs, i);
    864 
    865                                 if (!cSessionProcs)
    866                                     VBoxServiceVerbose(3, "Stale session for user=%ls detected! Procs %RU32->%RU32, Session RU%32->RU32\n",
     925                                VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last used session: %RU32)\n",
     926                                                   pCurUser->wszUser, cCurSessionProcs, userSession.ulLastSession);
     927
     928                                if (!cCurSessionProcs)
     929                                    VBoxServiceVerbose(3, "Stale session for user=%ls detected! Processes: %RU32 -> %RU32, Session: %RU32 -> %RU32\n",
    867930                                                       pCurUser->wszUser,
    868                                                        pCurUser->ulNumProcs, cSessionProcs,
    869                                                        pCurUser->ulSession, i);
    870 
    871                                 pCurUser->ulNumProcs = cSessionProcs;
    872                                 pCurUser->ulSession  = i;
     931                                                       pCurUser->ulNumProcs, cCurSessionProcs,
     932                                                       pCurUser->ulLastSession, userSession.ulLastSession);
     933
     934                                pCurUser->ulNumProcs = cCurSessionProcs;
     935                                pCurUser->ulLastSession  = userSession.ulLastSession;
    873936                            }
    874937                            /* There can be multiple session objects using the same session ID for the
    875938                             * current user -- so when we got the same session again just add the found
    876939                             * processes to it. */
    877                             else if (   pCurUser->ulSession == i
    878                                      && cSessionProcs)
     940                            else if (pCurUser->ulLastSession == userSession.ulLastSession)
    879941                            {
    880                                 VBoxServiceVerbose(4, "Adding %u processes to user=%ls (session=%RU32)\n",
    881                                                    cSessionProcs, pCurUser->wszUser, i);
    882 
    883                                 pCurUser->ulNumProcs += cSessionProcs;
     942                                VBoxServiceVerbose(4, "Updating processes for user=%ls (old procs=%RU32, new procs=%RU32, session=%RU32)\n",
     943                                                   pCurUser->wszUser, pCurUser->ulNumProcs, cCurSessionProcs, pCurUser->ulLastSession);
     944
     945                                pCurUser->ulNumProcs = cCurSessionProcs;
    884946                            }
    885947
     
    891953                    if (!fFoundUser)
    892954                    {
    893                         VBoxServiceVerbose(4, "Adding new user=%ls (session=%RU32) with %u processes\n",
    894                                            UserInfo.wszUser, i, cSessionProcs);
    895 
    896                         memcpy(&pUserInfo[cUniqueUsers], &UserInfo, sizeof(VBOXSERVICEVMINFOUSER));
    897                         pUserInfo[cUniqueUsers].ulNumProcs = cSessionProcs;
    898                         pUserInfo[cUniqueUsers].ulSession  = i;
     955                        VBoxServiceVerbose(4, "Adding new user=%ls (session=%RU32) with %RU32 processes\n",
     956                                           userSession.wszUser, userSession.ulLastSession, cCurSessionProcs);
     957
     958                        memcpy(&pUserInfo[cUniqueUsers], &userSession, sizeof(VBOXSERVICEVMINFOUSER));
     959                        pUserInfo[cUniqueUsers].ulNumProcs = cCurSessionProcs;
    899960                        cUniqueUsers++;
    900961                        Assert(cUniqueUsers <= cSessions);
     
    903964            }
    904965
    905 #ifdef DEBUG
    906             VBoxServiceWritePropF(s_uGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA",
    907                                   "%RU32: cSessions=%RU32, cProcs=%RU32, cUniqueUsers=%RU32",
    908                                   s_uIter, cSessions, cProcs, cUniqueUsers);
    909 #endif
     966            if (g_cVerbosity > 3)
     967                VBoxServiceWritePropF(s_uGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA",
     968                                      "#%RU32: cSessions=%RU32, cProcs=%RU32, cUniqueUsers=%RU32",
     969                                      s_uIter, cSessions, cProcs, cUniqueUsers);
     970
    910971            VBoxServiceVerbose(3, "Found %u unique logged-in user(s)\n",
    911972                               cUniqueUsers);
     
    914975            for (ULONG i = 0; i < cUniqueUsers; i++)
    915976            {
    916 #ifdef DEBUG
    917                 char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath,  sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/User/%RU32", i);
    918                 VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath,
    919                                       "%RU32: szName=%ls, sessionID=%RU32, cProcs=%RU32",
    920                                       s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulSession, pUserInfo[i].ulNumProcs);
    921 #endif
     977                if (g_cVerbosity > 3)
     978                {
     979                    char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath,  sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/User/%RU32", i);
     980                    VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath,
     981                                          "#%RU32: szName=%ls, sessionID=%RU32, cProcs=%RU32",
     982                                          s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulLastSession, pUserInfo[i].ulNumProcs);
     983                }
     984
    922985                bool fAddUser = false;
    923986                if (pUserInfo[i].ulNumProcs)
     
    926989                if (fAddUser)
    927990                {
    928                     VBoxServiceVerbose(3, "User %ls has %ld interactive processes (session %u)\n",
    929                                        pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ulSession);
     991                    VBoxServiceVerbose(3, "User \"%ls\" has %RU32 interactive processes (session=%RU32)\n",
     992                                       pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ulLastSession);
    930993
    931994                    if (*pcUsersInList > 0)
     
    9521015            RTMemFree(pUserInfo);
    9531016        }
    954         VBoxServiceVMInfoWinProcessesFree(paProcs);
     1017        VBoxServiceVMInfoWinProcessesFree(cProcs, paProcs);
    9551018    }
    9561019    LsaFreeReturnBuffer(paSessions);
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