Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.2 KiB

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