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.

539 lines
17 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and29 product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. #include <windows.h>
  23. #include <winnt.h>
  24. #include "res.h"
  25. #include "objsec.h"
  26. #include "rndsec.h"
  27. #define DSOP_FILTER_COMMON ( DSOP_FILTER_USERS | \
  28. DSOP_FILTER_UNIVERSAL_GROUPS_SE | \
  29. DSOP_FILTER_GLOBAL_GROUPS_SE )
  30. #define DSOP_FILTER_DL_COMMON1 ( DSOP_DOWNLEVEL_FILTER_USERS \
  31. | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS \
  32. | DSOP_DOWNLEVEL_FILTER_COMPUTERS \
  33. )
  34. #define DSOP_FILTER_DL_COMMON2 ( DSOP_FILTER_DL_COMMON1 \
  35. | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS \
  36. )
  37. #define DSOP_FILTER_DL_COMMON3 ( DSOP_FILTER_DL_COMMON2 \
  38. | DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS \
  39. )
  40. #define DECLARE_SCOPE(t,f,b,m,n,d) \
  41. { sizeof(DSOP_SCOPE_INIT_INFO), (t), (f), { { (b), (m), (n) }, (d) }, NULL, NULL, S_OK }
  42. static const DSOP_SCOPE_INIT_INFO g_aDSOPScopes[] =
  43. {
  44. // The domain to which the target computer is joined.
  45. DECLARE_SCOPE(DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN, \
  46. DSOP_SCOPE_FLAG_STARTING_SCOPE, \
  47. 0, \
  48. DSOP_FILTER_COMMON & ~DSOP_FILTER_UNIVERSAL_GROUPS_SE, \
  49. DSOP_FILTER_COMMON, \
  50. 0),
  51. DECLARE_SCOPE(DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,0,0,0,0,DSOP_FILTER_DL_COMMON2),
  52. // The Global Catalog
  53. DECLARE_SCOPE(DSOP_SCOPE_TYPE_GLOBAL_CATALOG,0,DSOP_FILTER_COMMON|DSOP_FILTER_WELL_KNOWN_PRINCIPALS,0,0,0),
  54. // The domains in the same forest (enterprise) as the domain to which
  55. // the target machine is joined. Note these can only be DS-aware
  56. DECLARE_SCOPE(DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN,0,DSOP_FILTER_COMMON,0,0,0),
  57. // Domains external to the enterprise but trusted directly by the
  58. // domain to which the target machine is joined.
  59. DECLARE_SCOPE(DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN, \
  60. 0, \
  61. DSOP_FILTER_COMMON, \
  62. 0, \
  63. 0, \
  64. DSOP_DOWNLEVEL_FILTER_USERS | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS),
  65. // Target computer scope. Computer scopes are always treated as
  66. // downlevel (i.e., they use the WinNT provider).
  67. DECLARE_SCOPE(DSOP_SCOPE_TYPE_TARGET_COMPUTER,0,0,0,0,DSOP_FILTER_DL_COMMON3),
  68. };
  69. GENERIC_MAPPING ObjMap =
  70. {
  71. ACCESS_READ,
  72. ACCESS_MODIFY,
  73. ACCESS_DELETE,
  74. };
  75. SI_ACCESS g_siObjAccesses[] =
  76. {
  77. { &GUID_NULL, ACCESS_READ, MAKEINTRESOURCEW(IDS_PRIV_READ), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  78. { &GUID_NULL, ACCESS_MODIFY, MAKEINTRESOURCEW(IDS_PRIV_MODIFY), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  79. { &GUID_NULL, ACCESS_DELETE, MAKEINTRESOURCEW(IDS_PRIV_DELETE), SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC },
  80. };
  81. #define g_iObjDefAccess GENERIC_READ
  82. // The following array defines the inheritance types for my containers.
  83. SI_INHERIT_TYPE g_siObjInheritTypes[] =
  84. {
  85. &GUID_NULL, 0, L"This container/object only",
  86. };
  87. /////////////////////////////////////////////////////////////////////////////////////////
  88. CObjSecurity::CObjSecurity() : m_cRef(1)
  89. {
  90. USES_CONVERSION;
  91. m_dwSIFlags = NULL;
  92. m_pConfProp = NULL;
  93. //
  94. // Let's have a properly constructor
  95. //
  96. m_bstrObject = NULL;
  97. m_bstrPage = NULL;
  98. m_pObjectPicker = NULL;
  99. }
  100. /////////////////////////////////////////////////////////////////////////////////////////
  101. CObjSecurity::~CObjSecurity()
  102. {
  103. //
  104. // Properly deallocation
  105. //
  106. if( m_bstrObject )
  107. SysFreeString( m_bstrObject );
  108. if( m_bstrPage )
  109. SysFreeString( m_bstrPage );
  110. if ( m_pObjectPicker )
  111. m_pObjectPicker->Release();
  112. }
  113. /////////////////////////////////////////////////////////////////////////////////////////
  114. STDMETHODIMP
  115. CObjSecurity::InternalInitialize( CONFPROP* pConfProp )
  116. {
  117. HRESULT hr = S_OK;
  118. //
  119. // we can initialize BSTRs here
  120. //
  121. m_bstrObject = SysAllocString( T2COLE(String(g_hInstLib, IDS_CONFPROP_PERMISSIONS_OBJECT )) );
  122. if( IsBadStringPtr( m_bstrObject, (UINT)-1) )
  123. return E_OUTOFMEMORY;
  124. m_bstrPage = SysAllocString( T2COLE(String(g_hInstLib, IDS_CONFPROP_PERMISSIONS_PAGE )) );
  125. if( IsBadStringPtr( m_bstrPage, (UINT)-1) )
  126. {
  127. SysFreeString( m_bstrObject);
  128. return E_OUTOFMEMORY;
  129. }
  130. m_pConfProp = pConfProp;
  131. return hr;
  132. }
  133. /////////////////////////////////////////////////////////////////////////////////////////
  134. /////////////////////////////////////////////////////////////////////////////////////////
  135. //IUnknown Methods
  136. /////////////////////////////////////////////////////////////////////////////////////////
  137. /////////////////////////////////////////////////////////////////////////////////////////
  138. /////////////////////////////////////////////////////////////////////////////////////////
  139. STDMETHODIMP_(ULONG)
  140. CObjSecurity::AddRef()
  141. {
  142. return ++m_cRef;
  143. }
  144. /////////////////////////////////////////////////////////////////////////////////////////
  145. STDMETHODIMP_(ULONG)
  146. CObjSecurity::Release()
  147. {
  148. if (--m_cRef == 0)
  149. {
  150. delete this;
  151. return 0;
  152. }
  153. return m_cRef;
  154. }
  155. /////////////////////////////////////////////////////////////////////////////////////////
  156. STDMETHODIMP
  157. CObjSecurity::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  158. {
  159. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
  160. {
  161. *ppv = (LPSECURITYINFO)this;
  162. }
  163. else if ( IsEqualIID(riid, IID_IDsObjectPicker) )
  164. {
  165. *ppv = static_cast<IDsObjectPicker*> (this);
  166. }
  167. else
  168. {
  169. *ppv = NULL;
  170. return E_NOINTERFACE;
  171. }
  172. m_cRef++;
  173. return S_OK;
  174. }
  175. /////////////////////////////////////////////////////////////////////////////////////////
  176. /////////////////////////////////////////////////////////////////////////////////////////
  177. // IDsObjectPicker
  178. /////////////////////////////////////////////////////////////////////////////////////////
  179. /////////////////////////////////////////////////////////////////////////////////////////
  180. STDMETHODIMP CObjSecurity::Initialize( PDSOP_INIT_INFO pInitInfo )
  181. {
  182. HRESULT hr = S_OK;
  183. DSOP_INIT_INFO InitInfo;
  184. PDSOP_SCOPE_INIT_INFO pDSOPScopes = NULL;
  185. _ASSERT( pInitInfo->cbSize >= FIELD_OFFSET(DSOP_INIT_INFO, cAttributesToFetch) );
  186. // Create an instance of the object
  187. if (!m_pObjectPicker)
  188. {
  189. hr = CoCreateInstance(CLSID_DsObjectPicker,
  190. NULL,
  191. CLSCTX_INPROC_SERVER,
  192. IID_IDsObjectPicker,
  193. (LPVOID*)&m_pObjectPicker);
  194. }
  195. if ( SUCCEEDED(hr) )
  196. {
  197. // Make a local copy of the InitInfo so we can modify it safely
  198. CopyMemory(&InitInfo, pInitInfo, min(pInitInfo->cbSize, sizeof(InitInfo)));
  199. // Make a local copy of g_aDSOPScopes so we can modify it safely.
  200. // Note also that m_pObjectPicker->Initialize returns HRESULTs
  201. // in this buffer.
  202. pDSOPScopes = (PDSOP_SCOPE_INIT_INFO)LocalAlloc(LPTR, sizeof(g_aDSOPScopes));
  203. if (pDSOPScopes)
  204. {
  205. CopyMemory(pDSOPScopes, g_aDSOPScopes, sizeof(g_aDSOPScopes));
  206. // Override the ACLUI default scopes, but don't touch
  207. // the other stuff.
  208. // pDSOPScopes->pwzDcName = m_strServerName;
  209. InitInfo.cDsScopeInfos = ARRAYSIZE(g_aDSOPScopes);
  210. InitInfo.aDsScopeInfos = pDSOPScopes;
  211. hr = m_pObjectPicker->Initialize(&InitInfo);
  212. LocalFree(pDSOPScopes);
  213. }
  214. else
  215. {
  216. hr = E_OUTOFMEMORY;
  217. }
  218. }
  219. return hr;
  220. }
  221. STDMETHODIMP CObjSecurity::InvokeDialog( HWND hwndParent, IDataObject **ppdoSelection )
  222. {
  223. HRESULT hr = E_UNEXPECTED;
  224. _ASSERT( ppdoSelection );
  225. if (m_pObjectPicker)
  226. hr = m_pObjectPicker->InvokeDialog(hwndParent, ppdoSelection);
  227. return hr;
  228. }
  229. /////////////////////////////////////////////////////////////////////////////////////////
  230. /////////////////////////////////////////////////////////////////////////////////////////
  231. // ISecurityInformation methods
  232. /////////////////////////////////////////////////////////////////////////////////////////
  233. /////////////////////////////////////////////////////////////////////////////////////////
  234. /////////////////////////////////////////////////////////////////////////////////////////
  235. STDMETHODIMP
  236. CObjSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
  237. {
  238. m_dwSIFlags = SI_EDIT_OWNER | SI_EDIT_PERMS | SI_NO_ACL_PROTECT | \
  239. SI_PAGE_TITLE;
  240. pObjectInfo->dwFlags = m_dwSIFlags;
  241. pObjectInfo->hInstance = g_hInstLib;
  242. pObjectInfo->pszServerName = NULL; //use local computer
  243. pObjectInfo->pszObjectName = m_bstrObject;
  244. pObjectInfo->pszPageTitle = m_bstrPage;
  245. return S_OK;
  246. }
  247. /////////////////////////////////////////////////////////////////////////////////////////
  248. STDMETHODIMP
  249. CObjSecurity::GetSecurity(SECURITY_INFORMATION si,
  250. PSECURITY_DESCRIPTOR *ppSD,
  251. BOOL fDefault)
  252. {
  253. HRESULT hr = S_OK;
  254. // Make the default if necessary...
  255. if ( !m_pConfProp->ConfInfo.m_pSecDesc )
  256. {
  257. hr = CoCreateInstance( CLSID_SecurityDescriptor,
  258. NULL,
  259. CLSCTX_INPROC_SERVER,
  260. IID_IADsSecurityDescriptor,
  261. (void **) &m_pConfProp->ConfInfo.m_pSecDesc );
  262. // Add default settings if successfully created the ACE
  263. if ( SUCCEEDED(hr) )
  264. hr = m_pConfProp->ConfInfo.AddDefaultACEs( m_pConfProp->ConfInfo.IsNewConference() );
  265. }
  266. // If we failed to get the defaults, just use whatever you can...
  267. if ( !m_pConfProp->ConfInfo.m_pSecDesc )
  268. {
  269. PSECURITY_DESCRIPTOR psdNewSD = LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH);
  270. //
  271. // Validate the allocation
  272. //
  273. if( psdNewSD == NULL )
  274. {
  275. hr = E_OUTOFMEMORY;
  276. }
  277. else
  278. {
  279. //
  280. // Allocation succeeded
  281. //
  282. if( !InitializeSecurityDescriptor(psdNewSD,SECURITY_DESCRIPTOR_REVISION) )
  283. {
  284. hr = GetLastError();
  285. }
  286. }
  287. *ppSD = psdNewSD;
  288. }
  289. else
  290. {
  291. DWORD dwSDLen = 0;
  292. ATLTRACE(_T(".1.CObjSecurity::GetSecurity() pre->Convert ticks = %ld.\n"), GetTickCount() );
  293. hr = ConvertObjectToSD( m_pConfProp->ConfInfo.m_pSecDesc, ppSD, &dwSDLen );
  294. ATLTRACE(_T(".1.CObjSecurity::GetSecurity() post Convert ticks = %ld.\n"), GetTickCount() );
  295. }
  296. return hr;
  297. }
  298. /////////////////////////////////////////////////////////////////////////////////////////
  299. STDMETHODIMP
  300. CObjSecurity::SetSecurity( SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD)
  301. {
  302. if ( !m_pConfProp ) return E_UNEXPECTED;
  303. HRESULT hr = S_OK;
  304. m_pConfProp->ConfInfo.SetSecuritySet( true );
  305. ///////////////////////////////////////////////////////////
  306. // If we don't have an existing SD, create one
  307. //
  308. if ( !m_pConfProp->ConfInfo.m_pSecDesc )
  309. {
  310. hr = CoCreateInstance( CLSID_SecurityDescriptor,
  311. NULL,
  312. CLSCTX_INPROC_SERVER,
  313. IID_IADsSecurityDescriptor,
  314. (void **) &m_pConfProp->ConfInfo.m_pSecDesc );
  315. // Failed te create the security descriptor object
  316. if ( FAILED(hr) ) return hr;
  317. }
  318. /////////////////////////////////////////////////////////////////////////////////
  319. // Set properties on the Security Descriptor
  320. //
  321. // Get control and revision information from SD
  322. DWORD dwRevision = 0;
  323. WORD wControl = 0;
  324. DWORD dwRet = GetSecurityDescriptorControl( pSD, &wControl, &dwRevision );
  325. if ( !dwRet ) return HRESULT_FROM_WIN32(GetLastError());
  326. hr = m_pConfProp->ConfInfo.m_pSecDesc->put_Control( wControl );
  327. BAIL_ON_FAILURE(hr);
  328. hr = m_pConfProp->ConfInfo.m_pSecDesc->put_Revision( dwRevision );
  329. BAIL_ON_FAILURE(hr);
  330. ////////////////////////////////////////////////
  331. // What was modified on the SD?
  332. if ( si & OWNER_SECURITY_INFORMATION )
  333. {
  334. BOOL bOwnerDefaulted = FALSE;
  335. LPBYTE pOwnerSidAddress = NULL;
  336. dwRet = GetSecurityDescriptorOwner( pSD, (PSID *) &pOwnerSidAddress, &bOwnerDefaulted );
  337. if ( dwRet )
  338. {
  339. LPWSTR pszOwner = NULL;
  340. if ( SUCCEEDED(hr = ConvertSidToFriendlyName(pOwnerSidAddress, &pszOwner)) )
  341. {
  342. if ( SUCCEEDED(hr = m_pConfProp->ConfInfo.m_pSecDesc->put_OwnerDefaulted((VARIANT_BOOL) bOwnerDefaulted)) )
  343. hr = m_pConfProp->ConfInfo.m_pSecDesc->put_Owner( pszOwner );
  344. }
  345. // Clean - up
  346. if ( pszOwner ) delete pszOwner;
  347. }
  348. else
  349. {
  350. hr = HRESULT_FROM_WIN32(GetLastError());
  351. }
  352. }
  353. ///////////////////////////////////////////////////////
  354. // Group security information changing...
  355. if ( si & GROUP_SECURITY_INFORMATION )
  356. {
  357. BOOL bGroupDefaulted = FALSE;
  358. LPBYTE pGroupSidAddress = NULL;
  359. dwRet = GetSecurityDescriptorGroup( pSD,
  360. (PSID *)&pGroupSidAddress,
  361. &bGroupDefaulted );
  362. if ( dwRet )
  363. {
  364. LPWSTR pszGroup = NULL;
  365. if ( SUCCEEDED(hr = ConvertSidToFriendlyName(pGroupSidAddress, &pszGroup)) )
  366. {
  367. if ( SUCCEEDED(hr = m_pConfProp->ConfInfo.m_pSecDesc->put_GroupDefaulted((VARIANT_BOOL) bGroupDefaulted)) )
  368. hr = m_pConfProp->ConfInfo.m_pSecDesc->put_Group( pszGroup );
  369. }
  370. // Clean - up
  371. if ( pszGroup ) delete pszGroup;
  372. }
  373. else
  374. {
  375. hr = HRESULT_FROM_WIN32(GetLastError());
  376. }
  377. }
  378. ///////////////////////////////////////////////
  379. // DACL list changing
  380. if ( si & DACL_SECURITY_INFORMATION )
  381. {
  382. LPBYTE pDACLAddress = NULL;
  383. BOOL bDaclPresent = FALSE, bDaclDefaulted = FALSE;
  384. VARIANT varDACL;
  385. VariantInit( &varDACL );
  386. // Extract DACL
  387. GetSecurityDescriptorDacl( pSD,
  388. &bDaclPresent,
  389. (PACL*) &pDACLAddress,
  390. &bDaclDefaulted );
  391. if ( bDaclPresent && pDACLAddress && SUCCEEDED(hr = ConvertACLToVariant((PACL) pDACLAddress, &varDACL)) )
  392. {
  393. if ( SUCCEEDED(hr = m_pConfProp->ConfInfo.m_pSecDesc->put_DaclDefaulted((VARIANT_BOOL) bDaclDefaulted)) )
  394. hr = m_pConfProp->ConfInfo.m_pSecDesc->put_DiscretionaryAcl( V_DISPATCH(&varDACL) );
  395. }
  396. // Clean - up
  397. VariantClear( &varDACL );
  398. }
  399. failed:
  400. return hr;
  401. }
  402. /////////////////////////////////////////////////////////////////////////////////////////
  403. STDMETHODIMP
  404. CObjSecurity::GetAccessRights(const GUID* /*pguidObjectType*/,
  405. DWORD dwFlags,
  406. PSI_ACCESS *ppAccesses,
  407. ULONG *pcAccesses,
  408. ULONG *piDefaultAccess)
  409. {
  410. *ppAccesses = g_siObjAccesses;
  411. *pcAccesses = sizeof(g_siObjAccesses)/sizeof(g_siObjAccesses[0]);
  412. *piDefaultAccess = g_iObjDefAccess;
  413. return S_OK;
  414. }
  415. /////////////////////////////////////////////////////////////////////////////////////////
  416. STDMETHODIMP
  417. CObjSecurity::MapGeneric(const GUID* /*pguidObjectType*/,
  418. UCHAR *pAceFlags,
  419. ACCESS_MASK *pmask)
  420. {
  421. MapGenericMask(pmask, &ObjMap);
  422. return S_OK;
  423. }
  424. /////////////////////////////////////////////////////////////////////////////////////////
  425. STDMETHODIMP
  426. CObjSecurity::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
  427. ULONG *pcInheritTypes)
  428. {
  429. *ppInheritTypes = g_siObjInheritTypes;
  430. *pcInheritTypes = sizeof(g_siObjInheritTypes)/sizeof(g_siObjInheritTypes[0]);
  431. return S_OK;
  432. }
  433. /////////////////////////////////////////////////////////////////////////////////////////
  434. STDMETHODIMP
  435. CObjSecurity::PropertySheetPageCallback(HWND hwnd,
  436. UINT uMsg,
  437. SI_PAGE_TYPE uPage)
  438. {
  439. return S_OK;
  440. }
  441. /////////////////////////////////////////////////////////////////////////////////////////
  442. /////////////////////////////////////////////////////////////////////////////////////////
  443. /////////////////////////////////////////////////////////////////////////////////////////