home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / cacls / filesec.cxx < prev    next >
C/C++ Source or Header  |  1997-10-02  |  6KB  |  179 lines

  1. //+------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1995, Microsoft Corporation.
  4. //
  5. // File:        filesec.cxx
  6. //
  7. // Classes:     CFileSecurity class encapsulating SECURITY_DESCRIPTOR
  8. //
  9. // History:     Nov-93      DaveMont         Created.
  10. //
  11. //-------------------------------------------------------------------
  12.  
  13. #include <filesec.hxx>
  14. //+---------------------------------------------------------------------------
  15. // Function:    Add2Ptr
  16. //
  17. // Synopsis:    Add an unscaled increment to a ptr regardless of type.
  18. //
  19. // Arguments:   [pv]    -- Initial ptr.
  20. //              [cb]    -- Increment
  21. //
  22. // Returns:     Incremented ptr.
  23. //
  24. //----------------------------------------------------------------------------
  25. VOID * Add2Ptr(VOID *pv, ULONG cb)
  26. {
  27.     return((BYTE *) pv + cb);
  28. }
  29. //+---------------------------------------------------------------------------
  30. //
  31. //  Member:     CFileSecurity::CFileSecurity, public
  32. //
  33. //  Synopsis:   initializes data members
  34. //              constructor will not throw
  35. //
  36. //  Arguments:  [filename] - name of file to apply security descriptor to
  37. //
  38. //----------------------------------------------------------------------------
  39. CFileSecurity::CFileSecurity(WCHAR *filename)
  40.     : _psd(NULL),
  41.       _pwfilename(filename)
  42. {
  43. }
  44. //+---------------------------------------------------------------------------
  45. //
  46. //  Member:     CFileSecurity::Init, public
  47. //
  48. //  Synopsis:   Init must be called before any other methods - this
  49. //              is not enforced.  gets security descriptor from file
  50. //
  51. //  Arguments:  none
  52. //
  53. //----------------------------------------------------------------------------
  54. ULONG CFileSecurity::Init()
  55. {
  56.     ULONG ret;
  57.     ULONG cpsd;
  58.  
  59.     // get the size of the security buffer
  60.  
  61.     if (!GetFileSecurity(_pwfilename,
  62.                          DACL_SECURITY_INFORMATION |
  63.                          GROUP_SECURITY_INFORMATION |
  64.                          OWNER_SECURITY_INFORMATION,
  65.                          NULL,
  66.                          0,
  67.                          &cpsd) )
  68.     {
  69.         if (ERROR_INSUFFICIENT_BUFFER == (ret = GetLastError()))
  70.         {
  71.             if (NULL == (_psd = (BYTE *)LocalAlloc(LMEM_FIXED, cpsd)))
  72.             {
  73.                  return(ERROR_NOT_ENOUGH_MEMORY);
  74.             }
  75.  
  76.             // actually get the buffer this time
  77.  
  78.             if ( GetFileSecurity(_pwfilename,
  79.                                  DACL_SECURITY_INFORMATION |
  80.                                  GROUP_SECURITY_INFORMATION |
  81.                                  OWNER_SECURITY_INFORMATION,
  82.                                  _psd,
  83.                                  cpsd,
  84.                                  &cpsd) )
  85.                 ret = ERROR_SUCCESS;
  86.             else
  87.                 ret = GetLastError();
  88.  
  89.         }
  90.     } else
  91.         return(ERROR_NO_SECURITY_ON_OBJECT);
  92.     return(ret);
  93. }
  94. //+---------------------------------------------------------------------------
  95. //
  96. //  Member:     Dtor, public
  97. //
  98. //  Synopsis:   frees security descriptor if allocated
  99. //
  100. //  Arguments:  none
  101. //
  102. //----------------------------------------------------------------------------
  103. CFileSecurity::~CFileSecurity()
  104. {
  105.     if (_psd)
  106.     {
  107.         LocalFree(_psd);
  108.     }
  109. }
  110.  
  111. //+---------------------------------------------------------------------------
  112. //
  113. //  Member:     CFileSecurity::SetFS, public
  114. //
  115. //  Synopsis:   sets or modifies the security descriptor DACL on the specified file
  116. //
  117. //  Arguments:  IN - [fmodify] - TRUE = modify ACL, FALSE = replace ACL
  118. //              IN - [pcdw]    - wrapper around new ACEs
  119. //              IN - [fdir]    - TRUE = directory
  120. //
  121. //  Returns:    status
  122. //
  123. //----------------------------------------------------------------------------
  124. ULONG CFileSecurity::SetFS(BOOL fmodify, CDaclWrap *pcdw, BOOL fdir)
  125. {
  126.    BOOL fdaclpresent;
  127.    BOOL cod;
  128.    ACL *pdacl;
  129.    ULONG ret;
  130.  
  131.    // get the ACL from the security descriptor
  132.  
  133.    if ( GetSecurityDescriptorDacl(_psd,
  134.                                   &fdaclpresent,
  135.                                   &pdacl,
  136.                                   &cod) )
  137.  
  138.    {
  139.        if (fdaclpresent)
  140.        {
  141.            // build the new ACL (from the new ACEs and the old ACL)
  142.  
  143.            ACL *pnewdacl = NULL;
  144.  
  145.            if (ERROR_SUCCESS == (ret =  pcdw->BuildAcl(&pnewdacl, fmodify ? pdacl : NULL, pdacl ? pdacl->AclRevision : ACL_REVISION, fdir)))
  146.            {
  147.                // make a new security descriptor
  148.  
  149.                SECURITY_DESCRIPTOR newsd;
  150.                newsd.Revision = ((SECURITY_DESCRIPTOR*) _psd)->Revision;
  151.                newsd.Sbz1 = 0;
  152.                newsd.Control = SE_DACL_PRESENT;
  153.                newsd.Owner = _psd + (ULONG)((SECURITY_DESCRIPTOR*)_psd)->Owner; // convert to absolute
  154.                newsd.Group = _psd + (ULONG)((SECURITY_DESCRIPTOR*)_psd)->Group; // convert to absolute
  155.                newsd.Sacl  = (ACL *) (_psd + (ULONG)((SECURITY_DESCRIPTOR*)_psd)->Sacl); // convert to absolute
  156.                newsd.Dacl = pnewdacl;
  157.  
  158.                // apply it to the file
  159.  
  160.                if (!SetFileSecurity(_pwfilename,
  161.                                     DACL_SECURITY_INFORMATION,
  162.                                     &newsd))
  163.                {
  164.                    ret = GetLastError();
  165.                }
  166.                LocalFree(pnewdacl);
  167.            }
  168.        }
  169.        else
  170.            return(ERROR_NO_SECURITY_ON_OBJECT);
  171.     } else
  172.     {
  173.         ret = GetLastError();
  174.     }
  175.  
  176.     return(ret);
  177. }
  178.  
  179.