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.

1590 lines
43 KiB

  1. /*Copyright (c) 1995-1998, Mission Critical Software, Inc. All rights reserved.
  2. ===============================================================================
  3. Module - SecureObject.cpp
  4. System - Domain Consolidation Toolkit.
  5. Author - Christy Boles
  6. Created - 97/06/27
  7. Description - Classes for objects that have security descriptors.
  8. TSecurableObject has a derived class for each type of object
  9. we will process security descriptors for. This class handles reading
  10. and writing the security descriptor. It contains a TSD object, which
  11. will handle manipulation of the SD while it is in memory.
  12. The TSecurableObject class also contains functions to translate a security
  13. descriptor, given an account mapping cache. These routines are only included
  14. in the class if the preprocessor directive SDRESOLVE is #defined. This allows
  15. the TSecurableObject class to be used for generic security descriptor manipulation,
  16. where the rest of the ACL translation code is not needed.
  17. Updates -
  18. ===============================================================================
  19. */
  20. #ifdef USE_STDAFX
  21. # include "stdafx.h"
  22. #else
  23. # include <windows.h>
  24. # include <process.h>
  25. #endif
  26. #include <stdio.h>
  27. #include <iostream.h>
  28. #include <assert.h>
  29. #include "common.hpp"
  30. #include "ErrDct.hpp"
  31. #include "Ustring.hpp"
  32. #include "sd.hpp"
  33. #include "SecObj.hpp"
  34. #ifdef SDRESOLVE
  35. #include "sidcache.hpp"
  36. #include "enumvols.hpp"
  37. #include "txtsid.h"
  38. #endif
  39. #define PRINT_BUFFER_SIZE 2000
  40. extern TErrorDct err;
  41. TSecurableObject::~TSecurableObject()
  42. {
  43. #ifdef SDRESOLVE
  44. TStatNode *node;
  45. for ( node = (TStatNode *)changelog.Head() ; node ; node = (TStatNode * )changelog.Head() )
  46. {
  47. changelog.Remove((TNode *)node);
  48. delete node;
  49. }
  50. #endif
  51. if ( handle != INVALID_HANDLE_VALUE )
  52. {
  53. CloseHandle(handle);
  54. handle = INVALID_HANDLE_VALUE;
  55. }
  56. if ( m_sd )
  57. {
  58. delete m_sd;
  59. }
  60. }
  61. #ifdef SDRESOLVE
  62. PACL // ret -pointer to Resolved ACL
  63. TSecurableObject::ResolveACL(
  64. PACL oldacl, // in -acl to resolve
  65. TAccountCache * cache, // in -cache to lookup sids
  66. TSDResolveStats * stat, // in -stats object
  67. bool * changes, // i/o-flag whether this SD has been modified
  68. BOOL verbose, // in -flag whether to display lots of junk
  69. int opType, // in - ADD_SECURITY, REPLACE_SECURITY, or REMOVE_SECURITY
  70. objectType objType, // in - the type of the object
  71. BOOL bUseMapFile // in - flag - whether we are using a sID mapping file
  72. )
  73. {
  74. int nAces,curr;
  75. TRidNode * tnode;
  76. PSID ps;
  77. bool aclchanges = false;
  78. PACL acl = oldacl;
  79. void * pAce;
  80. nAces = m_sd->ACLGetNumAces(acl);
  81. for ( curr = 0 ; curr < nAces; )
  82. {
  83. pAce = m_sd->ACLGetAce(acl,curr);
  84. if ( pAce )
  85. {
  86. TACE ace(pAce);
  87. ps = ace.GetSid();
  88. if (!bUseMapFile)
  89. tnode =(TRidNode *)cache->Lookup(ps);
  90. else
  91. tnode =(TRidNode *)((TSDRidCache*)cache)->LookupWODomain(ps);
  92. if ( ace.GetType() == SYSTEM_AUDIT_ACE_TYPE )
  93. {
  94. if ( stat )
  95. stat->IncrementSACEExamined();
  96. }
  97. else
  98. {
  99. if ( stat)
  100. stat->IncrementDACEExamined();
  101. }
  102. if ( tnode == NULL )
  103. {
  104. if ( ace.GetType() == SYSTEM_AUDIT_ACE_TYPE )
  105. {
  106. if ( stat )
  107. stat->IncrementSACENotSelected(this);
  108. }
  109. else
  110. {
  111. if ( stat)
  112. stat->IncrementDACENotSelected(this);
  113. }
  114. }
  115. // if ( (int)tnode == -1 ) // from Totally unknown
  116. if ( tnode == (TRidNode*)-1 ) // from Totally unknown
  117. {
  118. if ( ace.GetType() == SYSTEM_AUDIT_ACE_TYPE )
  119. {
  120. if ( stat )
  121. stat->IncrementSACEUnknown(this);
  122. }
  123. else
  124. {
  125. if ( stat)
  126. stat->IncrementDACEUnknown(this);
  127. }
  128. tnode = NULL;
  129. }
  130. if ( tnode )
  131. {
  132. if ( ace.GetType() == SYSTEM_AUDIT_ACE_TYPE )
  133. {
  134. if ( stat )
  135. stat->IncrementSACEChange(tnode,objType,this);
  136. }
  137. else
  138. {
  139. if ( stat)
  140. stat->IncrementDACEChange(tnode,objType,this);
  141. }
  142. }
  143. if ( tnode && ! tnode->IsValidOnTgt() )
  144. {
  145. if ( ace.GetType() == SYSTEM_AUDIT_ACE_TYPE )
  146. {
  147. if ( stat )
  148. stat->IncrementSACENoTarget(this);
  149. }
  150. else
  151. {
  152. if ( stat)
  153. stat->IncrementDACENoTarget(this);
  154. }
  155. }
  156. if ( tnode && tnode->IsValidOnTgt() )
  157. {
  158. if ( verbose )
  159. DisplaySid(ps,cache);
  160. if (!bUseMapFile)
  161. ps = cache->GetTgtSid(tnode);
  162. else
  163. ps = ((TSDRidCache*)cache)->GetTgtSidWODomain(tnode);
  164. switch ( opType )
  165. {
  166. case REPLACE_SECURITY:
  167. aclchanges = true;
  168. ace.SetSid(ps);
  169. curr++;
  170. break;
  171. case ADD_SECURITY:
  172. {
  173. TACE otherAce(ace.GetType(),ace.GetFlags(),ace.GetMask(),ps);
  174. PACL tempAcl = acl;
  175. // check to make sure we're not adding duplicates
  176. // check the next ace, to see if it matches the one we're about to add
  177. BOOL bOkToAdd = TRUE;
  178. // Check the ace where we are
  179. if ( EqualSid(otherAce.GetSid(),ace.GetSid()) )
  180. {
  181. bOkToAdd = FALSE;
  182. }
  183. // check the next ace, if any
  184. if ( curr+1 < nAces )
  185. {
  186. TACE nextAce(m_sd->ACLGetAce(acl,curr+1));
  187. if ( EqualSid(otherAce.GetSid(),nextAce.GetSid()) )
  188. {
  189. bOkToAdd = FALSE;
  190. }
  191. }
  192. // check the previous ace, if any
  193. if ( curr > 0 )
  194. {
  195. TACE prevAce(m_sd->ACLGetAce(acl,curr-1));
  196. if ( EqualSid(prevAce.GetSid(),otherAce.GetSid()) )
  197. {
  198. bOkToAdd = FALSE;
  199. }
  200. }
  201. if ( bOkToAdd )
  202. {
  203. m_sd->ACLAddAce(&acl,&otherAce,curr);
  204. if (acl)
  205. aclchanges = true;
  206. curr += 2;
  207. nAces++;
  208. }
  209. else
  210. {
  211. curr++;
  212. }
  213. if ( acl != tempAcl )
  214. {
  215. // we had to reallocate when we added the ace
  216. if ( tempAcl != oldacl )
  217. {
  218. // we had already reallocated once before -- free the intermediate acl
  219. free(tempAcl);
  220. }
  221. }
  222. }
  223. break;
  224. case REMOVE_SECURITY:
  225. aclchanges = true;
  226. m_sd->ACLDeleteAce(acl,curr);
  227. nAces--;
  228. break;
  229. }
  230. free(ps);
  231. }
  232. else
  233. {
  234. curr++;
  235. }
  236. }
  237. else
  238. {
  239. break;
  240. }
  241. }
  242. if ( ! aclchanges )
  243. {
  244. acl = NULL;
  245. }
  246. if ( aclchanges )
  247. {
  248. (*changes) = true;
  249. }
  250. return acl;
  251. }
  252. bool
  253. TSecurableObject::ResolveSD(
  254. SecurityTranslatorArgs * args, // in -translation settings
  255. TSDResolveStats * stat, // in -stats object to increment counters
  256. objectType objType, // in -is this file, dir or share
  257. TSecurableObject * Last // in -Last SD for cache comparison
  258. )
  259. {
  260. bool changes;
  261. bool iWillBeNewLast;
  262. if ( ! m_sd->m_absSD ) // Couldn't get SD for this object (or it doesn't have one).
  263. {
  264. return false;
  265. }
  266. MCSASSERT( m_sd && m_sd->IsValid() );
  267. if ( stat )
  268. stat->IncrementExamined(objType);
  269. if ( args->LogVerbose() )
  270. err.MsgWrite(0,DCT_MSG_EXAMINED_S,pathname);
  271. if ( ! Last || m_sd != Last->m_sd )
  272. {
  273. changes = ResolveSDInternal(args->Cache(),stat,args->LogVerbose(),args->TranslationMode(),objType,args->UsingMapFile());
  274. if ( changes )
  275. {
  276. if ( stat )
  277. {
  278. stat->IncrementChanged(objType);
  279. }
  280. if ( args->LogFileDetails() )
  281. err.MsgWrite(0,DCT_MSG_CHANGED_S,pathname);
  282. if ( args->LogMassive() )
  283. {
  284. err.DbgMsgWrite(0,L"BEFORE:************Security Descriptor for %ls*************",pathname);
  285. PermsPrint(pathname,objType);
  286. }
  287. if ( ! args->NoChange() )
  288. {
  289. if ( args->LogMassive() )
  290. {
  291. err.DbgMsgWrite(0,L"IN MEMORY:*********************************************",pathname);
  292. PrintSD(m_sd->m_absSD,pathname);
  293. }
  294. WriteSD();
  295. }
  296. if ( args->LogMassive() )
  297. {
  298. err.DbgMsgWrite(0,L"AFTER:************Security Descriptor for %ls*************",pathname);
  299. PermsPrint(pathname,objType);
  300. }
  301. }
  302. else
  303. {
  304. if ( args->LogMassive() )
  305. {
  306. err.DbgMsgWrite(0,L"UNCHANGED:************Security Descriptor for %ls*************",pathname);
  307. PermsPrint(pathname,objType);
  308. }
  309. }
  310. iWillBeNewLast = true;
  311. }
  312. else
  313. { // cache hit
  314. if ( stat )
  315. stat->IncrementLastFileChanges(Last,objType);
  316. iWillBeNewLast = false;
  317. if ( Last->Changed() )
  318. {
  319. Last->CopyAccessData(this);
  320. if ( args->LogFileDetails() )
  321. err.MsgWrite(0,DCT_MSG_CHANGED_S,pathname);
  322. if ( args->LogMassive() )
  323. {
  324. err.DbgMsgWrite(0,L"BEFORE:************Security Descriptor for %ls*************",pathname);
  325. PermsPrint(pathname,objType);
  326. }
  327. if ( ! args->NoChange() )
  328. Last->WriteSD();
  329. if ( args->LogFileDetails() )
  330. err.MsgWrite(0,DCT_MSG_CHANGED_S,pathname);
  331. if ( args->LogMassive() )
  332. {
  333. err.DbgMsgWrite(0,L"AFTER:************Security Descriptor for %ls*************",pathname);
  334. PermsPrint(pathname,objType);
  335. }
  336. }
  337. else
  338. {
  339. if ( args->LogMassive() )
  340. {
  341. err.DbgMsgWrite(0,L"UNCHANGED:************Security Descriptor for %ls*************",pathname);
  342. PermsPrint(pathname,objType);
  343. }
  344. }
  345. if ( stat )
  346. stat->IncrementCacheHit(objType);
  347. }
  348. return iWillBeNewLast;
  349. }
  350. bool // ret -true if changes made, otherwise false
  351. TSecurableObject::ResolveSDInternal(
  352. TAccountCache * cache, // in -cache to lookup sids
  353. TSDResolveStats * stat, // in -stats object
  354. BOOL verbose, // in -flag - whether to display stuff
  355. int opType, // in -operation type Add, Replace, or Remove
  356. objectType objType, // in - type of object
  357. BOOL bUseMapFile // in - flag - whether we are using a sID mapping file
  358. )
  359. {
  360. /* Examine each part of the SD, looking for SIDs in the cache */
  361. PSID ps;
  362. TRidNode * acct;
  363. bool changes = false;
  364. PACL pacl;
  365. PACL newacl;
  366. PSID newsid;
  367. MCSVERIFY(m_sd);
  368. // Process owner part of SD
  369. ps = m_sd->GetOwner();
  370. if ( ps )
  371. {
  372. if (!bUseMapFile)
  373. acct = (TRidNode *)cache->Lookup(ps); // See if owner SID is in the cache
  374. else
  375. acct = (TRidNode *)((TSDRidCache*)cache)->LookupWODomain(ps); // See if owner SID is in the cache
  376. if ( stat)
  377. stat->IncrementOwnerExamined();
  378. if (acct == NULL )
  379. {
  380. if ( stat )
  381. stat->IncrementOwnerNotSelected();
  382. }
  383. // else if ((int)acct == -1 )
  384. else if (acct == (TRidNode*)-1 )
  385. {
  386. if (stat)
  387. stat->IncrementOwnerUnknown();
  388. unkown = true;
  389. acct = NULL;
  390. }
  391. if ( acct && stat )
  392. {
  393. stat->IncrementOwnerChange(acct,objType,this);
  394. }
  395. if ( acct && acct->IsValidOnTgt() )
  396. {
  397. changes = true;
  398. if ( verbose )
  399. {
  400. err.DbgMsgWrite(0,L"Owner: ");
  401. DisplaySid(ps,cache);
  402. }
  403. owner_changed = true;
  404. if (!bUseMapFile)
  405. newsid = cache->GetTgtSid(acct);
  406. else
  407. newsid = ((TSDRidCache*)cache)->GetTgtSidWODomain(acct);
  408. m_sd->SetOwner(newsid);
  409. //free(newsid);
  410. }
  411. }
  412. // Process primary group part of SD
  413. ps = m_sd->GetGroup();
  414. if ( ps )
  415. {
  416. if (!bUseMapFile)
  417. acct = (TRidNode *)cache->Lookup(ps);
  418. else
  419. acct = (TRidNode *)((TSDRidCache*)cache)->LookupWODomain(ps);
  420. if ( stat)
  421. stat->IncrementGroupExamined();
  422. if (acct == NULL )
  423. {
  424. if ( stat )
  425. stat->IncrementGroupNotSelected();
  426. }
  427. // else if ((int)acct == -1 )
  428. else if (acct == (TRidNode*)-1 )
  429. {
  430. if (stat)
  431. stat->IncrementGroupUnknown();
  432. acct = NULL;
  433. unkgrp = true;
  434. }
  435. if ( acct && stat )
  436. {
  437. stat->IncrementGroupChange(acct,objType,this);
  438. }
  439. if ( acct && acct->IsValidOnTgt() )
  440. {
  441. changes = true;
  442. if ( verbose )
  443. {
  444. err.DbgMsgWrite(0,L"Group: ");
  445. DisplaySid(ps,cache);
  446. }
  447. group_changed = true;
  448. if (!bUseMapFile)
  449. newsid = cache->GetTgtSid(acct);
  450. else
  451. newsid = ((TSDRidCache*)cache)->GetTgtSidWODomain(acct);
  452. m_sd->SetGroup(newsid);
  453. //free(newsid);
  454. }
  455. }
  456. pacl = m_sd->GetDacl();
  457. if ( pacl && m_sd->IsDaclPresent() )
  458. {
  459. if ( stat )
  460. stat->IncrementDACLExamined();
  461. if ( verbose )
  462. err.DbgMsgWrite(0,L"DACL");
  463. if (!bUseMapFile)
  464. newacl = ResolveACL(pacl,cache,stat,&changes,verbose,opType,objType, FALSE);
  465. else
  466. newacl = ResolveACL(pacl,cache,stat,&changes,verbose,opType,objType, TRUE);
  467. if ( newacl )
  468. {
  469. m_sd->SetDacl(newacl,m_sd->IsDaclPresent());
  470. dacl_changed = true;
  471. if ( stat )
  472. stat->IncrementDACLChanged();
  473. }
  474. }
  475. pacl = NULL;
  476. pacl = m_sd->GetSacl();
  477. if ( pacl && m_sd->IsSaclPresent() )
  478. {
  479. if ( stat )
  480. stat->IncrementSACLExamined();
  481. if ( verbose )
  482. err.DbgMsgWrite(0,L"SACL");
  483. if (!bUseMapFile)
  484. newacl = ResolveACL(pacl,cache,stat,&changes,verbose,opType,objType, FALSE);
  485. else
  486. newacl = ResolveACL(pacl,cache,stat,&changes,verbose,opType,objType, TRUE);
  487. if ( newacl )
  488. {
  489. m_sd->SetSacl(newacl,m_sd->IsSaclPresent());
  490. sacl_changed = true;
  491. if ( stat )
  492. stat->IncrementSACLChanged();
  493. }
  494. }
  495. return changes;
  496. }
  497. #else
  498. WCHAR * // ret -machine-name prefix of pathname if pathname is a UNC path, otherwise returns NULL
  499. GetMachineName(
  500. const LPWSTR pathname // in -pathname from which to extract machine name
  501. )
  502. {
  503. int i;
  504. WCHAR * machinename = NULL;
  505. if ( pathname
  506. && pathname[0] == L'\\'
  507. && pathname[1] == L'\\'
  508. )
  509. {
  510. for ( i = 2 ; pathname[i] && pathname[i] != L'\\' ; i++ )
  511. ;
  512. machinename = new WCHAR[i+2];
  513. if (machinename)
  514. {
  515. UStrCpy(machinename,pathname,i+1);
  516. machinename[i] = 0;
  517. }
  518. }
  519. return machinename;
  520. }
  521. #endif
  522. void
  523. TSecurableObject::CopyAccessData(
  524. TSecurableObject * sourceFSD // in - sd from which to copy name & handle
  525. )
  526. {
  527. pathname[0] = 0;
  528. safecopy(pathname,sourceFSD->GetPathName());
  529. if ( handle != INVALID_HANDLE_VALUE )
  530. {
  531. CloseHandle(handle);
  532. }
  533. handle = sourceFSD->handle;
  534. sourceFSD->ResetHandle();
  535. }
  536. /************************************************TFileSD Implementation*************************/
  537. TFileSD::TFileSD(
  538. const LPWSTR path // in -pathname for this SD
  539. )
  540. {
  541. daceNS = 0;
  542. saceNS = 0;
  543. daceEx = 0;
  544. saceEx = 0;
  545. daceU = 0;
  546. saceU = 0;
  547. daceNT = 0;
  548. saceNT = 0;
  549. unkown = false;
  550. unkgrp = false;
  551. if ( path )
  552. {
  553. safecopy(pathname,path);
  554. }
  555. else
  556. {
  557. path[0] = 0;
  558. }
  559. handle = INVALID_HANDLE_VALUE;
  560. ReadSD(path);
  561. }
  562. TFileSD::~TFileSD()
  563. {
  564. if ( handle != INVALID_HANDLE_VALUE )
  565. {
  566. CloseHandle(handle);
  567. handle = INVALID_HANDLE_VALUE;
  568. }
  569. pathname[0]=0;
  570. }
  571. // writes the Absolute SD to the file "pathname"
  572. bool // ret -true iff successful
  573. TFileSD::WriteSD()
  574. {
  575. // DWORD rc = 0;
  576. bool error = false;
  577. SECURITY_DESCRIPTOR * sd = NULL;
  578. MCSVERIFY( m_sd && m_sd->IsValid() );
  579. if ( handle == INVALID_HANDLE_VALUE )
  580. {
  581. err.MsgWrite(ErrS,DCT_MSG_FST_WRITESD_INVALID);
  582. error = true;
  583. }
  584. SECURITY_INFORMATION si;
  585. if ( ! error )
  586. {
  587. si = 0;
  588. if ( m_sd->IsOwnerChanged() )
  589. si |= OWNER_SECURITY_INFORMATION;
  590. if ( m_sd->IsGroupChanged() )
  591. si |= GROUP_SECURITY_INFORMATION;
  592. if ( m_sd->IsDACLChanged() )
  593. si |= DACL_SECURITY_INFORMATION;
  594. if ( m_sd->IsSACLChanged() )
  595. si |= SACL_SECURITY_INFORMATION;
  596. sd = m_sd->MakeAbsSD();
  597. if (!sd)
  598. return false;
  599. if ( ! SetKernelObjectSecurity(handle, si, sd ) )
  600. {
  601. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_FILE_WRITESD_FAILED_SD,pathname,GetLastError());
  602. error = true;
  603. }
  604. m_sd->FreeAbsSD(sd);
  605. }
  606. return ! error;
  607. }
  608. bool // ret -pointer to SD, (or NULL if failure)
  609. TFileSD::ReadSD(
  610. const LPWSTR path // in -file to get SD from
  611. )
  612. {
  613. DWORD req;
  614. DWORD rc;
  615. // void * r = NULL;
  616. SECURITY_DESCRIPTOR * sd = NULL;
  617. bool error = false;
  618. WCHAR * longpath= NULL;
  619. if ( handle != INVALID_HANDLE_VALUE)
  620. {
  621. CloseHandle(handle);
  622. handle = INVALID_HANDLE_VALUE;
  623. }
  624. owner_changed = 0;
  625. group_changed = 0;
  626. dacl_changed = 0;
  627. sacl_changed = 0;
  628. if ( UStrLen(path) >= MAX_PATH && path[2] != L'?' )
  629. {
  630. longpath = new WCHAR[UStrLen(path) + 10];
  631. if (!longpath)
  632. return true;
  633. UStrCpy(longpath,L"\\\\?\\");
  634. UStrCpy(longpath + UStrLen(longpath),path);
  635. }
  636. else
  637. {
  638. longpath = path;
  639. }
  640. handle = CreateFileW(longpath,
  641. READ_CONTROL | ACCESS_SYSTEM_SECURITY | WRITE_OWNER |WRITE_DAC ,
  642. FILE_SHARE_READ | FILE_SHARE_WRITE,
  643. NULL,
  644. OPEN_EXISTING,
  645. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_BACKUP_SEMANTICS,
  646. 0);
  647. if ( handle == INVALID_HANDLE_VALUE )
  648. {
  649. rc = GetLastError();
  650. if ( rc == ERROR_SHARING_VIOLATION )
  651. {
  652. err.MsgWrite(ErrW, DCT_MSG_FST_FILE_IN_USE_S,path);
  653. }
  654. else
  655. {
  656. err.SysMsgWrite(ErrE, rc, DCT_MSG_FST_FILE_OPEN_FAILED_SD,longpath,rc);
  657. }
  658. error = true;
  659. }
  660. else
  661. {
  662. sd = (SECURITY_DESCRIPTOR *)malloc(SD_DEFAULT_SIZE);
  663. if (!sd)
  664. {
  665. if ( longpath != path )
  666. delete [] longpath;
  667. return true;
  668. }
  669. req = 0;
  670. if ( ! GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
  671. | DACL_SECURITY_INFORMATION
  672. | SACL_SECURITY_INFORMATION
  673. ,
  674. sd,
  675. SD_DEFAULT_SIZE,
  676. &req) )
  677. {
  678. if ( req <= SD_DEFAULT_SIZE )
  679. {
  680. err.SysMsgWrite(ErrE, GetLastError(), DCT_MSG_FST_GET_FILE_SECURITY_FAILED_SD,
  681. longpath, GetLastError());
  682. error = true;
  683. }
  684. else
  685. {
  686. free(sd);
  687. sd = (SECURITY_DESCRIPTOR *)malloc(req);
  688. if (!sd)
  689. {
  690. if ( longpath != path )
  691. delete [] longpath;
  692. return true;
  693. }
  694. if ( ! GetKernelObjectSecurity(handle,OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
  695. | DACL_SECURITY_INFORMATION
  696. | SACL_SECURITY_INFORMATION
  697. ,
  698. sd,
  699. req,
  700. &req) )
  701. {
  702. err.SysMsgWrite(ErrE, GetLastError(), DCT_MSG_FST_GET_FILE_SECURITY_FAILED_SD,
  703. longpath, GetLastError());
  704. error = true;
  705. }
  706. }
  707. }
  708. }
  709. if ( error && sd ) // free the space allocated
  710. {
  711. free(sd);
  712. sd = NULL;
  713. }
  714. if ( sd )
  715. {
  716. m_sd = new TSD(sd,McsFileSD,TRUE);
  717. if (!m_sd)
  718. error = true;
  719. }
  720. else
  721. {
  722. m_sd = NULL;
  723. }
  724. if (! error )
  725. {
  726. safecopy(pathname,longpath);
  727. }
  728. if ( longpath != path )
  729. delete [] longpath;
  730. return error;
  731. }
  732. //////////////////////////TShareSD implementation///////////////////////////////////////////////////////////
  733. TShareSD::TShareSD(
  734. const LPWSTR path // in -pathname for this SD
  735. )
  736. {
  737. daceNS = 0;
  738. saceNS = 0;
  739. daceEx = 0;
  740. saceEx = 0;
  741. daceU = 0;
  742. saceU = 0;
  743. daceNT = 0;
  744. saceNT = 0;
  745. unkown = false;
  746. unkgrp = false;
  747. shareInfo = NULL;
  748. if ( path )
  749. {
  750. safecopy(pathname,path);
  751. }
  752. else
  753. {
  754. path[0] = 0;
  755. }
  756. handle = INVALID_HANDLE_VALUE;
  757. ReadSD(path);
  758. }
  759. bool // ret-error=true
  760. TShareSD::ReadSD(
  761. const LPWSTR path // in -sharename
  762. )
  763. {
  764. DWORD rc;
  765. // void * r = NULL;
  766. SECURITY_DESCRIPTOR * sd = NULL;
  767. bool error = false;
  768. DWORD lenServerName = 0;
  769. if ( m_sd )
  770. {
  771. delete m_sd;
  772. }
  773. owner_changed = 0;
  774. group_changed = 0;
  775. dacl_changed = 0;
  776. sacl_changed = 0;
  777. serverName = GetMachineName(path);
  778. if ( serverName )
  779. lenServerName = UStrLen(serverName) + 1;
  780. safecopy(pathname,path + lenServerName);
  781. rc = NetShareGetInfo(serverName, pathname, 502, (LPBYTE *)&shareInfo);
  782. if ( rc )
  783. {
  784. err.SysMsgWrite(ErrE, rc, DCT_MSG_FST_GET_SHARE_SECURITY_FAILED_SD,
  785. path, rc);
  786. error = true;
  787. }
  788. else
  789. {
  790. sd = (SECURITY_DESCRIPTOR *)shareInfo->shi502_security_descriptor;
  791. if ( sd )
  792. {
  793. m_sd = new TSD(sd,McsShareSD,FALSE);
  794. if (!m_sd)
  795. error = true;
  796. }
  797. else
  798. {
  799. m_sd = NULL;
  800. }
  801. }
  802. return error;
  803. }
  804. bool // ret-error=true
  805. TShareSD::WriteSD()
  806. {
  807. bool error = false;
  808. DWORD rc = 0;
  809. DWORD parmErr = 0;
  810. SECURITY_DESCRIPTOR * pSD = NULL;
  811. // Build an absolute SD
  812. if ( m_sd )
  813. {
  814. pSD = m_sd->MakeAbsSD();
  815. if (!pSD)
  816. return false;
  817. shareInfo->shi502_security_descriptor = pSD;
  818. rc = NetShareSetInfo(serverName,pathname,502,(BYTE *)shareInfo,&parmErr);
  819. if ( rc )
  820. {
  821. err.SysMsgWrite(ErrE,rc,DCT_MSG_FST_SHARE_WRITESD_FAILED_SD,pathname,rc);
  822. }
  823. free(pSD);
  824. }
  825. else
  826. {
  827. MCSASSERT(FALSE); // SD does not exist
  828. }
  829. return error;
  830. }
  831. TRegSD::TRegSD(
  832. const LPWSTR path, // in -pathname for this SD
  833. HKEY hKey // in -handle for the registry key
  834. )
  835. {
  836. daceNS = 0;
  837. saceNS = 0;
  838. daceEx = 0;
  839. saceEx = 0;
  840. daceU = 0;
  841. saceU = 0;
  842. daceNT = 0;
  843. saceNT = 0;
  844. unkown = false;
  845. unkgrp = false;
  846. if ( path )
  847. {
  848. safecopy(pathname,path);
  849. }
  850. else
  851. {
  852. path[0] = 0;
  853. }
  854. m_hKey = hKey;
  855. ReadSD(m_hKey);
  856. }
  857. bool
  858. TRegSD::ReadSD(HKEY hKey)
  859. {
  860. DWORD rc = 0;
  861. DWORD lenBuffer = SD_DEFAULT_SIZE;
  862. SECURITY_DESCRIPTOR * sd = NULL;
  863. m_hKey = hKey;
  864. sd = (SECURITY_DESCRIPTOR *)malloc(SD_DEFAULT_SIZE);
  865. if (!sd)
  866. return false;
  867. rc = RegGetKeySecurity(hKey,OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
  868. | DACL_SECURITY_INFORMATION
  869. | SACL_SECURITY_INFORMATION,
  870. sd,&lenBuffer);
  871. if ( rc == ERROR_INSUFFICIENT_BUFFER )
  872. {
  873. free(sd);
  874. sd = (SECURITY_DESCRIPTOR *)malloc(lenBuffer);
  875. if (!sd)
  876. return false;
  877. rc = RegGetKeySecurity(hKey,OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
  878. | DACL_SECURITY_INFORMATION
  879. | SACL_SECURITY_INFORMATION,
  880. sd,&lenBuffer);
  881. }
  882. if ( rc )
  883. {
  884. free(sd);
  885. }
  886. else
  887. {
  888. m_sd = new TSD(sd,McsRegistrySD,TRUE);
  889. if (!m_sd)
  890. rc = ERROR_NOT_ENOUGH_MEMORY;
  891. }
  892. return ( rc == 0 );
  893. }
  894. bool
  895. TRegSD::WriteSD()
  896. {
  897. DWORD rc = 0;
  898. SECURITY_DESCRIPTOR * sd = NULL;
  899. MCSVERIFY( m_sd && m_sd->IsValid() );
  900. SECURITY_INFORMATION si;
  901. si = 0;
  902. if ( m_sd->IsOwnerChanged() )
  903. si |= OWNER_SECURITY_INFORMATION;
  904. if ( m_sd->IsGroupChanged() )
  905. si |= GROUP_SECURITY_INFORMATION;
  906. if ( m_sd->IsDACLChanged() )
  907. si |= DACL_SECURITY_INFORMATION;
  908. if ( m_sd->IsSACLChanged() )
  909. si |= SACL_SECURITY_INFORMATION;
  910. sd = m_sd->MakeAbsSD();
  911. if (!sd)
  912. return false;
  913. rc = RegSetKeySecurity(m_hKey,si,sd);
  914. if ( rc )
  915. {
  916. err.SysMsgWrite(ErrE,rc,DCT_MSG_REG_SD_WRITE_FAILED_SD,name,rc);
  917. }
  918. m_sd->FreeAbsSD(sd);
  919. return ( rc == 0 );
  920. }
  921. //////////////////////////TPrintSD implementation///////////////////////////////////////////////////////////
  922. TPrintSD::TPrintSD(
  923. const LPWSTR path // in -pathname for this SD
  924. )
  925. {
  926. daceNS = 0;
  927. saceNS = 0;
  928. daceEx = 0;
  929. saceEx = 0;
  930. daceU = 0;
  931. saceU = 0;
  932. daceNT = 0;
  933. saceNT = 0;
  934. unkown = false;
  935. unkgrp = false;
  936. buffer = NULL;
  937. if ( path )
  938. {
  939. safecopy(pathname,path);
  940. }
  941. else
  942. {
  943. path[0] = 0;
  944. }
  945. handle = INVALID_HANDLE_VALUE;
  946. ReadSD(path);
  947. }
  948. bool // ret-error=true
  949. TPrintSD::ReadSD(
  950. const LPWSTR path // in -sharename
  951. )
  952. {
  953. DWORD rc = 0;
  954. SECURITY_DESCRIPTOR * sd = NULL;
  955. if ( m_sd )
  956. {
  957. delete m_sd;
  958. }
  959. owner_changed = 0;
  960. group_changed = 0;
  961. dacl_changed = 0;
  962. sacl_changed = 0;
  963. PRINTER_DEFAULTS defaults;
  964. DWORD needed = 0;
  965. PRINTER_INFO_3 * pInfo;
  966. defaults.DesiredAccess = READ_CONTROL | PRINTER_ACCESS_ADMINISTER | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY;
  967. defaults.pDatatype = NULL;
  968. defaults.pDevMode = NULL;
  969. buffer = new BYTE[PRINT_BUFFER_SIZE];
  970. if (!buffer)
  971. return false;
  972. // Get the security descriptor for the printer
  973. if ( ! OpenPrinter(path,&hPrinter,&defaults) )
  974. {
  975. rc = GetLastError();
  976. err.SysMsgWrite(ErrE,rc,DCT_MSG_OPEN_PRINTER_FAILED_SD,path,rc);
  977. }
  978. else
  979. {
  980. if ( ! GetPrinter(hPrinter,3,buffer,PRINT_BUFFER_SIZE,&needed) )
  981. {
  982. rc = GetLastError();
  983. if ( rc == ERROR_INSUFFICIENT_BUFFER )
  984. {
  985. delete [] buffer;
  986. buffer = new BYTE[needed];
  987. if (!buffer)
  988. rc = ERROR_NOT_ENOUGH_MEMORY;
  989. else if (! GetPrinter(hPrinter,3,buffer, needed, &needed ) )
  990. {
  991. rc = GetLastError();
  992. }
  993. }
  994. }
  995. if ( rc )
  996. {
  997. err.SysMsgWrite(ErrE,rc,DCT_MSG_GET_PRINTER_FAILED_SD,path,rc);
  998. }
  999. else
  1000. {
  1001. pInfo = (PRINTER_INFO_3*)buffer;
  1002. sd = (SECURITY_DESCRIPTOR *)pInfo->pSecurityDescriptor;
  1003. if ( sd )
  1004. {
  1005. m_sd = new TSD(sd,McsPrinterSD,FALSE);
  1006. if (!m_sd)
  1007. rc = ERROR_NOT_ENOUGH_MEMORY;
  1008. }
  1009. else
  1010. {
  1011. m_sd = NULL;
  1012. }
  1013. }
  1014. }
  1015. return (rc == 0);
  1016. }
  1017. bool // ret-error=true
  1018. TPrintSD::WriteSD()
  1019. {
  1020. // bool error = false;
  1021. DWORD rc = 0;
  1022. SECURITY_DESCRIPTOR * pSD = NULL;
  1023. PRINTER_INFO_3 pInfo;
  1024. // Build an absolute SD
  1025. MCSVERIFY(hPrinter != INVALID_HANDLE_VALUE);
  1026. if ( m_sd )
  1027. {
  1028. pSD = m_sd->MakeAbsSD();
  1029. if (!pSD)
  1030. return false;
  1031. pInfo.pSecurityDescriptor = pSD;
  1032. SetLastError(0);
  1033. // Clear the primary group from the security descriptor, since in NT 4, setting a security descriptor
  1034. // with a non-NULL primary group sometimes doesn't work
  1035. SetSecurityDescriptorGroup(pSD,NULL,FALSE);
  1036. if (! SetPrinter(hPrinter,3,(LPBYTE)&pInfo,0) )
  1037. {
  1038. rc = GetLastError();
  1039. }
  1040. if ( rc )
  1041. {
  1042. err.SysMsgWrite(ErrE,rc,DCT_MSG_PRINTER_WRITESD_FAILED_SD,pathname,rc);
  1043. }
  1044. free(pSD);
  1045. }
  1046. else
  1047. {
  1048. MCSASSERT(FALSE); // SD does not exist
  1049. }
  1050. return (rc == 0);
  1051. }
  1052. #ifdef SDRESOLVE
  1053. /////////////////////////////////////////////////Utility routines to print security descriptors for debug logging
  1054. //#pragma title("PrintSD- Formats/prints security info")
  1055. // Author - Tom Bernhardt
  1056. // Created- 09/11/93
  1057. #include <stdlib.h>
  1058. #include <stdio.h>
  1059. #include <string.h>
  1060. #include <windows.h>
  1061. #include <malloc.h>
  1062. #include <winbase.h>
  1063. #include <lm.h>
  1064. #include "common.hpp"
  1065. #include "err.hpp"
  1066. #include "Ustring.hpp"
  1067. #define SDBUFFSIZE (sizeof (SECURITY_DESCRIPTOR) + 10000)
  1068. static const char sidType[][16]= {"--0--" , "User" ,
  1069. "Group" , "Domain" ,
  1070. "Alias" , "WellKnownGroup",
  1071. "Deleted", "Invalid" ,
  1072. "Unknown"};
  1073. class SidTree
  1074. {
  1075. public:
  1076. SidTree * left;
  1077. SidTree * right;
  1078. SID_NAME_USE sidUse;
  1079. USHORT lenSid;
  1080. char buffer[1]; // contains sid, account name and domain
  1081. SidTree() {};
  1082. SidTree * // ret-found/created node
  1083. Find(
  1084. SidTree ** sidTree ,// i/o-head of extension tree
  1085. PSID const pSid // in -file extension
  1086. );
  1087. };
  1088. static char *
  1089. AclType(
  1090. BOOL isPresent ,// in -1 if present
  1091. BOOL isDefault // in -1 if default ACL
  1092. )
  1093. {
  1094. if ( !isPresent )
  1095. return "none";
  1096. if ( isDefault )
  1097. return "default";
  1098. return "present";
  1099. }
  1100. //#pragma page()
  1101. // For each "on" bit in the bitmap, appends the corresponding char in
  1102. // mapStr to retStr, thus forming a recognizable form of the bit string.
  1103. static
  1104. int _stdcall // ret-legngth of string written
  1105. BitMapStr(
  1106. DWORD bitmap ,// in -bits to map
  1107. char const * mapStr ,// in -map character array string
  1108. char * retStr // out-return selected map char string
  1109. )
  1110. {
  1111. char const * m;
  1112. char * r = retStr;
  1113. for ( m = mapStr; *m; m++, bitmap >>= 1 )
  1114. if ( bitmap & 1 ) // if current permission on
  1115. *r++ = *m; // set output string to corresponding char
  1116. *r = '\0';
  1117. return (int)(r - retStr);
  1118. }
  1119. //#pragma page()
  1120. // converts an ACE access mask to a semi-undertandable string
  1121. static
  1122. char * _stdcall
  1123. PermStr(
  1124. DWORD access ,// in -access mask
  1125. char * retStr // out-return permissions string
  1126. )
  1127. {
  1128. // static char const fileSpecific[] = "R W WaErEwX . ArAw";
  1129. // static char const dirSpecific[] = "L C M ErEwT D ArAw";
  1130. static char const specific[] = "RWbeEXDaA.......",
  1131. standard[] = "DpPOs...",
  1132. generic[] = "SM..AXWR";
  1133. char * o = retStr;
  1134. if ( (access & FILE_ALL_ACCESS) == FILE_ALL_ACCESS )
  1135. *o++ = '*';
  1136. else
  1137. o += BitMapStr(access, specific, o);
  1138. access >>= 16;
  1139. *o++ = '-';
  1140. if ( (access & (STANDARD_RIGHTS_ALL >> 16)) == (STANDARD_RIGHTS_ALL >> 16) )
  1141. *o++ = '*';
  1142. else
  1143. o += BitMapStr(access, standard, o);
  1144. access >>= 8;
  1145. if ( access )
  1146. {
  1147. *o++ = '-';
  1148. o += BitMapStr(access, generic, o);
  1149. }
  1150. *o = '\0'; // null terminate string
  1151. return retStr;
  1152. }
  1153. //#pragma page()
  1154. // Binary tree insertion/searching of Sids that obviates the constant
  1155. // use of LookupAccount and speeds execution by 100x!!!!!
  1156. SidTree * // ret-found/created node
  1157. SidTree::Find(
  1158. SidTree ** sidTree ,// i/o-head of extension tree
  1159. PSID const pSid // in -file extension
  1160. )
  1161. {
  1162. SidTree * curr,
  1163. ** prevNext = sidTree; // &forward-chain
  1164. int cmp; // compare result
  1165. DWORD lenSid;
  1166. WCHAR name[60],
  1167. domain[60];
  1168. DWORD lenName,
  1169. lenDomain,
  1170. rc;
  1171. SID_NAME_USE sidUse;
  1172. static int nUnknown = 0;
  1173. for ( curr = *prevNext; curr; curr = *prevNext )
  1174. {
  1175. if ( (cmp = memcmp(pSid, curr->buffer, curr->lenSid)) < 0 )
  1176. prevNext = &curr->left; // go down left side
  1177. else if ( cmp > 0 )
  1178. prevNext = &curr->right; // go down right side
  1179. else
  1180. return curr; // found it and return address
  1181. }
  1182. // not found in tree -- create it
  1183. lenName = DIM(name);
  1184. lenDomain = DIM(domain);
  1185. if ( !LookupAccountSid(NULL, pSid, name, &lenName,
  1186. domain, &lenDomain, &sidUse) )
  1187. {
  1188. rc = GetLastError();
  1189. if ( rc != ERROR_NONE_MAPPED )
  1190. err.DbgMsgWrite(0, L"LookupAccountSid()=%ld", rc);
  1191. lenName = swprintf(name, L"**Unknown%d**", ++nUnknown);
  1192. UStrCpy(domain, "-unknown-");
  1193. lenDomain = 9;
  1194. sidUse = (_SID_NAME_USE)0;
  1195. }
  1196. lenSid = GetLengthSid(pSid);
  1197. *prevNext = (SidTree *)malloc(sizeof **prevNext + lenSid + lenName + lenDomain + 1);
  1198. if (!(*prevNext))
  1199. return NULL;
  1200. memset(*prevNext, '\0', sizeof **prevNext);
  1201. memcpy((*prevNext)->buffer, pSid, lenSid);
  1202. (*prevNext)->lenSid = (USHORT)lenSid;
  1203. (*prevNext)->sidUse = sidUse;
  1204. UStrCpy((*prevNext)->buffer + lenSid, name, lenName + 1);
  1205. UStrCpy((*prevNext)->buffer + lenSid + lenName + 1, domain, lenDomain + 1);
  1206. return *prevNext;
  1207. }
  1208. //#pragma page()
  1209. SidTree gSidTree;
  1210. SidTree * sidHead = &gSidTree;
  1211. SECURITY_DESCRIPTOR * sd = NULL;
  1212. // Formats and prints (to stdout) the contents of the argment ACL
  1213. static
  1214. void _stdcall
  1215. PrintACL(
  1216. const PACL acl ,// in -ACL (SACL or DACL)
  1217. WCHAR const * resource // in -resource name
  1218. )
  1219. {
  1220. ACCESS_ALLOWED_ACE * ace;
  1221. DWORD nAce;
  1222. static char const typeStr[] = "+-A*";
  1223. SidTree * sidTree;
  1224. char permStr[33],
  1225. inherStr[5];
  1226. WCHAR txtSid[200];
  1227. char sTxtSid[200];
  1228. DWORD txtSidLen = DIM(txtSid);
  1229. err.DbgMsgWrite(0,L" T Fl Acc Mask Permissions Account name "
  1230. L"Domain Acct Type");
  1231. for ( nAce = 0; nAce < acl->AceCount; nAce++ )
  1232. {
  1233. if ( !GetAce(acl, nAce, (LPVOID *)&ace) )
  1234. {
  1235. err.DbgMsgWrite(0,L"GetAclInformation()=%ld ", GetLastError());
  1236. return;
  1237. }
  1238. sidTree = sidHead->Find(&sidHead, &ace->SidStart);
  1239. BitMapStr(ace->Header.AceFlags, "FDNI", inherStr);
  1240. txtSid[0] = 0;
  1241. txtSidLen = DIM(txtSid);
  1242. GetTextualSid(&ace->SidStart,txtSid,&txtSidLen);
  1243. safecopy(sTxtSid,txtSid);
  1244. err.DbgMsgWrite(0,L" %c%-3S %08x %-16S %-16S %-14S %S",
  1245. typeStr[ace->Header.AceType],
  1246. inherStr,
  1247. ace->Mask,
  1248. PermStr(ace->Mask, permStr),
  1249. (*(sidTree->buffer + sidTree->lenSid)) ? (sidTree->buffer + sidTree->lenSid) : sTxtSid,
  1250. sidTree->buffer + sidTree->lenSid + strlen(sidTree->buffer + sidTree->lenSid) + 1,
  1251. sidType[sidTree->sidUse]);
  1252. }
  1253. }
  1254. SECURITY_DESCRIPTOR *
  1255. GetSD(
  1256. WCHAR * path
  1257. )
  1258. { //added by christy
  1259. //this does the same stuff as
  1260. // PermsPrint, but doesn't print
  1261. DWORD req;
  1262. HANDLE hSrc;
  1263. DWORD rc = 0;
  1264. // void * r = NULL;
  1265. // WIN32_STREAM_ID * s = (WIN32_STREAM_ID *)copyBuffer;
  1266. char static const * streamName[] = {"Err", "Data", "EA", "Security", "Alternate", "Link", "Err6"};
  1267. hSrc = CreateFile(path,
  1268. GENERIC_READ |ACCESS_SYSTEM_SECURITY,
  1269. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1270. NULL,
  1271. OPEN_EXISTING,
  1272. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_BACKUP_SEMANTICS,
  1273. 0);
  1274. if ( hSrc == INVALID_HANDLE_VALUE )
  1275. {
  1276. rc = GetLastError();
  1277. if ( rc == ERROR_SHARING_VIOLATION )
  1278. err.DbgMsgWrite(ErrE, L"Source file in use %S", path );
  1279. else
  1280. err.DbgMsgWrite(ErrS,L"OpenR(%S) ", path);
  1281. return NULL;
  1282. }
  1283. if ( ! GetKernelObjectSecurity(hSrc, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
  1284. | DACL_SECURITY_INFORMATION
  1285. | SACL_SECURITY_INFORMATION
  1286. ,
  1287. sd,
  1288. SDBUFFSIZE,
  1289. &req) )
  1290. {
  1291. err.DbgMsgWrite(0, L"GetKernelObjectSecurity(%S)=%ld req=%ld ",
  1292. path, GetLastError(),req);
  1293. return NULL;
  1294. }
  1295. CloseHandle(hSrc);
  1296. return sd;
  1297. }
  1298. //#pragma page()
  1299. // Gets the security descriptors for a resource (path), format the owner
  1300. // information, gets the ACL and SACL and prints them.
  1301. DWORD
  1302. PermsPrint(
  1303. WCHAR * path, // in -iterate directory paths
  1304. objectType objType // in -type of the object
  1305. )
  1306. {
  1307. TFileSD fsd(path);
  1308. TShareSD ssd(path);
  1309. TPrintSD psd(path);
  1310. TRegSD rsd(path,NULL);
  1311. SECURITY_DESCRIPTOR const* pSD = NULL;
  1312. switch ( objType )
  1313. {
  1314. case file:
  1315. case directory:
  1316. fsd.ReadSD(path);
  1317. if ( fsd.GetSecurity() )
  1318. {
  1319. pSD = fsd.GetSecurity()->GetSD();
  1320. }
  1321. break;
  1322. case printer:
  1323. psd.ReadSD(path);
  1324. if ( psd.GetSecurity() )
  1325. {
  1326. pSD = psd.GetSecurity()->GetSD();
  1327. }
  1328. break;
  1329. case share:
  1330. ssd.ReadSD(path);
  1331. if ( ssd.GetSecurity() )
  1332. {
  1333. pSD = ssd.GetSecurity()->GetSD();
  1334. }
  1335. break;
  1336. case regkey:
  1337. rsd.ReadSD(path);
  1338. if ( rsd.GetSecurity() )
  1339. {
  1340. pSD = rsd.GetSecurity()->GetSD();
  1341. }
  1342. break;
  1343. default:
  1344. break;
  1345. }
  1346. if ( pSD )
  1347. {
  1348. PrintSD(const_cast<SECURITY_DESCRIPTOR*>(pSD),path);
  1349. }
  1350. else
  1351. {
  1352. err.DbgMsgWrite(0,L"Couldn't load Security descriptor for %ls",path);
  1353. }
  1354. return 0;
  1355. }
  1356. DWORD PrintSD(SECURITY_DESCRIPTOR * sd,WCHAR const * path)
  1357. {
  1358. BOOL isPresent,
  1359. isDefault;
  1360. PACL dacl;
  1361. PACL sacl;
  1362. PSID pSidOwner;
  1363. SidTree * sidTree = &gSidTree;
  1364. // DWORD rc = 0;
  1365. if ( !GetSecurityDescriptorOwner(sd, &pSidOwner, &isDefault) )
  1366. {
  1367. err.DbgMsgWrite(0,L"GetSecurityDescriptorOwner()=%ld ", GetLastError());
  1368. return 1;
  1369. }
  1370. err.DbgMsgWrite(0,L"%s",path);
  1371. if ( pSidOwner )
  1372. {
  1373. sidTree = sidHead->Find(&sidHead, pSidOwner);
  1374. if (sidTree)
  1375. {
  1376. err.DbgMsgWrite(0,L"owner=%S\\%S, type=%S, ",
  1377. //path,
  1378. sidTree->buffer + sidTree->lenSid + strlen(sidTree->buffer + sidTree->lenSid) + 1,
  1379. sidTree->buffer + sidTree->lenSid,
  1380. sidType[sidTree->sidUse]);
  1381. }
  1382. }
  1383. else
  1384. {
  1385. err.DbgMsgWrite(0,L"owner=NULL");
  1386. }
  1387. if ( !GetSecurityDescriptorDacl(sd, &isPresent, &dacl, &isDefault) )
  1388. {
  1389. err.DbgMsgWrite(0, L"GetSecurityDescriptorDacl()=%ld ", GetLastError());
  1390. return 1;
  1391. }
  1392. err.DbgMsgWrite(0,L" DACL=%S", AclType(isPresent, isDefault) );
  1393. if ( dacl )
  1394. PrintACL(dacl, path);
  1395. if ( !GetSecurityDescriptorSacl(sd, &isPresent, &sacl, &isDefault) )
  1396. {
  1397. err.DbgMsgWrite(0, L"GetSecurityDescriptorSacl()=%ld ", GetLastError());
  1398. return 1;
  1399. }
  1400. if ( isPresent )
  1401. {
  1402. err.DbgMsgWrite(0,L" SACL %S", AclType(isPresent, isDefault) );
  1403. if (!sacl)
  1404. {
  1405. err.DbgMsgWrite(0,L"SACL is empty.");
  1406. }
  1407. else PrintACL(sacl, path);
  1408. }
  1409. return 0;
  1410. }
  1411. #endif