home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / CHIP_CD_1998_07_PL.iso / SOFTWARE / bezpiecz / getadmin / LsaEnj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-08  |  10.4 KB  |  431 lines

  1.  
  2. #ifndef UNICODE
  3. #define UNICODE
  4. #endif // UNICODE
  5.  
  6. #include <windows.h>
  7.  
  8. #include <ntsecapi.h>
  9. #include <lmaccess.h>
  10.  
  11.  
  12.  
  13.  
  14. void LogA(LPSTR strA);
  15.  
  16. void LogW(LPTSTR strW)
  17. {
  18.     char strA[256];
  19.     wcstombs(strA,strW,wcslen(strW));
  20.     LogA(strA);
  21. }
  22.  
  23.  
  24.  
  25. NTSTATUS
  26. OpenPolicy(
  27.     LPWSTR ServerName,          // machine to open policy on (Unicode)
  28.     DWORD DesiredAccess,        // desired access to policy
  29.     PLSA_HANDLE PolicyHandle    // resultant policy handle
  30.     );
  31.  
  32. BOOL
  33. GetAccountSid(
  34.     LPTSTR SystemName,          // where to lookup account
  35.     LPTSTR AccountName,         // account of interest
  36.     PSID *Sid                   // resultant buffer containing SID
  37.     );
  38.  
  39. NTSTATUS
  40. SetPrivilegeOnAccount(
  41.     LSA_HANDLE PolicyHandle,    // open policy handle
  42.     PSID AccountSid,            // SID to grant privilege to
  43.     LPWSTR PrivilegeName,       // privilege to grant (Unicode)
  44.     BOOL bEnable                // enable or disable
  45.     );
  46.  
  47. void
  48. InitLsaString(
  49.     PLSA_UNICODE_STRING LsaString, // destination
  50.     LPWSTR String                  // source (Unicode)
  51.     );
  52.  
  53. void
  54. DisplayNtStatus(
  55.     LPSTR szAPI,                // pointer to function name (ANSI)
  56.     NTSTATUS Status             // NTSTATUS error value
  57.     );
  58.  
  59. void
  60. DisplayWinError(
  61.     LPSTR szAPI,                // pointer to function name (ANSI)
  62.     DWORD WinError              // DWORD WinError
  63.     );
  64.  
  65.  
  66.  
  67. #define RTN_OK 0
  68. #define RTN_USAGE 1
  69. #define RTN_ERROR 13
  70.  
  71. //
  72. // If you have the ddk, include ntstatus.h.
  73. //
  74. #ifndef STATUS_SUCCESS
  75. #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
  76. #endif
  77.  
  78.  
  79. int ChangeUserRights(char* Account)
  80. {
  81.     LSA_HANDLE PolicyHandle;
  82.     WCHAR wComputerName[200]=L"";
  83.     WCHAR wGroupName[200]=L"Administrators";   
  84.  
  85.     WCHAR szAccountName[200];
  86.     WCHAR szProcessAccountName[200];
  87.     DWORD dwAccountSize = 200;
  88.     LONG lAccountSize = 200;
  89.  
  90.     PSID pSid;
  91.     NTSTATUS Status;
  92.     int iRetVal=RTN_ERROR;          
  93.  
  94.  
  95.     
  96.     mbstowcs(szAccountName,Account,strlen(Account));
  97.     
  98.     LogA("\nChangeUserRight Begin");
  99.  
  100.  
  101.     
  102.     GetUserName(szProcessAccountName,&dwAccountSize);
  103.     LogA("\nProcess Account: ");
  104.     LogW(szProcessAccountName);
  105.  
  106.  
  107.  
  108.     if(!wcslen(szAccountName)){
  109.         LogA("\nNo account");
  110.         return 0;
  111.     }
  112.  
  113.     LogA("\nUserName:");
  114.     LogW(szAccountName);
  115.     LogA("\n");
  116.     
  117.  
  118.         
  119.     //
  120.     // Open the policy on the target machine.
  121.     //
  122.     if((Status=OpenPolicy(
  123.                 wComputerName,      // target machine
  124.                 POLICY_ALL_ACCESS, //
  125.                 &PolicyHandle       // resultant policy handle
  126.                 )) != STATUS_SUCCESS) {
  127.         DisplayNtStatus("OpenPolicy", Status);
  128.         return RTN_ERROR;
  129.     }
  130.  
  131.     
  132.     //
  133.     // Obtain the SID of the user/group.
  134.     // Note that we could target a specific machine, but we don't.
  135.     // Specifying NULL for target machine searches for the SID in the
  136.     // following order: well-known, Built-in and local, primary domain,
  137.     // trusted domains.
  138.     //
  139.     if(GetAccountSid(
  140.             NULL,       // default lookup logic
  141.             szAccountName,// account to obtain SID
  142.             &pSid       // buffer to allocate to contain resultant SID
  143.             )) {
  144.         //
  145.         // We only grant the privilege if we succeeded in obtaining the
  146.         // SID. We can actually add SIDs which cannot be looked up, but
  147.         // looking up the SID is a good sanity check which is suitable for
  148.         // most cases.
  149.  
  150.         //SE_SHUTDOWN_NAME
  151.  
  152.         // Grant the SeServiceLogonRight to users represented by pSid.
  153.         //
  154.         /*
  155.         if((Status=SetPrivilegeOnAccount(
  156.                     PolicyHandle,           // policy handle
  157.                     pSid,                   // SID to grant privilege
  158.                     L"SeDebugPrivilege", // Unicode privilege
  159.                     TRUE                    // enable the privilege
  160.                     )) == STATUS_SUCCESS)
  161.             iRetVal=RTN_OK;
  162.         else
  163.             DisplayNtStatus("AddUserRightToAccount", Status);
  164.             */
  165.     }
  166.     else {
  167.         //
  168.         // Error obtaining SID.
  169.         //
  170.         DisplayWinError("GetAccountSid", GetLastError());
  171.     }
  172.  
  173.     NetLocalGroupAddMember(0,wGroupName,pSid);
  174.  
  175.  
  176.     //
  177.     // Close the policy handle.
  178.     //
  179.     LsaClose(PolicyHandle);
  180.  
  181.     //
  182.     // Free memory allocated for SID.
  183.     //
  184.     if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid);
  185.  
  186.    
  187.     return iRetVal;
  188. }
  189.  
  190. void
  191. InitLsaString(
  192.     PLSA_UNICODE_STRING LsaString,
  193.     LPWSTR String
  194.     )
  195. {
  196.     DWORD StringLength;
  197.  
  198.     if (String == NULL) {
  199.         LsaString->Buffer = NULL;
  200.         LsaString->Length = 0;
  201.         LsaString->MaximumLength = 0;
  202.         return;
  203.     }
  204.  
  205.     StringLength = wcslen(String);
  206.     LsaString->Buffer = String;
  207.     LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  208.     LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
  209. }
  210.  
  211. NTSTATUS
  212. OpenPolicy(
  213.     LPWSTR ServerName,
  214.     DWORD DesiredAccess,
  215.     PLSA_HANDLE PolicyHandle
  216.     )
  217. {
  218.     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  219.     LSA_UNICODE_STRING ServerString;
  220.     PLSA_UNICODE_STRING Server = NULL;
  221.  
  222.     //
  223.     // Always initialize the object attributes to all zeroes.
  224.     //
  225.     ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  226.  
  227.     if (ServerName != NULL) {
  228.         //
  229.         // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  230.         //
  231.         InitLsaString(&ServerString, ServerName);
  232.         Server = &ServerString;
  233.     }
  234.  
  235.     //
  236.     // Attempt to open the policy.
  237.     //
  238.     return LsaOpenPolicy(
  239.                 Server,
  240.                 &ObjectAttributes,
  241.                 DesiredAccess,
  242.                 PolicyHandle
  243.                 );
  244. }
  245.  
  246.  
  247. BOOL
  248. GetAccountSid(
  249.     LPTSTR SystemName,
  250.     LPTSTR AccountName,
  251.     PSID *Sid
  252.     )
  253. {
  254.     LPTSTR ReferencedDomain=NULL;
  255.     DWORD cbSid=128;    // initial allocation attempt
  256.     DWORD cbReferencedDomain=16; // initial allocation size
  257.     SID_NAME_USE peUse;
  258.     BOOL bSuccess=FALSE; // assume this function will fail
  259.  
  260.     __try {
  261.  
  262.     //
  263.     // initial memory allocations
  264.     //
  265.     if((*Sid=HeapAlloc(
  266.                     GetProcessHeap(),
  267.                     0,
  268.                     cbSid
  269.                     )) == NULL) __leave;
  270.  
  271.     if((ReferencedDomain=(LPTSTR)HeapAlloc(
  272.                     GetProcessHeap(),
  273.                     0,
  274.                     cbReferencedDomain
  275.                     )) == NULL) __leave;
  276.  
  277.     //
  278.     // Obtain the SID of the specified account on the specified system.
  279.     //
  280.     while(!LookupAccountName(
  281.                     SystemName,         // machine to lookup account on
  282.                     AccountName,        // account to lookup
  283.                     *Sid,               // SID of interest
  284.                     &cbSid,             // size of SID
  285.                     ReferencedDomain,   // domain account was found on
  286.                     &cbReferencedDomain,
  287.                     &peUse
  288.                     )) {
  289.         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  290.             //
  291.             // reallocate memory
  292.             //
  293.             if((*Sid=HeapReAlloc(
  294.                         GetProcessHeap(),
  295.                         0,
  296.                         *Sid,
  297.                         cbSid
  298.                         )) == NULL) __leave;
  299.  
  300.             if((ReferencedDomain=(LPTSTR)HeapReAlloc(
  301.                         GetProcessHeap(),
  302.                         0,
  303.                         ReferencedDomain,
  304.                         cbReferencedDomain
  305.                         )) == NULL) __leave;
  306.         }
  307.         else __leave;
  308.     }
  309.  
  310.     //
  311.     // Indicate success.
  312.     //
  313.     bSuccess=TRUE;
  314.  
  315.     } // finally
  316.     __finally {
  317.  
  318.     //
  319.     // Cleanup and indicate failure, if appropriate.
  320.     //
  321.  
  322.     HeapFree(GetProcessHeap(), 0, ReferencedDomain);
  323.  
  324.     if(!bSuccess) {
  325.         if(*Sid != NULL) {
  326.             HeapFree(GetProcessHeap(), 0, *Sid);
  327.             *Sid = NULL;
  328.         }
  329.     }
  330.  
  331.     } // finally
  332.  
  333.     return bSuccess;
  334. }
  335.  
  336. NTSTATUS
  337. SetPrivilegeOnAccount(
  338.     LSA_HANDLE PolicyHandle,    // open policy handle
  339.     PSID AccountSid,            // SID to grant privilege to
  340.     LPWSTR PrivilegeName,       // privilege to grant (Unicode)
  341.     BOOL bEnable                // enable or disable
  342.     )
  343. {
  344.     LSA_UNICODE_STRING PrivilegeString;
  345.  
  346.     //
  347.     // Create a LSA_UNICODE_STRING for the privilege name.
  348.     //
  349.     InitLsaString(&PrivilegeString, PrivilegeName);
  350.  
  351.     //
  352.     // grant or revoke the privilege, accordingly
  353.     //
  354.     if(bEnable) {
  355.         return LsaAddAccountRights(
  356.                 PolicyHandle,       // open policy handle
  357.                 AccountSid,         // target SID
  358.                 &PrivilegeString,   // privileges
  359.                 1                   // privilege count
  360.                 );
  361.     }
  362.     else {
  363.         return LsaRemoveAccountRights(
  364.                 PolicyHandle,       // open policy handle
  365.                 AccountSid,         // target SID
  366.                 FALSE,              // do not disable all rights
  367.                 &PrivilegeString,   // privileges
  368.                 1                   // privilege count
  369.                 );
  370.     }
  371. }
  372.  
  373. void
  374. DisplayNtStatus(
  375.     LPSTR szAPI,
  376.     NTSTATUS Status
  377.     )
  378. {
  379.     //
  380.     // Convert the NTSTATUS to Winerror. Then call DisplayWinError().
  381.     //
  382.     DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
  383. }
  384.  
  385. void
  386. DisplayWinError(
  387.     LPSTR szAPI,
  388.     DWORD WinError
  389.     )
  390. {
  391.     LPSTR MessageBuffer;
  392.     DWORD dwBufferLength;
  393.  
  394.  
  395.     if(dwBufferLength=FormatMessageA(
  396.                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
  397.                         FORMAT_MESSAGE_FROM_SYSTEM,
  398.                         NULL,
  399.                         WinError,
  400.                         GetUserDefaultLangID(),
  401.                         (LPSTR) &MessageBuffer,
  402.                         0,
  403.                         NULL
  404.                         ))
  405.     {
  406.  
  407.  
  408.         //
  409.         // Output message string on stderr.
  410.         //
  411.         /*
  412.         WriteFile(
  413.             GetStdHandle(STD_ERROR_HANDLE),
  414.             MessageBuffer,
  415.             dwBufferLength,
  416.             &dwBytesWritten,
  417.             NULL
  418.             );
  419.         */
  420.         MessageBuffer[dwBufferLength] =0;
  421.         LogA(MessageBuffer);
  422.  
  423.         //
  424.         // Free the buffer allocated by the system.
  425.         //
  426.         LocalFree(MessageBuffer);
  427.     }
  428.  
  429. }
  430.  
  431.