home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / winnt / takeown / takeown.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  414 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /*++
  13.  
  14. Module Name:
  15.  
  16.     Takeown.c
  17.  
  18. Abstract:
  19.  
  20.     Implements a recovery scheme to give an Administrator access to a 
  21.     file that has been denied to all.  
  22.  
  23. Environment:
  24.  
  25.     Must be run from an Administrator account in order to perform 
  26.     reliably.  
  27.  
  28. --*/
  29. #include <windows.h>
  30. #include <stdio.h>
  31. #include <malloc.h>
  32.  
  33. BOOL
  34. AssertTakeOwnership(
  35.     HANDLE TokenHandle
  36.     );
  37.  
  38. BOOL
  39. GetTokenHandle(
  40.     PHANDLE TokenHandle
  41.     );
  42.  
  43. BOOL
  44. VariableInitialization();
  45.  
  46.  
  47.  
  48.  
  49. PSID AliasAdminsSid = NULL;
  50. PSID SeWorldSid;
  51.  
  52. static SID_IDENTIFIER_AUTHORITY    SepNtAuthority = SECURITY_NT_AUTHORITY;
  53. static SID_IDENTIFIER_AUTHORITY    SepWorldSidAuthority   = SECURITY_WORLD_SID_AUTHORITY;
  54.  
  55.  
  56.  
  57.  
  58. void main (int argc, char *argv[])
  59. {
  60.  
  61.  
  62.     BOOL Result;
  63.     LPSTR lpFileName;
  64.     SECURITY_DESCRIPTOR SecurityDescriptor;
  65.     HANDLE TokenHandle;
  66.  
  67.  
  68.     //
  69.     // We expect a file...
  70.     //
  71.     if (argc <= 1) {
  72.  
  73.         printf("Must specify a file name");
  74.         return;
  75.     }
  76.  
  77.  
  78.     lpFileName = argv[1];
  79.  
  80.  
  81.     Result = VariableInitialization();
  82.  
  83.     if ( !Result ) {
  84.         printf("Out of memory\n");
  85.         return;
  86.     }
  87.  
  88.  
  89.  
  90.  
  91.     Result = GetTokenHandle( &TokenHandle );
  92.  
  93.     if ( !Result ) {
  94.  
  95.         //
  96.         // This should not happen
  97.         //
  98.  
  99.         printf("Unable to obtain the handle to our token, exiting\n");
  100.         return;
  101.     }
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.     //
  109.     // Attempt to put a NULL Dacl on the object
  110.     //
  111.  
  112.     InitializeSecurityDescriptor( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
  113.  
  114.  
  115.     Result = SetSecurityDescriptorDacl (
  116.                  &SecurityDescriptor,
  117.                  TRUE,
  118.                  NULL,
  119.                  FALSE
  120.                  );
  121.  
  122.  
  123.  
  124.     if ( !Result ) {
  125.         printf("SetSecurityDescriptorDacl failed, error code = %d\n", GetLastError());
  126.         printf("Exiting\n");
  127.         return;
  128.     }
  129.  
  130.     Result = SetFileSecurity(
  131.                  lpFileName,
  132.                  DACL_SECURITY_INFORMATION,
  133.                  &SecurityDescriptor
  134.                  );
  135.  
  136.     if ( Result ) {
  137.  
  138.         printf("Successful, protection removed\n");
  139.         return;
  140.     } 
  141.  
  142.  
  143.     //
  144.     // That didn't work.
  145.     //
  146.  
  147.  
  148.     //
  149.     // Attempt to make Administrator the owner of the file.
  150.     //
  151.  
  152.  
  153.     Result = SetSecurityDescriptorOwner (
  154.                  &SecurityDescriptor,
  155.                  AliasAdminsSid,
  156.                  FALSE
  157.                  );
  158.  
  159.     if ( !Result ) {
  160.         printf("SetSecurityDescriptorOwner failed, lasterror = %d\n", GetLastError());
  161.         return;
  162.     }
  163.  
  164.  
  165.     Result = SetFileSecurity(
  166.                  lpFileName,
  167.                  OWNER_SECURITY_INFORMATION,
  168.                  &SecurityDescriptor
  169.                  );
  170.  
  171.     if ( !Result ) {
  172.  
  173.  
  174.         //
  175.         // That didn't work either.
  176.         //
  177.  
  178.  
  179.  
  180.         //
  181.         // Assert TakeOwnership privilege, then try again.  Note that
  182.         // since the privilege is only enabled for the duration of 
  183.         // this process, we don't have to worry about turning it off
  184.         // again.
  185.         //
  186.  
  187.         Result = AssertTakeOwnership( TokenHandle );
  188.  
  189.         if ( !Result ) {
  190.             printf("Could not enable SeTakeOwnership privilege\n");
  191.             printf("Log on as Administrator and try again\n");
  192.             return;
  193.         }
  194.  
  195.  
  196.         Result = SetFileSecurity(
  197.                      lpFileName,
  198.                      OWNER_SECURITY_INFORMATION,
  199.                      &SecurityDescriptor
  200.                      );
  201.  
  202.         if ( !Result ) {
  203.  
  204.             printf("Unable to assign Administrator as owner\n");
  205.             printf("Log on as Administrator and try again\n");
  206.             return;
  207.  
  208.         }
  209.     }
  210.  
  211.     //
  212.     // Try to put a benign DACL onto the file again
  213.     //
  214.  
  215.     Result = SetFileSecurity(
  216.                  lpFileName,
  217.                  DACL_SECURITY_INFORMATION,
  218.                  &SecurityDescriptor
  219.                  );
  220.  
  221.     if ( !Result ) {
  222.  
  223.         //
  224.         // This should not happen.
  225.         //
  226.  
  227.         printf("SetFileSecurity unexpectedly failed, error code = %d\n", GetLastError());
  228.  
  229.     } else {
  230.  
  231.         printf("Successful, protection removed\n");
  232.         return;
  233.     }
  234. }
  235.  
  236.  
  237.  
  238.  
  239.  
  240. BOOL
  241. GetTokenHandle(
  242.     PHANDLE TokenHandle
  243.     )
  244. //
  245. // This routine will open the current process and return
  246. // a handle to its token.
  247. //
  248. // These handles will be closed for us when the process
  249. // exits.
  250. //
  251. {
  252.  
  253.     HANDLE ProcessHandle;
  254.     BOOL Result;
  255.  
  256.     ProcessHandle = OpenProcess(
  257.                         PROCESS_QUERY_INFORMATION,
  258.                         FALSE,
  259.                         GetCurrentProcessId()
  260.                         );
  261.  
  262.     if ( ProcessHandle == NULL ) {
  263.  
  264.         //
  265.         // This should not happen
  266.         //
  267.  
  268.         return( FALSE );
  269.     }
  270.  
  271.  
  272.     Result = OpenProcessToken (
  273.                  ProcessHandle,
  274.                  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  275.                  TokenHandle
  276.                  );
  277.  
  278.     if ( !Result ) {
  279.  
  280.         //
  281.         // This should not happen
  282.         //
  283.  
  284.         return( FALSE );
  285.  
  286.     }
  287.  
  288.     return( TRUE );
  289. }
  290.  
  291.  
  292. BOOL
  293. AssertTakeOwnership(
  294.     HANDLE TokenHandle
  295.     )
  296. //
  297. // This routine turns on SeTakeOwnershipPrivilege in the current
  298. // token.  Once that has been accomplished, we can open the file
  299. // for WRITE_OWNER even if we are denied that access by the ACL
  300. // on the file.
  301.  
  302. {
  303.     LUID TakeOwnershipValue;
  304.     BOOL Result;
  305.     TOKEN_PRIVILEGES TokenPrivileges;
  306.  
  307.  
  308.     //
  309.     // First, find out the value of TakeOwnershipPrivilege
  310.     //
  311.  
  312.  
  313.     Result = LookupPrivilegeValue(
  314.                  NULL,
  315.                  "SeTakeOwnershipPrivilege",
  316.                  &TakeOwnershipValue
  317.                  );
  318.  
  319.     if ( !Result ) {
  320.  
  321.         //
  322.         // This should not happen
  323.         //
  324.  
  325.         printf("Unable to obtain value of TakeOwnership privilege\n");
  326.         printf("Error = %d\n",GetLastError());
  327.         printf("Exiting\n");
  328.         return FALSE;
  329.     }
  330.  
  331.     //
  332.     // Set up the privilege set we will need
  333.     //
  334.  
  335.     TokenPrivileges.PrivilegeCount = 1;
  336.     TokenPrivileges.Privileges[0].Luid = TakeOwnershipValue;
  337.     TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  338.  
  339.  
  340.  
  341.  
  342.     (VOID) AdjustTokenPrivileges (
  343.                 TokenHandle,
  344.                 FALSE,
  345.                 &TokenPrivileges,
  346.                 sizeof( TOKEN_PRIVILEGES ),
  347.                 NULL,
  348.                 NULL
  349.                 );
  350.  
  351.     if ( GetLastError() != NO_ERROR ) {
  352.  
  353.         return( FALSE );
  354.  
  355.     } else {
  356.  
  357.         return( TRUE );
  358.     }
  359.  
  360. }
  361.  
  362.  
  363.  
  364. BOOL
  365. VariableInitialization()
  366.  
  367. //
  368. // Create some useful SIDs.
  369. //
  370.  
  371. {
  372.  
  373.     BOOL Result;
  374.  
  375.     Result = AllocateAndInitializeSid(
  376.                  &SepNtAuthority,
  377.                  2,
  378.                  SECURITY_BUILTIN_DOMAIN_RID,
  379.                  DOMAIN_ALIAS_RID_ADMINS,
  380.                  0,
  381.                  0,
  382.                  0,
  383.                  0,
  384.                  0,
  385.                  0,
  386.                  &AliasAdminsSid
  387.                  );
  388.  
  389.     if ( !Result ) {
  390.         return( FALSE );
  391.     }
  392.  
  393.  
  394.     Result = AllocateAndInitializeSid(
  395.                  &SepWorldSidAuthority,
  396.                  1,
  397.                  SECURITY_WORLD_RID,
  398.                  0,
  399.                  0,
  400.                  0,
  401.                  0,
  402.                  0,
  403.                  0,
  404.                  0,
  405.                  &SeWorldSid
  406.                  );
  407.  
  408.     if ( !Result ) {
  409.         return( FALSE );
  410.     }
  411.  
  412.     return( TRUE );
  413. }
  414.