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.

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