Leaked source code of windows server 2003
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.

333 lines
9.9 KiB

  1. // PermPage.cxx : Implementation ACL Editor classes
  2. // jonn 7/10/97 copied from \nt\private\admin\snapin\filemgmt\permpage.cpp
  3. #include "headers.hxx"
  4. #pragma hdrstop
  5. #include "acl.hxx"
  6. #include "resource.h" // IDS_SHAREPERM_*
  7. #include "util.hxx" // CopySecurityDescriptor
  8. // need IID_ISecurityInformation
  9. #define INITGUID
  10. #include <initguid.h>
  11. #include <aclui.h>
  12. //
  13. // I define my own implementation of ISecurityInformation
  14. //
  15. class CSecurityInformation : public ISecurityInformation
  16. {
  17. public:
  18. // IUnknown
  19. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  20. STDMETHOD_(ULONG, AddRef)();
  21. STDMETHOD_(ULONG, Release)();
  22. // *** ISecurityInformation methods ***
  23. STDMETHOD(GetObjectInformation) (PSI_OBJECT_INFO pObjectInfo ) = 0;
  24. STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
  25. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  26. BOOL fDefault ) = 0;
  27. STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
  28. PSECURITY_DESCRIPTOR pSecurityDescriptor ) = 0;
  29. STDMETHOD(GetAccessRights) (const GUID* pguidObjectType,
  30. DWORD dwFlags,
  31. PSI_ACCESS *ppAccess,
  32. ULONG *pcAccesses,
  33. ULONG *piDefaultAccess );
  34. STDMETHOD(MapGeneric) (const GUID *pguidObjectType,
  35. UCHAR *pAceFlags,
  36. ACCESS_MASK *pMask);
  37. STDMETHOD(GetInheritTypes) (PSI_INHERIT_TYPE *ppInheritTypes,
  38. ULONG *pcInheritTypes );
  39. STDMETHOD(PropertySheetPageCallback)(HWND hwnd, UINT uMsg, SI_PAGE_TYPE uPage );
  40. CSecurityInformation() : _cRef(1) {}
  41. private:
  42. LONG _cRef;
  43. };
  44. class CShareSecurityInformation : public CSecurityInformation
  45. {
  46. private:
  47. LPCWSTR m_strMachineName;
  48. LPCWSTR m_strShareName;
  49. WCHAR m_szTitle[200];
  50. public:
  51. CShareSecurityInformation(LPCWSTR pszMachineName, LPCWSTR pszShareName)
  52. : m_strMachineName(pszMachineName), m_strShareName(pszShareName)
  53. {
  54. LoadString( g_hInstance, IDS_PERMPAGE_TITLE, m_szTitle, ARRAYLEN(m_szTitle) );
  55. }
  56. LPCWSTR QueryMachineName()
  57. {
  58. return m_strMachineName;
  59. }
  60. LPCWSTR QueryShareName()
  61. {
  62. return m_strShareName;
  63. }
  64. // *** ISecurityInformation methods ***
  65. STDMETHOD(GetObjectInformation) (PSI_OBJECT_INFO pObjectInfo );
  66. };
  67. class CSMBSecurityInformation : public CShareSecurityInformation
  68. {
  69. STDMETHOD(GetSecurity) (SECURITY_INFORMATION RequestedInformation,
  70. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  71. BOOL fDefault );
  72. STDMETHOD(SetSecurity) (SECURITY_INFORMATION SecurityInformation,
  73. PSECURITY_DESCRIPTOR pSecurityDescriptor );
  74. public:
  75. PSECURITY_DESCRIPTOR m_pInitialDescriptor;
  76. PSECURITY_DESCRIPTOR* m_ppCurrentDescriptor;
  77. CSMBSecurityInformation(LPCWSTR pszMachineName, LPCWSTR pszShareName, PSECURITY_DESCRIPTOR pSDOriginal, PSECURITY_DESCRIPTOR *ppSDResult);
  78. ~CSMBSecurityInformation();
  79. };
  80. // IUnknown implementation
  81. STDMETHODIMP CSecurityInformation::QueryInterface(REFIID riid, void **ppv)
  82. {
  83. static const QITAB qit[] =
  84. {
  85. QITABENT(CSecurityInformation, ISecurityInformation),
  86. { 0 },
  87. };
  88. return QISearch(this, qit, riid, ppv);
  89. }
  90. STDMETHODIMP_(ULONG) CSecurityInformation::AddRef()
  91. {
  92. return InterlockedIncrement(&_cRef);
  93. }
  94. STDMETHODIMP_(ULONG) CSecurityInformation::Release()
  95. {
  96. appAssert(0 != _cRef);
  97. ULONG cRef = InterlockedDecrement(&_cRef);
  98. if (0 == cRef)
  99. {
  100. delete this;
  101. }
  102. return cRef;
  103. }
  104. // ISecurityInformation interface implementation
  105. SI_ACCESS siShareAccesses[] =
  106. {
  107. { &GUID_NULL,
  108. FILE_ALL_ACCESS,
  109. MAKEINTRESOURCE(IDS_SHAREPERM_ALL),
  110. SI_ACCESS_GENERAL },
  111. { &GUID_NULL,
  112. FILE_GENERIC_READ | FILE_EXECUTE | FILE_GENERIC_WRITE | DELETE,
  113. MAKEINTRESOURCE(IDS_SHAREPERM_MODIFY),
  114. SI_ACCESS_GENERAL },
  115. { &GUID_NULL,
  116. FILE_GENERIC_READ | FILE_EXECUTE,
  117. MAKEINTRESOURCE(IDS_SHAREPERM_READ),
  118. SI_ACCESS_GENERAL }
  119. };
  120. #define iShareDefAccess 2 // FILE_GEN_READ
  121. STDMETHODIMP CSecurityInformation::GetAccessRights (
  122. const GUID* /*pguidObjectType*/,
  123. DWORD /*dwFlags*/,
  124. PSI_ACCESS *ppAccess,
  125. ULONG *pcAccesses,
  126. ULONG *piDefaultAccess )
  127. {
  128. appAssert(ppAccess != NULL);
  129. appAssert(pcAccesses != NULL);
  130. appAssert(piDefaultAccess != NULL);
  131. *ppAccess = siShareAccesses;
  132. *pcAccesses = ARRAYLEN(siShareAccesses);
  133. *piDefaultAccess = iShareDefAccess;
  134. return S_OK;
  135. }
  136. // This is consistent with the NETUI code
  137. GENERIC_MAPPING ShareMap =
  138. {
  139. FILE_GENERIC_READ,
  140. FILE_GENERIC_WRITE,
  141. FILE_GENERIC_EXECUTE,
  142. FILE_ALL_ACCESS
  143. };
  144. STDMETHODIMP CSecurityInformation::MapGeneric (
  145. const GUID* /*pguidObjectType*/,
  146. UCHAR* /*pAceFlags*/,
  147. ACCESS_MASK *pMask)
  148. {
  149. appAssert(pMask != NULL);
  150. MapGenericMask(pMask, &ShareMap);
  151. return S_OK;
  152. }
  153. STDMETHODIMP CSecurityInformation::GetInheritTypes (
  154. PSI_INHERIT_TYPE* /*ppInheritTypes*/,
  155. ULONG* /*pcInheritTypes*/ )
  156. {
  157. appAssert(FALSE);
  158. return E_NOTIMPL;
  159. }
  160. STDMETHODIMP CSecurityInformation::PropertySheetPageCallback(HWND /*hwnd*/, UINT /*uMsg*/, SI_PAGE_TYPE /*uPage*/)
  161. {
  162. return S_OK;
  163. }
  164. /*
  165. JeffreyS 1/24/97:
  166. If you don't set the SI_RESET flag in
  167. ISecurityInformation::GetObjectInformation, then fDefault should never be TRUE
  168. so you can ignore it. Returning E_NOTIMPL in this case is OK too.
  169. If you want the user to be able to reset the ACL to some default state
  170. (defined by you) then turn on SI_RESET and return your default ACL
  171. when fDefault is TRUE. This happens if/when the user pushes a button
  172. that is only visible when SI_RESET is on.
  173. */
  174. STDMETHODIMP CShareSecurityInformation::GetObjectInformation (
  175. PSI_OBJECT_INFO pObjectInfo )
  176. {
  177. if (NULL == pObjectInfo)
  178. return E_POINTER;
  179. pObjectInfo->dwFlags = SI_EDIT_PERMS | SI_NO_ACL_PROTECT | SI_PAGE_TITLE;
  180. pObjectInfo->hInstance = g_hInstance;
  181. pObjectInfo->pszServerName = (LPWSTR)QueryMachineName();
  182. pObjectInfo->pszObjectName = (LPWSTR)QueryShareName();
  183. // page title added JonN 3/8/99 per 115196
  184. pObjectInfo->pszPageTitle = m_szTitle;
  185. return S_OK;
  186. }
  187. CSMBSecurityInformation::CSMBSecurityInformation(
  188. LPCWSTR pszMachineName, LPCWSTR pszShareName,
  189. PSECURITY_DESCRIPTOR pSDOriginal, PSECURITY_DESCRIPTOR *ppSDResult
  190. )
  191. : CShareSecurityInformation(pszMachineName, pszShareName)
  192. , m_pInitialDescriptor( pSDOriginal )
  193. , m_ppCurrentDescriptor( ppSDResult )
  194. {
  195. }
  196. CSMBSecurityInformation::~CSMBSecurityInformation()
  197. {
  198. }
  199. STDMETHODIMP CSMBSecurityInformation::GetSecurity (
  200. SECURITY_INFORMATION RequestedInformation,
  201. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  202. BOOL fDefault )
  203. {
  204. HRESULT hr = S_OK;
  205. if (NULL == ppSecurityDescriptor)
  206. return E_POINTER;
  207. *ppSecurityDescriptor = NULL;
  208. if (0 == RequestedInformation )
  209. return E_INVALIDARG;
  210. if (fDefault)
  211. return E_NOTIMPL;
  212. appAssert( NULL != m_ppCurrentDescriptor );
  213. if (NULL != *m_ppCurrentDescriptor)
  214. {
  215. hr = CopySecurityDescriptor(*m_ppCurrentDescriptor, ppSecurityDescriptor);
  216. }
  217. else if (NULL != m_pInitialDescriptor)
  218. {
  219. hr = CopySecurityDescriptor(m_pInitialDescriptor, ppSecurityDescriptor);
  220. }
  221. else
  222. {
  223. // Ok to return NULL for "no security". Aclui will interpret
  224. // this as "Everyone: Full Control".
  225. }
  226. return hr;
  227. }
  228. STDMETHODIMP CSMBSecurityInformation::SetSecurity (
  229. SECURITY_INFORMATION /*SecurityInformation*/,
  230. PSECURITY_DESCRIPTOR pSecurityDescriptor )
  231. {
  232. PSECURITY_DESCRIPTOR psdTemp;
  233. HRESULT hr = CopySecurityDescriptor(pSecurityDescriptor, &psdTemp);
  234. if (SUCCEEDED(hr))
  235. {
  236. appAssert( NULL != m_ppCurrentDescriptor );
  237. ::LocalFree(*m_ppCurrentDescriptor);
  238. *m_ppCurrentDescriptor = psdTemp;
  239. }
  240. return hr;
  241. }
  242. HMODULE g_hlibACLUI = NULL;
  243. typedef BOOL (*EDIT_SECURITY_PROC) ( HWND, LPSECURITYINFO );
  244. EDIT_SECURITY_PROC g_pfnEditSecurityProc;
  245. LONG
  246. EditShareAcl(
  247. IN HWND hwndParent,
  248. IN LPCWSTR pszServerName,
  249. IN LPCWSTR pszShareName,
  250. IN PSECURITY_DESCRIPTOR pSecDesc,
  251. OUT BOOL* pfSecDescModified,
  252. OUT PSECURITY_DESCRIPTOR* ppSecDesc
  253. )
  254. {
  255. appAssert( ppSecDesc != NULL );
  256. *ppSecDesc = NULL;
  257. if (NULL == g_hlibACLUI)
  258. {
  259. g_hlibACLUI = ::LoadLibrary(L"ACLUI.DLL");
  260. if (NULL == g_hlibACLUI)
  261. {
  262. appAssert(FALSE); // ACLUI.DLL isn't installed?
  263. return 0;
  264. }
  265. }
  266. if (NULL == g_pfnEditSecurityProc)
  267. {
  268. g_pfnEditSecurityProc = reinterpret_cast<EDIT_SECURITY_PROC>(::GetProcAddress(g_hlibACLUI,"EditSecurity"));
  269. if (NULL == g_pfnEditSecurityProc)
  270. {
  271. appAssert(FALSE); // ACLUI.DLL is invalid?
  272. return 0;
  273. }
  274. }
  275. CSMBSecurityInformation* psecinfo = new CSMBSecurityInformation(pszServerName, pszShareName, pSecDesc, ppSecDesc);
  276. if (NULL == psecinfo)
  277. return 0;
  278. (g_pfnEditSecurityProc)(hwndParent,psecinfo);
  279. if (NULL != pfSecDescModified)
  280. *pfSecDescModified = (NULL != *ppSecDesc);
  281. psecinfo->Release();
  282. return 0;
  283. }