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.

817 lines
21 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*************************************************************************
  3. *
  4. * acl.c
  5. *
  6. * Generic routines to manage ACL's
  7. *
  8. * Author: John Richardson 04/25/97
  9. *
  10. *
  11. *************************************************************************/
  12. /*
  13. * Includes
  14. */
  15. #include "stdafx.h"
  16. /*
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. */
  21. #include <windows.h>
  22. #include <rpc.h>
  23. #include <stdio.h>
  24. #include <process.h>
  25. #include <lmaccess.h>
  26. #include <lmapibuf.h>
  27. #include <lmerr.h>
  28. #undef DBG
  29. #define DBG 1
  30. #define DBGTRACE 1
  31. #define DbgPrint(x)
  32. #if DBG
  33. //ULONG
  34. //DbgPrint(
  35. // PCH Format,
  36. // ...
  37. // );
  38. #define DBGPRINT(x) DbgPrint(x)
  39. #if DBGTRACE
  40. #define TRACE0(x) DbgPrint x
  41. #define TRACE1(x) DbgPrint x
  42. #else
  43. #define TRACE0(x)
  44. #define TRACE1(x)
  45. #endif
  46. #else
  47. #define DBGPRINT(x)
  48. #define TRACE0(x)
  49. #define TRACE1(x)
  50. #endif
  51. /*
  52. * Forward references
  53. */
  54. BOOL
  55. xxxLookupAccountName(
  56. PWCHAR pSystemName,
  57. PWCHAR pAccountName,
  58. PSID *ppSid
  59. );
  60. BOOL
  61. SelfRelativeToAbsoluteSD(
  62. PSECURITY_DESCRIPTOR SecurityDescriptorIn,
  63. PSECURITY_DESCRIPTOR *SecurityDescriptorOut,
  64. PULONG ReturnedLength
  65. );
  66. /*****************************************************************************
  67. *
  68. * AddTerminalServerUserToSD
  69. *
  70. * Add the given user for the given domain to the security descriptor.
  71. * The callers security descriptor may be re-allocated.
  72. *
  73. * ENTRY:
  74. * Param1 (input/output)
  75. * Comments
  76. *
  77. * EXIT:
  78. * STATUS_SUCCESS - no error
  79. *
  80. ****************************************************************************/
  81. BOOL
  82. AddTerminalServerUserToSD(
  83. PSECURITY_DESCRIPTOR *ppSd,
  84. DWORD NewAccess,
  85. PACL *ppDacl
  86. )
  87. {
  88. ULONG i;
  89. BOOL Result;
  90. BOOL DaclPresent;
  91. BOOL DaclDefaulted;
  92. DWORD Length;
  93. DWORD NewAclLength;
  94. PACE_HEADER OldAce;
  95. PACE_HEADER NewAce;
  96. ACL_SIZE_INFORMATION AclInfo;
  97. PSID pSid = NULL;
  98. PACL Dacl = NULL;
  99. PACL NewDacl = NULL;
  100. PACL NewAceDacl = NULL;
  101. PSECURITY_DESCRIPTOR NewSD = NULL;
  102. PSECURITY_DESCRIPTOR OldSD = NULL;
  103. SID_IDENTIFIER_AUTHORITY SepNtAuthority = SECURITY_NT_AUTHORITY;
  104. OldSD = *ppSd;
  105. pSid = LocalAlloc(LMEM_FIXED, 1024);
  106. if (!pSid || !InitializeSid(pSid, &SepNtAuthority, 1))
  107. {
  108. return( FALSE );
  109. };
  110. *(GetSidSubAuthority(pSid, 0 )) = SECURITY_TERMINAL_SERVER_RID;
  111. /*
  112. * Convert SecurityDescriptor to absolute format. It generates
  113. * a new SecurityDescriptor for its output which we must free.
  114. */
  115. Result = SelfRelativeToAbsoluteSD( OldSD, &NewSD, NULL );
  116. if ( !Result ) {
  117. LOGMESSAGE1(_T("Could not convert to AbsoluteSD %d\n"),GetLastError());
  118. LocalFree( pSid );
  119. return( FALSE );
  120. }
  121. // Must get DACL pointer again from new (absolute) SD
  122. Result = GetSecurityDescriptorDacl(
  123. NewSD,
  124. &DaclPresent,
  125. &Dacl,
  126. &DaclDefaulted
  127. );
  128. if( !Result ) {
  129. LOGMESSAGE1(_T("Could not get Dacl %d\n"),GetLastError());
  130. LocalFree( pSid );
  131. LocalFree( NewSD );
  132. return( FALSE );
  133. }
  134. //
  135. // If no DACL, no need to add the user since no DACL
  136. // means all accesss
  137. //
  138. if( !DaclPresent ) {
  139. LOGMESSAGE2(_T("SD has no DACL, Present %d, Defaulted %d\n"),DaclPresent,DaclDefaulted);
  140. LocalFree( pSid );
  141. LocalFree( NewSD );
  142. return( TRUE );
  143. }
  144. //
  145. // Code can return DaclPresent, but a NULL which means
  146. // a NULL Dacl is present. This allows all access to the object.
  147. //
  148. if( Dacl == NULL ) {
  149. LOGMESSAGE2(_T("SD has NULL DACL, Present %d, Defaulted %d\n"),DaclPresent,DaclDefaulted);
  150. LocalFree( pSid );
  151. LocalFree( NewSD );
  152. return( TRUE );
  153. }
  154. // Get the current ACL's size
  155. Result = GetAclInformation(
  156. Dacl,
  157. &AclInfo,
  158. sizeof(AclInfo),
  159. AclSizeInformation
  160. );
  161. if( !Result ) {
  162. LOGMESSAGE1(_T("Error GetAclInformation %d\n"),GetLastError());
  163. LocalFree( pSid );
  164. LocalFree( NewSD );
  165. return( FALSE );
  166. }
  167. //
  168. // Create a new ACL to put the new access allowed ACE on
  169. // to get the right structures and sizes.
  170. //
  171. NewAclLength = sizeof(ACL) +
  172. sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) +
  173. GetLengthSid( pSid );
  174. NewAceDacl = (PACL) LocalAlloc( LMEM_FIXED, NewAclLength );
  175. if ( NewAceDacl == NULL ) {
  176. LOGMESSAGE1(_T("Error LocalAlloc %d bytes\n"),NewAclLength);
  177. LocalFree( pSid );
  178. LocalFree( NewSD );
  179. return( FALSE );
  180. }
  181. Result = InitializeAcl( NewAceDacl, NewAclLength, ACL_REVISION );
  182. if( !Result ) {
  183. LOGMESSAGE1(_T("Error Initializing Acl %d\n"),GetLastError());
  184. LocalFree( NewAceDacl );
  185. LocalFree( pSid );
  186. LocalFree( NewSD );
  187. return( FALSE );
  188. }
  189. Result = AddAccessAllowedAce(
  190. NewAceDacl,
  191. ACL_REVISION,
  192. NewAccess,
  193. pSid
  194. );
  195. if( !Result ) {
  196. LOGMESSAGE1(_T("Error adding Ace %d\n"),GetLastError());
  197. LocalFree( NewAceDacl );
  198. LocalFree( pSid );
  199. LocalFree( NewSD );
  200. return( FALSE );
  201. }
  202. LOGMESSAGE1(_T("Added 0x%x Access to ACL\n"),NewAccess);
  203. Result = GetAce( NewAceDacl, 0, (void **)&NewAce );
  204. if( !Result ) {
  205. LOGMESSAGE1(_T("Error getting Ace %d\n"),GetLastError());
  206. LocalFree( NewAceDacl );
  207. LocalFree( pSid );
  208. LocalFree( NewSD );
  209. return( FALSE );
  210. }
  211. /* add CONTAINER_INHERIT_ACE TO AceFlags */
  212. NewAce->AceFlags |= CONTAINER_INHERIT_ACE;
  213. /*
  214. * Allocate new DACL and copy existing ACE list
  215. */
  216. Length = AclInfo.AclBytesInUse + NewAce->AceSize;
  217. NewDacl = (PACL) LocalAlloc( LMEM_FIXED, Length );
  218. if( NewDacl == NULL ) {
  219. LOGMESSAGE1(_T("Error LocalAlloc %d bytes\n"),Length);
  220. LocalFree( NewAceDacl );
  221. LocalFree( pSid );
  222. LocalFree( NewSD );
  223. return( FALSE );
  224. }
  225. Result = InitializeAcl( NewDacl, Length, ACL_REVISION );
  226. if( !Result ) {
  227. LOGMESSAGE1(_T("Error Initializing Acl %d\n"),GetLastError());
  228. LocalFree( NewDacl );
  229. LocalFree( NewAceDacl );
  230. LocalFree( pSid );
  231. LocalFree( NewSD );
  232. return( FALSE );
  233. }
  234. /*
  235. * Insert new ACE at the front of the DACL
  236. */
  237. Result = AddAce( NewDacl, ACL_REVISION, 0, NewAce, NewAce->AceSize );
  238. if( !Result ) {
  239. LOGMESSAGE1(_T("Error Adding New Ace to Acl %d\n"),GetLastError());
  240. LocalFree( NewDacl );
  241. LocalFree( NewAceDacl );
  242. LocalFree( pSid );
  243. LocalFree( NewSD );
  244. return( FALSE );
  245. }
  246. /*
  247. * Now put the ACE's on the old Dacl to the new Dacl
  248. */
  249. for ( i = 0; i < AclInfo.AceCount; i++ ) {
  250. Result = GetAce( Dacl, i, (void **) &OldAce );
  251. if( !Result ) {
  252. LOGMESSAGE1(_T("Error getting old Ace from Acl %d\n"),GetLastError());
  253. LocalFree( NewDacl );
  254. LocalFree( NewAceDacl );
  255. LocalFree( pSid );
  256. LocalFree( NewSD );
  257. return( FALSE );
  258. }
  259. Result = AddAce( NewDacl, ACL_REVISION, i+1, OldAce, OldAce->AceSize );
  260. if( !Result ) {
  261. LOGMESSAGE1(_T("Error setting old Ace to Acl %d\n"),GetLastError());
  262. LocalFree( NewDacl );
  263. LocalFree( NewAceDacl );
  264. LocalFree( pSid );
  265. LocalFree( NewSD );
  266. return( FALSE );
  267. }
  268. }
  269. /*
  270. * Set new DACL for Security Descriptor
  271. */
  272. Result = SetSecurityDescriptorDacl(
  273. NewSD,
  274. TRUE,
  275. NewDacl,
  276. FALSE
  277. );
  278. if( !Result ) {
  279. LOGMESSAGE1(_T("Error setting New Dacl to SD %d\n"),GetLastError());
  280. LocalFree( NewDacl );
  281. LocalFree( NewAceDacl );
  282. LocalFree( pSid );
  283. LocalFree( NewSD );
  284. return( FALSE );
  285. }
  286. // the DACL must be passed back so that it can be saved to the registry using the new
  287. // GetNamedSecurityInfo() func.
  288. *ppDacl = Dacl = NewDacl;
  289. // Release the callers old security descriptor
  290. // LocalFree( OldSD );
  291. // There was a bug in W2K such that keys created under our install hive had the
  292. // incorrect DACL headers which caused the DACL to be basically open to all users
  293. // for full control.
  294. // The prolem was due to the wrong SD->Control flag which was NT4 style though ACLs
  295. // were in NT5 style
  296. SetSecurityDescriptorControl(NewSD,
  297. SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
  298. SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
  299. *ppSd = NewSD;
  300. // The new SD is in absolute format, so don't free the SID.
  301. // LocalFree( pSid );
  302. return( TRUE );
  303. }
  304. /*****************************************************************************
  305. *
  306. * AddUserToSD
  307. *
  308. * Add the given user for the given domain to the security descriptor.
  309. * The callers security descriptor may be re-allocated.
  310. *
  311. * ENTRY:
  312. * Param1 (input/output)
  313. * Comments
  314. *
  315. * EXIT:
  316. * STATUS_SUCCESS - no error
  317. *
  318. ****************************************************************************/
  319. BOOL
  320. AddUserToSD(
  321. PSECURITY_DESCRIPTOR *ppSd,
  322. PWCHAR pAccount,
  323. PWCHAR pDomain,
  324. DWORD NewAccess
  325. )
  326. {
  327. ULONG i;
  328. BOOL Result;
  329. BOOL DaclPresent;
  330. BOOL DaclDefaulted;
  331. DWORD Length;
  332. // NET_API_STATUS Status;
  333. DWORD /*NewAceLength,*/ NewAclLength;
  334. PACE_HEADER OldAce;
  335. PACE_HEADER NewAce;
  336. ACL_SIZE_INFORMATION AclInfo;
  337. PWCHAR pDC = NULL;
  338. PSID pSid = NULL;
  339. PACL Dacl = NULL;
  340. PACL NewDacl = NULL;
  341. PACL NewAceDacl = NULL;
  342. PSECURITY_DESCRIPTOR NewSD = NULL;
  343. PSECURITY_DESCRIPTOR OldSD = NULL;
  344. OldSD = *ppSd;
  345. /*
  346. // Get our domain controller
  347. Status = NetGetAnyDCName(
  348. NULL, // Local computer
  349. pDomain,
  350. (LPBYTE*)&pDC
  351. );
  352. if( Status != NERR_Success ) {
  353. LOGMESSAGE2(_T("SUSERVER: Could not get domain controller %d for domain %ws\n"),Status,pDomain);
  354. return( FALSE );
  355. }
  356. */
  357. // Get Users SID
  358. Result = xxxLookupAccountName(
  359. pDomain,
  360. pAccount,
  361. &pSid
  362. );
  363. if( !Result ) {
  364. LOGMESSAGE2(_T("SUSERVER: Could not get users SID %d, %ws\n"),GetLastError(),pAccount);
  365. NetApiBufferFree( pDC );
  366. return( FALSE );
  367. }
  368. NetApiBufferFree( pDC );
  369. /*
  370. * Convert SecurityDescriptor to absolute format. It generates
  371. * a new SecurityDescriptor for its output which we must free.
  372. */
  373. Result = SelfRelativeToAbsoluteSD( OldSD, &NewSD, NULL );
  374. if ( !Result ) {
  375. LOGMESSAGE1(_T("Could not convert to AbsoluteSD %d\n"),GetLastError());
  376. LocalFree( pSid );
  377. return( FALSE );
  378. }
  379. // Must get DACL pointer again from new (absolute) SD
  380. Result = GetSecurityDescriptorDacl(
  381. NewSD,
  382. &DaclPresent,
  383. &Dacl,
  384. &DaclDefaulted
  385. );
  386. if( !Result ) {
  387. LOGMESSAGE1(_T("Could not get Dacl %d\n"),GetLastError());
  388. LocalFree( pSid );
  389. LocalFree( NewSD );
  390. return( FALSE );
  391. }
  392. //
  393. // If no DACL, no need to add the user since no DACL
  394. // means all accesss
  395. //
  396. if( !DaclPresent ) {
  397. LOGMESSAGE2(_T("SD has no DACL, Present %d, Defaulted %d\n"),DaclPresent,DaclDefaulted);
  398. LocalFree( pSid );
  399. LocalFree( NewSD );
  400. return( TRUE );
  401. }
  402. //
  403. // Code can return DaclPresent, but a NULL which means
  404. // a NULL Dacl is present. This allows all access to the object.
  405. //
  406. if( Dacl == NULL ) {
  407. LOGMESSAGE2(_T("SD has NULL DACL, Present %d, Defaulted %d\n"),DaclPresent,DaclDefaulted);
  408. LocalFree( pSid );
  409. LocalFree( NewSD );
  410. return( TRUE );
  411. }
  412. // Get the current ACL's size
  413. Result = GetAclInformation(
  414. Dacl,
  415. &AclInfo,
  416. sizeof(AclInfo),
  417. AclSizeInformation
  418. );
  419. if( !Result ) {
  420. LOGMESSAGE1(_T("Error GetAclInformation %d\n"),GetLastError());
  421. LocalFree( pSid );
  422. LocalFree( NewSD );
  423. return( FALSE );
  424. }
  425. //
  426. // Create a new ACL to put the new access allowed ACE on
  427. // to get the right structures and sizes.
  428. //
  429. NewAclLength = sizeof(ACL) +
  430. sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG) +
  431. GetLengthSid( pSid );
  432. NewAceDacl = (PACL) LocalAlloc( LMEM_FIXED, NewAclLength );
  433. if ( NewAceDacl == NULL ) {
  434. LOGMESSAGE1(_T("Error LocalAlloc %d bytes\n"),NewAclLength);
  435. LocalFree( pSid );
  436. LocalFree( NewSD );
  437. return( FALSE );
  438. }
  439. Result = InitializeAcl( NewAceDacl, NewAclLength, ACL_REVISION );
  440. if( !Result ) {
  441. LOGMESSAGE1(_T("Error Initializing Acl %d\n"),GetLastError());
  442. LocalFree( NewAceDacl );
  443. LocalFree( pSid );
  444. LocalFree( NewSD );
  445. return( FALSE );
  446. }
  447. Result = AddAccessAllowedAce(
  448. NewAceDacl,
  449. ACL_REVISION,
  450. NewAccess,
  451. pSid
  452. );
  453. if( !Result ) {
  454. LOGMESSAGE1(_T("Error adding Ace %d\n"),GetLastError());
  455. LocalFree( NewAceDacl );
  456. LocalFree( pSid );
  457. LocalFree( NewSD );
  458. return( FALSE );
  459. }
  460. LOGMESSAGE1(_T("Added 0x%x Access to ACL\n"),NewAccess);
  461. Result = GetAce( NewAceDacl, 0, (void **)&NewAce );
  462. if( !Result ) {
  463. LOGMESSAGE1(_T("Error getting Ace %d\n"),GetLastError());
  464. LocalFree( NewAceDacl );
  465. LocalFree( pSid );
  466. LocalFree( NewSD );
  467. return( FALSE );
  468. }
  469. /* add CONTAINER_INHERIT_ACE TO AceFlags */
  470. NewAce->AceFlags |= CONTAINER_INHERIT_ACE;
  471. /*
  472. * Allocate new DACL and copy existing ACE list
  473. */
  474. Length = AclInfo.AclBytesInUse + NewAce->AceSize;
  475. NewDacl = (PACL) LocalAlloc( LMEM_FIXED, Length );
  476. if( NewDacl == NULL ) {
  477. LOGMESSAGE1(_T("Error LocalAlloc %d bytes\n"),Length);
  478. LocalFree( NewAceDacl );
  479. LocalFree( pSid );
  480. LocalFree( NewSD );
  481. return( FALSE );
  482. }
  483. Result = InitializeAcl( NewDacl, Length, ACL_REVISION );
  484. if( !Result ) {
  485. LOGMESSAGE1(_T("Error Initializing Acl %d\n"),GetLastError());
  486. LocalFree( NewDacl );
  487. LocalFree( NewAceDacl );
  488. LocalFree( pSid );
  489. LocalFree( NewSD );
  490. return( FALSE );
  491. }
  492. /*
  493. * Insert new ACE at the front of the DACL
  494. */
  495. Result = AddAce( NewDacl, ACL_REVISION, 0, NewAce, NewAce->AceSize );
  496. if( !Result ) {
  497. LOGMESSAGE1(_T("Error Adding New Ace to Acl %d\n"),GetLastError());
  498. LocalFree( NewDacl );
  499. LocalFree( NewAceDacl );
  500. LocalFree( pSid );
  501. LocalFree( NewSD );
  502. return( FALSE );
  503. }
  504. /*
  505. * Now put the ACE's on the old Dacl to the new Dacl
  506. */
  507. for ( i = 0; i < AclInfo.AceCount; i++ ) {
  508. Result = GetAce( Dacl, i, (void **) &OldAce );
  509. if( !Result ) {
  510. LOGMESSAGE1(_T("Error getting old Ace from Acl %d\n"),GetLastError());
  511. LocalFree( NewDacl );
  512. LocalFree( NewAceDacl );
  513. LocalFree( pSid );
  514. LocalFree( NewSD );
  515. return( FALSE );
  516. }
  517. Result = AddAce( NewDacl, ACL_REVISION, i+1, OldAce, OldAce->AceSize );
  518. if( !Result ) {
  519. LOGMESSAGE1(_T("Error setting old Ace to Acl %d\n"),GetLastError());
  520. LocalFree( NewDacl );
  521. LocalFree( NewAceDacl );
  522. LocalFree( pSid );
  523. LocalFree( NewSD );
  524. return( FALSE );
  525. }
  526. }
  527. /*
  528. * Set new DACL for Security Descriptor
  529. */
  530. Result = SetSecurityDescriptorDacl(
  531. NewSD,
  532. TRUE,
  533. NewDacl,
  534. FALSE
  535. );
  536. if( !Result ) {
  537. LOGMESSAGE1(_T("Error setting New Dacl to SD %d\n"),GetLastError());
  538. LocalFree( NewDacl );
  539. LocalFree( NewAceDacl );
  540. LocalFree( pSid );
  541. LocalFree( NewSD );
  542. return( FALSE );
  543. }
  544. Dacl = NewDacl;
  545. // Release the callers old security descriptor
  546. // LocalFree( OldSD );
  547. *ppSd = NewSD;
  548. // The new SD is in absolute format, so don't free the SID.
  549. // LocalFree( pSid );
  550. return( TRUE );
  551. }
  552. /*******************************************************************************
  553. *
  554. * SelfRelativeToAbsoluteSD
  555. *
  556. * Convert a Security Descriptor from self-relative format to absolute.
  557. *
  558. * ENTRY:
  559. * SecurityDescriptorIn (input)
  560. * Pointer to self-relative SD to convert
  561. * SecurityDescriptorIn (output)
  562. * Pointer to location to return absolute SD
  563. * ReturnLength (output)
  564. * Pointer to location to return length of absolute SD
  565. *
  566. * EXIT:
  567. *
  568. ******************************************************************************/
  569. BOOL
  570. SelfRelativeToAbsoluteSD(
  571. PSECURITY_DESCRIPTOR SecurityDescriptorIn,
  572. PSECURITY_DESCRIPTOR *SecurityDescriptorOut,
  573. PULONG ReturnedLength
  574. )
  575. {
  576. BOOL Result;
  577. PACL pDacl, pSacl;
  578. PSID pOwner, pGroup;
  579. PSECURITY_DESCRIPTOR pSD;
  580. ULONG SdSize, DaclSize, SaclSize, OwnerSize, GroupSize;
  581. /*
  582. * Determine buffer size needed to convert self-relative SD to absolute.
  583. * We use try-except here since if the input security descriptor value
  584. * is sufficiently messed up, it is possible for this call to trap.
  585. */
  586. SdSize = DaclSize = SaclSize = OwnerSize = GroupSize = 0;
  587. __try {
  588. Result = MakeAbsoluteSD(
  589. SecurityDescriptorIn,
  590. NULL, &SdSize,
  591. NULL, &DaclSize,
  592. NULL, &SaclSize,
  593. NULL, &OwnerSize,
  594. NULL, &GroupSize
  595. );
  596. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  597. SetLastError( ERROR_INVALID_SECURITY_DESCR );
  598. Result = FALSE;
  599. }
  600. if ( Result || (GetLastError() != ERROR_INSUFFICIENT_BUFFER) ) {
  601. LOGMESSAGE1(_T("SUSERVER: SelfRelativeToAbsoluteSD, Error %d\n"),GetLastError());
  602. return( FALSE );
  603. }
  604. /*
  605. * Allocate memory for the absolute SD and setup various pointers
  606. */
  607. pSD = LocalAlloc( LMEM_FIXED, SdSize + DaclSize + SaclSize + OwnerSize + GroupSize );
  608. if ( pSD == NULL )
  609. return( FALSE );
  610. pDacl = (PACL)((PCHAR)pSD + SdSize);
  611. pSacl = (PACL)((PCHAR)pDacl + DaclSize);
  612. pOwner = (PSID)((PCHAR)pSacl + SaclSize);
  613. pGroup = (PSID)((PCHAR)pOwner + OwnerSize);
  614. /*
  615. * Now convert self-relative SD to absolute format.
  616. * We use try-except here since if the input security descriptor value
  617. * is sufficiently messed up, it is possible for this call to trap.
  618. */
  619. __try {
  620. Result = MakeAbsoluteSD(
  621. SecurityDescriptorIn,
  622. pSD, &SdSize,
  623. pDacl, &DaclSize,
  624. pSacl, &SaclSize,
  625. pOwner, &OwnerSize,
  626. pGroup, &GroupSize
  627. );
  628. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  629. SetLastError( ERROR_INVALID_SECURITY_DESCR );
  630. Result = FALSE;
  631. }
  632. if ( !Result ) {
  633. LOGMESSAGE1(_T("SUSERVER: SelfRelativeToAbsoluteSD, Error %d\n"),GetLastError());
  634. LocalFree( pSD );
  635. return( FALSE );
  636. }
  637. *SecurityDescriptorOut = pSD;
  638. if ( ReturnedLength )
  639. *ReturnedLength = SdSize + DaclSize + SaclSize + OwnerSize + GroupSize;
  640. return( TRUE );
  641. }
  642. /*****************************************************************************
  643. *
  644. * xxxLookupAccountName
  645. *
  646. * Wrapper to lookup the SID for a given account name
  647. *
  648. * Returns a pointer to the SID in newly allocated memory
  649. *
  650. * ENTRY:
  651. * Param1 (input/output)
  652. * Comments
  653. *
  654. * EXIT:
  655. * STATUS_SUCCESS - no error
  656. *
  657. ****************************************************************************/
  658. BOOL
  659. xxxLookupAccountName(
  660. PWCHAR pSystemName,
  661. PWCHAR pAccountName,
  662. PSID *ppSid
  663. )
  664. {
  665. BOOL rc;
  666. DWORD Size, DomainSize, Error;
  667. SID_NAME_USE Type;
  668. PWCHAR pDomain = NULL;
  669. PSID pSid = NULL;
  670. WCHAR Buf;
  671. Size = 0;
  672. DomainSize = 0;
  673. rc = LookupAccountNameW(
  674. pSystemName,
  675. pAccountName,
  676. &Buf, // pSid
  677. &Size,
  678. &Buf, // pDomain
  679. &DomainSize,
  680. &Type
  681. );
  682. if( rc ) {
  683. return( FALSE );
  684. }
  685. else {
  686. Error = GetLastError();
  687. if( Error != ERROR_INSUFFICIENT_BUFFER ) {
  688. return( FALSE );
  689. }
  690. pSid = LocalAlloc( LMEM_FIXED, Size );
  691. if( pSid == NULL ) {
  692. return( FALSE );
  693. }
  694. pDomain = (WCHAR *)LocalAlloc( LMEM_FIXED, DomainSize*sizeof(WCHAR) );
  695. if( pDomain == NULL ) {
  696. LocalFree( pSid );
  697. return( FALSE );
  698. }
  699. rc = LookupAccountNameW(
  700. pSystemName,
  701. pAccountName,
  702. pSid,
  703. &Size,
  704. pDomain,
  705. &DomainSize,
  706. &Type
  707. );
  708. if( !rc ) {
  709. LocalFree( pSid );
  710. LocalFree( pDomain );
  711. return( FALSE );
  712. }
  713. *ppSid = pSid;
  714. LocalFree( pDomain );
  715. return( TRUE );
  716. }
  717. }