home *** CD-ROM | disk | FTP | other *** search
/ Softwarová Záchrana 3 / Softwarova-zachrana-3.bin / pserv.cpl / pserv-2.4.exe / source / CNTMachineAccount.cpp < prev    next >
C/C++ Source or Header  |  2005-01-05  |  5KB  |  253 lines

  1. #include "stdafx.h"
  2. #include "CNTMachineAccount.h"
  3. #include <accctrl.h>
  4. #include <aclapi.h>
  5.  
  6. #define SD_SIZE (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH)
  7.  
  8. PNtMachineAccount theMachineAccount;
  9.  
  10. BOOL PNtMachineAccount::RevertToSelf()
  11. {
  12.     return ::RevertToSelf();
  13. } // RevertToSelf()
  14.  
  15. PNtMachineAccount::PNtMachineAccount()
  16. {
  17.     m_hToken = 0;
  18.     m_hProcess = 0;
  19. } // PNtMachineAccount()
  20.  
  21. PNtMachineAccount::~PNtMachineAccount()
  22. {
  23. } // ~PNtMachineAccount()
  24.  
  25. BOOL PAdjustTokenPrivileges( LPCTSTR lpszPrivileges )
  26. {
  27.     // Retrieve a handle of the access token
  28.     HANDLE hToken;
  29.     if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
  30.     {
  31.         return FALSE;
  32.     }
  33.  
  34.     // Enable the SE_DEBUG_NAME privilege
  35.     LUID DebugValue;
  36.     if( !LookupPrivilegeValue( NULL, lpszPrivileges, &DebugValue ) )
  37.     {
  38.         return FALSE;
  39.     }
  40.  
  41.     TOKEN_PRIVILEGES tkp;
  42.     tkp.PrivilegeCount = 1;
  43.     tkp.Privileges[0].Luid = DebugValue;
  44.     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  45.     AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(tkp), 0, 0 );
  46.  
  47.     // The return value of AdjustTokenPrivileges can't be tested
  48.     HRESULT hResult = GetLastError();
  49.     if( hResult != ERROR_SUCCESS )
  50.     {
  51.         SetLastError( hResult );
  52.         return FALSE;
  53.     }
  54.     return TRUE;
  55. } // PAdjustTokenPrivileges()
  56.  
  57.  
  58. DWORD PNtMachineAccount::DetermineSystemPID()
  59. {
  60.     if( !PAdjustTokenPrivileges(SE_DEBUG_NAME) )
  61.     {
  62.         return FALSE;
  63.     }
  64.  
  65.     OSVERSIONINFO ovi;
  66.     ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  67.     GetVersionEx( &ovi );
  68.     if( ovi.dwMajorVersion <= 4 )
  69.     {
  70.         return 2;
  71.     }
  72.     else
  73.     {
  74.         return 8;
  75.     }
  76. } // DetermineSystemPID()
  77.  
  78. BOOL PNtMachineAccount::ModifySecurity(HANDLE hProc, DWORD dwAccess)
  79. {
  80.    UCHAR          ucSDbuf[SD_SIZE];
  81.    PSECURITY_DESCRIPTOR pSD=(PSECURITY_DESCRIPTOR)ucSDbuf;
  82.    DWORD          dwSDLengthNeeded;
  83.  
  84.    PACL           pAcl;
  85.    PACL           pNewAcl;
  86.  
  87.    EXPLICIT_ACCESS explicitaccess;
  88.  
  89.    BOOL fDaclPresent,fDaclDefaulted;
  90.    DWORD dwResult;
  91.  
  92.    UCHAR          ucAbsSDbuf[SD_SIZE];
  93.    PSECURITY_DESCRIPTOR pAbsSD=(PSECURITY_DESCRIPTOR)ucAbsSDbuf;
  94.    DWORD dwSDLength;
  95.  
  96. #define ACL_SIZE 2048
  97. #define SID_SIZE 1024
  98.  
  99.    PACL pacl,psacl;
  100.    DWORD dwAclSize=ACL_SIZE, dwSaclSize=ACL_SIZE;
  101.    PSID pSidOwner,pSidPrimary;
  102.    DWORD dwSidOwnLen=SID_SIZE,dwSidPrimLen=SID_SIZE;
  103.  
  104.  
  105.    if(!GetKernelObjectSecurity(
  106.       hProc,
  107.       DACL_SECURITY_INFORMATION,
  108.       pSD,
  109.       SD_SIZE,
  110.       &dwSDLengthNeeded))
  111.    {
  112.       return FALSE;
  113.    }
  114.  
  115.    if(!GetSecurityDescriptorDacl(
  116.       pSD,
  117.       &fDaclPresent,
  118.       &pAcl,
  119.       &fDaclDefaulted))
  120.    {
  121.       return FALSE;
  122.    }
  123.  
  124.  
  125.    BuildExplicitAccessWithName(
  126.       &explicitaccess,
  127.       _T("administrators"),
  128.       dwAccess,
  129.       GRANT_ACCESS,
  130.       0 );
  131.  
  132.    if( dwResult = SetEntriesInAcl(
  133.       1,
  134.       &explicitaccess,
  135.       pAcl,
  136.       &pNewAcl ) )
  137.    {
  138.       SetLastError(dwResult);
  139.       return FALSE;
  140.    }
  141.  
  142.  
  143.    pacl = (ACL*)malloc(ACL_SIZE);
  144.    psacl = (ACL*)malloc(ACL_SIZE);
  145.    pSidOwner = malloc(SID_SIZE);
  146.    pSidPrimary = malloc(SID_SIZE);
  147.  
  148.    dwSDLength = SD_SIZE;
  149.  
  150.    if(!MakeAbsoluteSD(
  151.       pSD,
  152.       pAbsSD,
  153.       &dwSDLength,
  154.       pacl, &dwAclSize,
  155.       psacl, &dwSaclSize,
  156.       pSidOwner, &dwSidOwnLen,
  157.       pSidPrimary, &dwSidPrimLen))
  158.    {
  159.       return FALSE;
  160.    }
  161.  
  162.    if(!SetSecurityDescriptorDacl(
  163.       pAbsSD,
  164.       fDaclPresent,
  165.       pNewAcl,
  166.       fDaclDefaulted))
  167.    {
  168.       return FALSE;
  169.    }
  170.  
  171.    if(!SetKernelObjectSecurity(
  172.       hProc,
  173.       DACL_SECURITY_INFORMATION,
  174.       pAbsSD))
  175.    {
  176.       return FALSE;
  177.    }
  178.  
  179.    return (TRUE);
  180. }
  181.  
  182. BOOL PNtMachineAccount::Refresh()
  183. {
  184.    if( !m_hToken )
  185.    {
  186.        //
  187.        // PID 2 is always(?) associated with the
  188.        // "system" process which has the context we
  189.        // are after - local system
  190.        //
  191.        DWORD dwSystemPID = DetermineSystemPID();
  192.  
  193.        if(!(m_hProcess = OpenProcess(
  194.           PROCESS_ALL_ACCESS,
  195.           FALSE,
  196.           dwSystemPID)))
  197.        {
  198.           return FALSE;
  199.        }
  200.  
  201.        //
  202.        // Open the process token with this access
  203.        // so that we can modify the DACL and add
  204.        // TOKEN_DUPLICATE & TOKEN_ASSIGN_PRIMARY
  205.        // rights for this user
  206.        //
  207.        if( !OpenProcessToken(
  208.           m_hProcess,
  209.           READ_CONTROL|WRITE_DAC,
  210.           &m_hToken) )
  211.        {
  212.           return FALSE;
  213.        }
  214.  
  215.        if(!ModifySecurity(
  216.           m_hToken,
  217.           TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_QUERY))
  218.        {
  219.           return FALSE;
  220.        }
  221.  
  222.        CloseHandle(m_hToken);
  223.  
  224.        //
  225.        // Close that handle and get a new one with the right
  226.        // privilege level
  227.        //
  228.  
  229.        if( !OpenProcessToken(
  230.           m_hProcess,
  231.           TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY,
  232.           &m_hToken) )
  233.        {
  234.           return FALSE;
  235.        }
  236.        
  237.     }
  238.     if( m_hToken == 0 )
  239.         return FALSE;
  240.     
  241.     return TRUE;
  242. }
  243.  
  244. BOOL PNtMachineAccount::Impersonate()
  245. {                                                  
  246.     if( Refresh() )
  247.     {
  248.         return ImpersonateLoggedOnUser( m_hToken );
  249.     }
  250.     return FALSE;
  251. }
  252.  
  253.