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.

640 lines
19 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. #include "precomp.h"
  3. #include <winioctl.h>
  4. #include "si.h"
  5. #include "resource.h"
  6. #include <cguid.h>
  7. #include <stdio.h>
  8. //-----------------------------------------------------------------------------
  9. CSecurityInformation::~CSecurityInformation()
  10. {
  11. }
  12. #define HINST_THISDLL _Module.GetModuleInstance()
  13. //-----------------------------------------------------------------------------
  14. HRESULT CSecurityInformation::PropertySheetPageCallback(HWND hwnd,
  15. UINT uMsg,
  16. SI_PAGE_TYPE uPage)
  17. {
  18. return S_OK;
  19. }
  20. //======================================================================
  21. //------------------- ISECURITYINFORMATION follows ---------------------------
  22. //EXTERN_C const GUID IID_ISecurityInformation =
  23. // { 0x965fc360, 0x16ff, 0x11d0, 0x91, 0xcb, 0x0, 0xaa, 0x0, 0xbb, 0xb7, 0x23 };
  24. #define WBEM_ENABLE ( 0x0001 )
  25. #define WBEM_METHOD_EXECUTE ( 0x0002 )
  26. #define WBEM_FULL_WRITE_REP ( 0x001c )
  27. #define WBEM_PARTIAL_WRITE_REP ( 0x0008 )
  28. #define WBEM_WRITE_PROVIDER ( 0x0010 )
  29. #define WBEM_REMOTE_ENABLE ( 0x0020 )
  30. #define WBEM_GENERAL_WRITE (WBEM_FULL_WRITE_REP|WBEM_PARTIAL_WRITE_REP|WBEM_WRITE_PROVIDER)
  31. #define WBEM_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
  32. SYNCHRONIZE |\
  33. WBEM_ENABLE |\
  34. WBEM_METHOD_EXECUTE |\
  35. WBEM_FULL_WRITE_REP |\
  36. WBEM_PARTIAL_WRITE_REP |\
  37. WBEM_WRITE_PROVIDER)
  38. #define WBEM_GENERIC_READ (STANDARD_RIGHTS_READ |\
  39. WBEM_ENABLE)
  40. #define WBEM_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\
  41. WBEM_FULL_WRITE_REP |\
  42. WBEM_PARTIAL_WRITE_REP |\
  43. WBEM_WRITE_PROVIDER)
  44. #define WBEM_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
  45. WBEM_METHOD_EXECUTE)
  46. // The following array defines the permission names for WMI.
  47. SI_ACCESS siWMIAccesses[] =
  48. {
  49. { &GUID_NULL, WBEM_METHOD_EXECUTE, MAKEINTRESOURCEW(IDS_WBEM_GENERIC_EXECUTE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  50. { &GUID_NULL, WBEM_FULL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_FULL_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  51. { &GUID_NULL, WBEM_PARTIAL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_PARTIAL_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  52. { &GUID_NULL, WBEM_WRITE_PROVIDER, MAKEINTRESOURCEW(IDS_WBEM_PROVIDER_WRITE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  53. { &GUID_NULL, WBEM_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_ENABLE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  54. { &GUID_NULL, WBEM_REMOTE_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_REMOTE_ENABLE), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  55. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCEW(IDS_WBEM_READ_SECURITY), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  56. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCEW(IDS_WBEM_EDIT_SECURITY), SI_ACCESS_GENERAL | SI_ACCESS_CONTAINER },
  57. { &GUID_NULL, 0, MAKEINTRESOURCEW(IDS_NONE), 0 }
  58. };
  59. #define iWMIDefAccess 4 // FILE_GENERAL_READ_EX
  60. SI_ACCESS siWMIAccessesAdvanced[] =
  61. {
  62. { &GUID_NULL, WBEM_METHOD_EXECUTE, MAKEINTRESOURCEW(IDS_WBEM_GENERIC_EXECUTE), SI_ACCESS_SPECIFIC },
  63. { &GUID_NULL, WBEM_FULL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_FULL_WRITE), SI_ACCESS_SPECIFIC },
  64. { &GUID_NULL, WBEM_PARTIAL_WRITE_REP, MAKEINTRESOURCEW(IDS_WBEM_PARTIAL_WRITE), SI_ACCESS_SPECIFIC },
  65. { &GUID_NULL, WBEM_WRITE_PROVIDER, MAKEINTRESOURCEW(IDS_WBEM_PROVIDER_WRITE), SI_ACCESS_SPECIFIC },
  66. { &GUID_NULL, WBEM_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_ENABLE), SI_ACCESS_SPECIFIC },
  67. { &GUID_NULL, WBEM_REMOTE_ENABLE, MAKEINTRESOURCEW(IDS_WBEM_REMOTE_ENABLE), SI_ACCESS_SPECIFIC },
  68. { &GUID_NULL, READ_CONTROL, MAKEINTRESOURCEW(IDS_WBEM_READ_SECURITY), SI_ACCESS_SPECIFIC },
  69. { &GUID_NULL, WRITE_DAC, MAKEINTRESOURCEW(IDS_WBEM_EDIT_SECURITY), SI_ACCESS_SPECIFIC },
  70. { &GUID_NULL, 0, MAKEINTRESOURCEW(IDS_NONE), 0 }
  71. };
  72. #define iWMIDefAccessAdvanced 4 // FILE_GENERAL_READ_EX
  73. SI_INHERIT_TYPE siWMIInheritTypes[] =
  74. {
  75. &GUID_NULL, 0, MAKEINTRESOURCEW(IDS_WBEM_NAMESPACE),
  76. &GUID_NULL, CONTAINER_INHERIT_ACE, MAKEINTRESOURCEW(IDS_WBEM_NAMESPACE_SUBNAMESPACE),
  77. &GUID_NULL, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE, MAKEINTRESOURCEW(IDS_WBEM_SUBNAMESPACE_ONLY),
  78. };
  79. GENERIC_MAPPING WMIMap =
  80. {
  81. WBEM_GENERIC_READ,
  82. WBEM_GENERIC_WRITE,
  83. WBEM_GENERIC_EXECUTE,
  84. WBEM_ALL_ACCESS
  85. };
  86. //---------------------------------------------------------------
  87. CSDSecurity::CSDSecurity(struct NSNODE *nsNode,
  88. _bstr_t server,
  89. bool local)
  90. : m_nsNode(nsNode),
  91. m_server(server),
  92. m_local(local),
  93. m_pSidOwner(NULL),
  94. m_pSidGroup(NULL)
  95. {
  96. }
  97. //------------------ Accessors to the above arrays---------------
  98. //---------------------------------------------------------------
  99. HRESULT CSDSecurity::MapGeneric(const GUID *pguidObjectType,
  100. UCHAR *pAceFlags,
  101. ACCESS_MASK *pMask)
  102. {
  103. *pAceFlags &= ~OBJECT_INHERIT_ACE;
  104. MapGenericMask(pMask, &WMIMap);
  105. return S_OK;
  106. }
  107. //-----------------------------------------------------------------------------
  108. HRESULT CSDSecurity::GetInheritTypes(PSI_INHERIT_TYPE *ppInheritTypes,
  109. ULONG *pcInheritTypes)
  110. {
  111. *ppInheritTypes = siWMIInheritTypes;
  112. *pcInheritTypes = ARRAYSIZE(siWMIInheritTypes);
  113. return S_OK;
  114. }
  115. //---------------------------------------------------
  116. LPWSTR CSDSecurity::CloneWideString(_bstr_t pszSrc )
  117. {
  118. LPWSTR pszDst = NULL;
  119. pszDst = new WCHAR[(lstrlen(pszSrc) + 1)];
  120. if (pszDst)
  121. {
  122. wcscpy( pszDst, pszSrc );
  123. }
  124. return pszDst;
  125. }
  126. //-----------------------------------------------------------------------------
  127. HRESULT CSDSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
  128. {
  129. // ATLASSERT(pObjectInfo != NULL &&
  130. // !IsBadWritePtr(pObjectInfo, sizeof(*pObjectInfo)));
  131. pObjectInfo->dwFlags = SI_EDIT_PERMS | /*SI_EDIT_OWNER |*/ // dacl, owner pages.
  132. SI_ADVANCED | SI_CONTAINER |
  133. SI_NO_TREE_APPLY | SI_NO_ACL_PROTECT;
  134. USES_CONVERSION;
  135. // NOTE: This weirdness is so nt4sp5+ can put up the
  136. // user browser for Add User.
  137. if(m_local)
  138. {
  139. pObjectInfo->pszServerName = NULL;
  140. }
  141. else
  142. {
  143. // NOTE: NT4 seems to want the "\\" and w2k doesn't care.
  144. bstr_t temp(_T("\\\\"));
  145. temp += m_server;
  146. pObjectInfo->pszServerName = CloneWideString(temp);
  147. }
  148. pObjectInfo->hInstance = HINST_THISDLL;
  149. pObjectInfo->pszObjectName = CloneWideString(m_nsNode->display);
  150. return S_OK;
  151. }
  152. //-----------------------------------------------------------------------------
  153. HRESULT CSDSecurity::GetAccessRights(const GUID *pguidObjectType,
  154. DWORD dwFlags,
  155. PSI_ACCESS *ppAccess,
  156. ULONG *pcAccesses,
  157. ULONG *piDefaultAccess)
  158. {
  159. // dwFlags is zero if the basic security page is being initialized,
  160. // Otherwise, it is a combination of the following values:
  161. // SI_ADVANCED - Advanced sheet is being initialized.
  162. // SI_EDIT_AUDITS - Advanced sheet includes the Audit property page.
  163. // SI_EDIT_PROPERTIES - Advanced sheet enables editing of ACEs that
  164. // apply to object's properties and property sets
  165. // We only currently support '0' or 'SI_ADVANCED'
  166. ATLASSERT(0 == dwFlags || SI_ADVANCED == dwFlags);
  167. if(0 == dwFlags)
  168. {
  169. *ppAccess = siWMIAccesses;
  170. *pcAccesses = ARRAYSIZE(siWMIAccesses);
  171. *piDefaultAccess = iWMIDefAccess;
  172. }
  173. else
  174. {
  175. *ppAccess = siWMIAccessesAdvanced;
  176. *pcAccesses = ARRAYSIZE(siWMIAccessesAdvanced);
  177. *piDefaultAccess = iWMIDefAccessAdvanced;
  178. }
  179. return S_OK;
  180. }
  181. //------------------ Real workers -------------------------------
  182. //---------------------------------------------------------------
  183. #define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
  184. #define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
  185. /* Commenting out since winbase.h makes one available for 0x0500 and above
  186. BOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR psd,
  187. SECURITY_DESCRIPTOR_CONTROL wControlMask,
  188. SECURITY_DESCRIPTOR_CONTROL wControlBits)
  189. {
  190. DWORD dwErr = NOERROR;
  191. PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)psd;
  192. if (pSD)
  193. pSD->Control = (pSD->Control & ~wControlMask) | wControlBits;
  194. else
  195. dwErr = ERROR_INVALID_PARAMETER;
  196. return dwErr;
  197. }
  198. */
  199. void CSDSecurity::ProtectACLs(SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR pSD)
  200. {
  201. SECURITY_DESCRIPTOR_CONTROL wSDControl;
  202. DWORD dwRevision;
  203. PACL pAcl;
  204. BOOL bDefaulted;
  205. BOOL bPresent;
  206. PACE_HEADER pAce;
  207. UINT cAces;
  208. if (0 == si || NULL == pSD)
  209. return; // Nothing to do
  210. // Get the ACL protection control bits
  211. GetSecurityDescriptorControl(pSD, &wSDControl, &dwRevision);
  212. wSDControl &= SE_DACL_PROTECTED | SE_SACL_PROTECTED;
  213. if ((si & DACL_SECURITY_INFORMATION) && !(wSDControl & SE_DACL_PROTECTED))
  214. {
  215. wSDControl |= SE_DACL_PROTECTED;
  216. pAcl = NULL;
  217. GetSecurityDescriptorDacl(pSD, &bPresent, &pAcl, &bDefaulted);
  218. // Theoretically, modifying the DACL in this way can cause it to be
  219. // no longer canonical. However, the only way this can happen is if
  220. // there is an inherited Deny ACE and a non-inherited Allow ACE.
  221. // Since this function is only called for root objects, this means
  222. // a) the server DACL must have a Deny ACE and b) the DACL on this
  223. // object must have been modified later. But if the DACL was
  224. // modified through the UI, then we would have eliminated all of the
  225. // Inherited ACEs already. Therefore, it must have been modified
  226. // through some other means. Considering that the DACL originally
  227. // inherited from the server never has a Deny ACE, this situation
  228. // should be extrememly rare. If it ever does happen, the ACL
  229. // Editor will just tell the user that the DACL is non-canonical.
  230. //
  231. // Therefore, let's ignore the possibility here.
  232. if (NULL != pAcl)
  233. {
  234. for (cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
  235. cAces > 0;
  236. --cAces, pAce = (PACE_HEADER)NextAce(pAce))
  237. {
  238. pAce->AceFlags &= ~INHERITED_ACE;
  239. }
  240. }
  241. }
  242. if ((si & SACL_SECURITY_INFORMATION) && !(wSDControl & SE_SACL_PROTECTED))
  243. {
  244. wSDControl |= SE_SACL_PROTECTED;
  245. pAcl = NULL;
  246. GetSecurityDescriptorSacl(pSD, &bPresent, &pAcl, &bDefaulted);
  247. if (NULL != pAcl)
  248. {
  249. for (cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
  250. cAces > 0;
  251. --cAces, pAce = (PACE_HEADER)NextAce(pAce))
  252. {
  253. pAce->AceFlags &= ~INHERITED_ACE;
  254. }
  255. }
  256. }
  257. SetSecurityDescriptorControl(pSD, SE_DACL_PROTECTED | SE_SACL_PROTECTED, wSDControl);
  258. }
  259. //---------------------------------------------------------------
  260. HRESULT CSDSecurity::GetSecurity(THIS_ SECURITY_INFORMATION RequestedInformation,
  261. PSECURITY_DESCRIPTOR *ppSecurityDescriptor,
  262. BOOL fDefault )
  263. {
  264. // ATLASSERT(ppSecurityDescriptor != NULL);
  265. HRESULT hr = E_FAIL;
  266. *ppSecurityDescriptor = NULL;
  267. if(fDefault)
  268. {
  269. ATLTRACE(_T("Default security descriptor not supported"));
  270. return E_NOTIMPL;
  271. }
  272. // does it want something?
  273. if(RequestedInformation != 0)
  274. {
  275. if(m_pSidOwner != NULL)
  276. {
  277. BYTE *p = (LPBYTE)m_pSidOwner;
  278. delete []p;
  279. m_pSidOwner = NULL;
  280. }
  281. if(m_pSidGroup != NULL)
  282. {
  283. BYTE *p = (LPBYTE)m_pSidGroup;
  284. delete []p;
  285. m_pSidGroup = NULL;
  286. }
  287. switch(m_nsNode->sType)
  288. {
  289. case TYPE_NAMESPACE:
  290. {
  291. CWbemClassObject _in;
  292. CWbemClassObject _out;
  293. hr = m_nsNode->ns->GetMethodSignatures("__SystemSecurity", "GetSD",
  294. _in, _out);
  295. if(SUCCEEDED(hr))
  296. {
  297. hr = m_nsNode->ns->ExecMethod("__SystemSecurity", "GetSD",
  298. _in, _out);
  299. if(SUCCEEDED(hr))
  300. {
  301. HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
  302. if(FAILED(hr1))
  303. {
  304. hr = hr1;
  305. }
  306. else
  307. {
  308. _out.GetBLOB("SD", (LPBYTE *)ppSecurityDescriptor);
  309. hr = InitializeOwnerandGroup(ppSecurityDescriptor);
  310. }
  311. }
  312. }
  313. break;
  314. }
  315. case TYPE_STATIC_INSTANCE:
  316. {
  317. m_nsNode->pclsObj->GetBLOB("__SD",(LPBYTE *)ppSecurityDescriptor);
  318. hr = InitializeOwnerandGroup(ppSecurityDescriptor);
  319. break;
  320. }
  321. }
  322. }
  323. else
  324. {
  325. *ppSecurityDescriptor = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  326. if(*ppSecurityDescriptor)
  327. InitializeSecurityDescriptor(*ppSecurityDescriptor,
  328. SECURITY_DESCRIPTOR_REVISION);
  329. else
  330. hr = E_OUTOFMEMORY;
  331. }
  332. //ProtectACLs(RequestedInformation, *ppSecurityDescriptor);
  333. return hr;
  334. }
  335. //-----------------------------------------------------------------------------
  336. #define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
  337. #define NextAce(Ace) ((PVOID)((PUCHAR)(Ace) + ((PACE_HEADER)(Ace))->AceSize))
  338. HRESULT CSDSecurity::SetSecurity(SECURITY_INFORMATION SecurityInformation,
  339. PSECURITY_DESCRIPTOR pSecurityDescriptor)
  340. {
  341. HRESULT hr = E_FAIL;
  342. // dont pass the SI_OWNER_RECURSE bit to wbem.
  343. // SecurityInformation &= ~(OWNER_SECURITY_INFORMATION | SI_OWNER_RECURSE);
  344. // if something was changed...
  345. if(SecurityInformation != 0)
  346. {
  347. // set the CONTAINER_INHERIT_ACE bit.
  348. if(SecurityInformation & DACL_SECURITY_INFORMATION)
  349. {
  350. PACL pAcl = NULL;
  351. BOOL bDefaulted;
  352. BOOL bPresent;
  353. PACE_HEADER pAce;
  354. UINT cAces;
  355. GetSecurityDescriptorDacl(pSecurityDescriptor, &bPresent, &pAcl, &bDefaulted);
  356. if(NULL != pAcl)
  357. {
  358. for(cAces = pAcl->AceCount, pAce = (PACE_HEADER)FirstAce(pAcl);
  359. cAces > 0;
  360. --cAces, pAce = (PACE_HEADER)NextAce(pAce))
  361. {
  362. // Make sure we don't get 'object inherit'
  363. // This happens when creating a new ace from advance page
  364. pAce->AceFlags &= ~OBJECT_INHERIT_ACE;
  365. }
  366. }
  367. }
  368. SECURITY_DESCRIPTOR *pSD = NULL;
  369. // ACLUI sends absolute format so change to self-relative so the
  370. // PutBLOB() has contiguous memory to copy.
  371. DWORD srLen = 0;
  372. SetLastError(0);
  373. BOOL bCheck;
  374. if(m_pSidOwner != NULL)
  375. {
  376. bCheck = SetSecurityDescriptorOwner(pSecurityDescriptor,m_pSidOwner,m_bOwnerDefaulted);
  377. if(bCheck == FALSE)
  378. {
  379. return E_FAIL;
  380. }
  381. }
  382. if(m_pSidGroup != NULL)
  383. {
  384. bCheck = SetSecurityDescriptorGroup(pSecurityDescriptor,m_pSidGroup,m_bGroupDefaulted);
  385. if(bCheck == FALSE)
  386. {
  387. return E_FAIL;
  388. }
  389. }
  390. // get the size needed.
  391. BOOL x1 = MakeSelfRelativeSD(pSecurityDescriptor, NULL, &srLen);
  392. DWORD eee = GetLastError();
  393. pSD = (SECURITY_DESCRIPTOR *)LocalAlloc(LPTR, srLen);
  394. if(pSD)
  395. {
  396. BOOL converted = MakeSelfRelativeSD(pSecurityDescriptor, pSD, &srLen);
  397. hr = S_OK;
  398. }
  399. else
  400. {
  401. hr = E_OUTOFMEMORY;
  402. return hr;
  403. }
  404. switch(m_nsNode->sType)
  405. {
  406. case TYPE_NAMESPACE:
  407. {
  408. CWbemClassObject _in;
  409. CWbemClassObject _out;
  410. hr = m_nsNode->ns->GetMethodSignatures("__SystemSecurity", "SetSD",
  411. _in, _out);
  412. if(SUCCEEDED(hr))
  413. {
  414. _in.PutBLOB("SD", (LPBYTE)pSD, GetSecurityDescriptorLength(pSD));
  415. hr = m_nsNode->ns->ExecMethod("__SystemSecurity", "SetSD",
  416. _in, _out);
  417. if(SUCCEEDED(hr))
  418. {
  419. HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
  420. if(FAILED(hr1))
  421. {
  422. hr = hr1;
  423. }
  424. }
  425. }
  426. // HACK: because of how the core caches/uses security, I have to close &
  427. // reopen my connection because GetSecurity() will be immediately called
  428. // to refresh the UI. If I dont do this, GetSecurity() will return to old
  429. // security settings even though they're really saved.
  430. m_nsNode->ns->DisconnectServer();
  431. CHString1 path;
  432. // if we've got a server, here - append it.
  433. if (((BSTR)m_server != NULL) && wcslen(m_server))
  434. path = CHString1("\\\\") + CHString1((BSTR)m_server) + CHString1("\\") + CHString1((BSTR)m_nsNode->fullPath);
  435. else
  436. path = m_nsNode->fullPath;
  437. m_nsNode->ns->ConnectServer(_bstr_t((const WCHAR*)path));
  438. break;
  439. }
  440. case TYPE_STATIC_INSTANCE:
  441. {
  442. m_nsNode->pclsObj->PutBLOB("__SD",(LPBYTE)pSD, GetSecurityDescriptorLength(pSD));
  443. //Now put the instance back
  444. hr = m_nsNode->ns->PutInstance(*(m_nsNode->pclsObj)/*,flag*/);
  445. delete m_nsNode->pclsObj;
  446. *(m_nsNode->pclsObj) = m_nsNode->ns->GetObject(m_nsNode->relPath/*,flag*/);
  447. break;
  448. }
  449. }
  450. if(m_pSidOwner != NULL)
  451. {
  452. BYTE *p = (LPBYTE)m_pSidOwner;
  453. delete []p;
  454. m_pSidOwner = NULL;
  455. }
  456. if(m_pSidGroup != NULL)
  457. {
  458. BYTE *p = (LPBYTE)m_pSidGroup;
  459. delete []p;
  460. m_pSidGroup = NULL;
  461. }
  462. }
  463. return hr;
  464. }
  465. HRESULT CSDSecurity::InitializeOwnerandGroup(PSECURITY_DESCRIPTOR *ppSecurityDescriptor)
  466. {
  467. SID *pSid;
  468. BOOL bDefaulted;
  469. BOOL bCheck = GetSecurityDescriptorOwner(*ppSecurityDescriptor,
  470. (void **)&pSid,&m_bOwnerDefaulted);
  471. if(bCheck == TRUE)
  472. {
  473. if (pSid != NULL)
  474. {
  475. m_nLengthOwner = GetSidLengthRequired(pSid->SubAuthorityCount);
  476. if(m_pSidOwner != NULL)
  477. {
  478. BYTE *p = (LPBYTE)m_pSidOwner;
  479. delete []p;
  480. m_pSidOwner = NULL;
  481. }
  482. m_pSidOwner = (SID *)new BYTE[m_nLengthOwner];
  483. if(m_pSidOwner == NULL ||
  484. CopySid(m_nLengthOwner,m_pSidOwner,pSid) == FALSE)
  485. {
  486. delete m_pSidOwner;
  487. m_pSidOwner = NULL;
  488. m_nLengthOwner = -1;
  489. return E_FAIL;
  490. }
  491. }
  492. else
  493. {
  494. m_pSidOwner = NULL;
  495. m_nLengthOwner = 0;
  496. }
  497. }
  498. else
  499. {
  500. m_pSidOwner = NULL;
  501. m_nLengthOwner = -1;
  502. return E_FAIL;
  503. }
  504. SID *pGroup;
  505. bCheck = GetSecurityDescriptorGroup(*ppSecurityDescriptor,
  506. (void **)&pGroup,&m_bGroupDefaulted);
  507. if(bCheck == TRUE)
  508. {
  509. if (pGroup != NULL)
  510. {
  511. m_nLengthGroup = GetSidLengthRequired(pGroup->SubAuthorityCount);
  512. if(m_pSidGroup != NULL)
  513. {
  514. BYTE *p = (LPBYTE)m_pSidGroup;
  515. delete []p;
  516. m_pSidGroup = NULL;
  517. }
  518. m_pSidGroup = (SID *)new BYTE[m_nLengthGroup];
  519. if(m_pSidGroup == NULL ||
  520. CopySid(m_nLengthGroup,m_pSidGroup,pGroup) == FALSE)
  521. {
  522. delete m_pSidGroup;
  523. m_pSidGroup = NULL;
  524. m_nLengthGroup = -1;
  525. return E_FAIL;
  526. }
  527. }
  528. else
  529. {
  530. m_pSidGroup = NULL;
  531. m_nLengthGroup = 0;
  532. }
  533. }
  534. else
  535. {
  536. m_pSidGroup = NULL;
  537. m_nLengthGroup = -1;
  538. return E_FAIL;
  539. }
  540. return S_OK;
  541. }