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.

1142 lines
27 KiB

  1. /*++
  2. Copyright (c) 1987-1996 Microsoft Corporation
  3. Module Name:
  4. lsarepl.c
  5. Abstract:
  6. Low level LSA Replication functions.
  7. Author:
  8. 06-Apr-1992 (madana)
  9. Created for LSA replication.
  10. Environment:
  11. User mode only.
  12. Contains NT-specific code.
  13. Requires ANSI C extensions: slash-slash comments, long external names.
  14. Revision History:
  15. --*/
  16. //
  17. // Common include files.
  18. //
  19. #include "logonsrv.h" // Include files common to entire service
  20. #pragma hdrstop
  21. #include "lsarepl.h"
  22. NTSTATUS
  23. NlPackLsaPolicy(
  24. IN OUT PNETLOGON_DELTA_ENUM Delta,
  25. IN PDB_INFO DBInfo,
  26. IN LPDWORD BufferSize )
  27. /*++
  28. Routine Description:
  29. Pack a description of the LSA policy info into the specified buffer.
  30. Arguments:
  31. Delta: pointer to the delta structure where the new delta will
  32. be returned.
  33. DBInfo: pointer to the database info structure.
  34. BufferSize: size of MIDL buffer that is consumed for this delta is
  35. returned here.
  36. Return Value:
  37. NT status code.
  38. --*/
  39. {
  40. NTSTATUS Status;
  41. ULONG i;
  42. PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  43. PLSAPR_POLICY_INFORMATION PolicyAuditLogInfo = NULL;
  44. PLSAPR_POLICY_INFORMATION PolicyAuditEventsInfo = NULL;
  45. PLSAPR_POLICY_INFORMATION PolicyPrimaryDomainInfo = NULL;
  46. PLSAPR_POLICY_INFORMATION PolicyDefaultQuotaInfo = NULL;
  47. PLSAPR_POLICY_INFORMATION PolicyModificationInfo = NULL;
  48. PNETLOGON_DELTA_POLICY DeltaPolicy = NULL;
  49. DEFPACKTIMER;
  50. DEFLSATIMER;
  51. INITPACKTIMER;
  52. INITLSATIMER;
  53. STARTPACKTIMER;
  54. NlPrint((NL_SYNC_MORE, "Packing Policy Object\n"));
  55. *BufferSize = 0;
  56. Delta->DeltaType = AddOrChangeLsaPolicy;
  57. Delta->DeltaUnion.DeltaPolicy = NULL;
  58. QUERY_LSA_SECOBJ_INFO(DBInfo->DBHandle);
  59. STARTLSATIMER;
  60. Status = LsarQueryInformationPolicy(
  61. DBInfo->DBHandle,
  62. PolicyAuditLogInformation,
  63. &PolicyAuditLogInfo);
  64. STOPLSATIMER;
  65. if (!NT_SUCCESS(Status)) {
  66. PolicyAuditLogInfo = NULL;
  67. goto Cleanup;
  68. }
  69. STARTLSATIMER;
  70. Status = LsarQueryInformationPolicy(
  71. DBInfo->DBHandle,
  72. PolicyAuditEventsInformation,
  73. &PolicyAuditEventsInfo);
  74. STOPLSATIMER;
  75. if (!NT_SUCCESS(Status)) {
  76. PolicyAuditEventsInfo = NULL;
  77. goto Cleanup;
  78. }
  79. STARTLSATIMER;
  80. Status = LsarQueryInformationPolicy(
  81. DBInfo->DBHandle,
  82. PolicyPrimaryDomainInformation,
  83. &PolicyPrimaryDomainInfo);
  84. STOPLSATIMER;
  85. if (!NT_SUCCESS(Status)) {
  86. PolicyPrimaryDomainInfo = NULL;
  87. goto Cleanup;
  88. }
  89. STARTLSATIMER;
  90. Status = LsarQueryInformationPolicy(
  91. DBInfo->DBHandle,
  92. PolicyDefaultQuotaInformation,
  93. &PolicyDefaultQuotaInfo);
  94. STOPLSATIMER;
  95. if (!NT_SUCCESS(Status)) {
  96. PolicyDefaultQuotaInfo = NULL;
  97. goto Cleanup;
  98. }
  99. STARTLSATIMER;
  100. Status = LsarQueryInformationPolicy(
  101. DBInfo->DBHandle,
  102. PolicyModificationInformation,
  103. &PolicyModificationInfo);
  104. STOPLSATIMER;
  105. if (!NT_SUCCESS(Status)) {
  106. PolicyModificationInfo = NULL;
  107. goto Cleanup;
  108. }
  109. //
  110. // Fill in the delta structure
  111. //
  112. //
  113. // copy SID info (There is only one policy database. It has no SID).
  114. //
  115. Delta->DeltaID.Sid = NULL;
  116. //
  117. // allocate delta buffer
  118. //
  119. DeltaPolicy = (PNETLOGON_DELTA_POLICY)
  120. MIDL_user_allocate( sizeof(NETLOGON_DELTA_POLICY) );
  121. if( DeltaPolicy == NULL ) {
  122. Status = STATUS_NO_MEMORY;
  123. goto Cleanup;
  124. }
  125. //
  126. // wipe off the buffer so that cleanup will not be in fault.
  127. //
  128. RtlZeroMemory( DeltaPolicy, sizeof(NETLOGON_DELTA_POLICY) );
  129. // INIT_PLACE_HOLDER(DeltaPolicy);
  130. Delta->DeltaUnion.DeltaPolicy = DeltaPolicy;
  131. *BufferSize += sizeof(NETLOGON_DELTA_POLICY);
  132. DeltaPolicy->MaximumLogSize =
  133. PolicyAuditLogInfo->PolicyAuditLogInfo.MaximumLogSize;
  134. DeltaPolicy->AuditRetentionPeriod;
  135. PolicyAuditLogInfo->PolicyAuditLogInfo.AuditRetentionPeriod;
  136. DeltaPolicy->AuditingMode =
  137. PolicyAuditEventsInfo->
  138. PolicyAuditEventsInfo.AuditingMode;
  139. DeltaPolicy->MaximumAuditEventCount =
  140. PolicyAuditEventsInfo->
  141. PolicyAuditEventsInfo.MaximumAuditEventCount;
  142. *BufferSize += NlCopyData(
  143. (LPBYTE *)&(PolicyAuditEventsInfo->
  144. PolicyAuditEventsInfo.EventAuditingOptions),
  145. (LPBYTE *)&(DeltaPolicy->EventAuditingOptions),
  146. (DeltaPolicy->MaximumAuditEventCount + 1) *
  147. sizeof(ULONG));
  148. // Tell the BDC to 'set' these bits and not just 'or' them in to the current ones
  149. for ( i=0; i<DeltaPolicy->MaximumAuditEventCount; i++ ) {
  150. DeltaPolicy->EventAuditingOptions[i] |= POLICY_AUDIT_EVENT_NONE;
  151. }
  152. //
  153. // sanitity check, EventAuditingOptions size is ULONG size.
  154. //
  155. NlAssert(sizeof(*(PolicyAuditEventsInfo->
  156. PolicyAuditEventsInfo.EventAuditingOptions)) ==
  157. sizeof(ULONG) );
  158. *BufferSize += NlCopyUnicodeString(
  159. (PUNICODE_STRING)&PolicyPrimaryDomainInfo->
  160. PolicyPrimaryDomainInfo.Name,
  161. &DeltaPolicy->PrimaryDomainName );
  162. *BufferSize += NlCopyData(
  163. (LPBYTE *)&(PolicyPrimaryDomainInfo->
  164. PolicyPrimaryDomainInfo.Sid),
  165. (LPBYTE *)&(DeltaPolicy->PrimaryDomainSid),
  166. RtlLengthSid((PSID)(PolicyPrimaryDomainInfo->
  167. PolicyPrimaryDomainInfo.Sid) ));
  168. DeltaPolicy->QuotaLimits.PagedPoolLimit =
  169. (ULONG)PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.PagedPoolLimit;
  170. DeltaPolicy->QuotaLimits.NonPagedPoolLimit =
  171. (ULONG)PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.NonPagedPoolLimit;
  172. DeltaPolicy->QuotaLimits.MinimumWorkingSetSize =
  173. (ULONG)PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.MinimumWorkingSetSize;
  174. DeltaPolicy->QuotaLimits.MaximumWorkingSetSize =
  175. (ULONG)PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.MaximumWorkingSetSize;
  176. DeltaPolicy->QuotaLimits.PagefileLimit =
  177. (ULONG)PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.PagefileLimit;
  178. NEW_TO_OLD_LARGE_INTEGER(
  179. PolicyDefaultQuotaInfo->PolicyDefaultQuotaInfo.QuotaLimits.TimeLimit,
  180. DeltaPolicy->QuotaLimits.TimeLimit );
  181. NEW_TO_OLD_LARGE_INTEGER(
  182. PolicyModificationInfo->PolicyModificationInfo.ModifiedId,
  183. DeltaPolicy->ModifiedId );
  184. NEW_TO_OLD_LARGE_INTEGER(
  185. PolicyModificationInfo->PolicyModificationInfo.DatabaseCreationTime,
  186. DeltaPolicy->DatabaseCreationTime );
  187. DELTA_SECOBJ_INFO(DeltaPolicy);
  188. //
  189. // All Done
  190. //
  191. Status = STATUS_SUCCESS;
  192. Cleanup:
  193. STARTLSATIMER;
  194. if ( SecurityDescriptor != NULL ) {
  195. LsaIFree_LSAPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
  196. }
  197. if ( PolicyAuditLogInfo != NULL ) {
  198. LsaIFree_LSAPR_POLICY_INFORMATION(
  199. PolicyAuditLogInformation,
  200. PolicyAuditLogInfo );
  201. }
  202. if ( PolicyAuditEventsInfo != NULL ) {
  203. LsaIFree_LSAPR_POLICY_INFORMATION(
  204. PolicyAuditEventsInformation,
  205. PolicyAuditEventsInfo );
  206. }
  207. if ( PolicyPrimaryDomainInfo != NULL ) {
  208. LsaIFree_LSAPR_POLICY_INFORMATION(
  209. PolicyPrimaryDomainInformation,
  210. PolicyPrimaryDomainInfo );
  211. }
  212. if ( PolicyDefaultQuotaInfo != NULL ) {
  213. LsaIFree_LSAPR_POLICY_INFORMATION(
  214. PolicyDefaultQuotaInformation,
  215. PolicyDefaultQuotaInfo );
  216. }
  217. if ( PolicyModificationInfo != NULL ) {
  218. LsaIFree_LSAPR_POLICY_INFORMATION(
  219. PolicyModificationInformation,
  220. PolicyModificationInfo );
  221. }
  222. STOPLSATIMER;
  223. if( !NT_SUCCESS(Status) ) {
  224. NlFreeDBDelta( Delta );
  225. *BufferSize = 0;
  226. }
  227. STOPPACKTIMER;
  228. NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack POLICY object:\n"));
  229. PRINTPACKTIMER;
  230. PRINTLSATIMER;
  231. return(Status);
  232. }
  233. NTSTATUS
  234. NlPackLsaTDomain(
  235. IN PSID Sid,
  236. IN OUT PNETLOGON_DELTA_ENUM Delta,
  237. IN PDB_INFO DBInfo,
  238. IN LPDWORD BufferSize )
  239. /*++
  240. Routine Description:
  241. Pack a description of the specified trusted domain info into the
  242. specified buffer.
  243. Arguments:
  244. Sid - The SID of the trusted domain.
  245. Delta: pointer to the delta structure where the new delta will
  246. be returned.
  247. DBInfo: pointer to the database info structure.
  248. BufferSize: size of MIDL buffer that is consumed for this delta is
  249. returned here.
  250. Return Value:
  251. NT status code.
  252. --*/
  253. {
  254. NTSTATUS Status;
  255. LSAPR_HANDLE TrustedDomainHandle = NULL;
  256. PLSAPR_TRUSTED_DOMAIN_INFO TrustedDomainNameInfo = NULL;
  257. PLSAPR_TRUSTED_DOMAIN_INFO TrustedPosixOffsetInfo = NULL;
  258. PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  259. PNETLOGON_DELTA_TRUSTED_DOMAINS DeltaTDomain = NULL;
  260. DWORD i;
  261. DWORD Entries;
  262. DWORD Size = 0;
  263. PLSAPR_UNICODE_STRING UnicodeControllerName;
  264. DEFPACKTIMER;
  265. DEFLSATIMER;
  266. INITPACKTIMER;
  267. INITLSATIMER;
  268. STARTPACKTIMER;
  269. NlPrint((NL_SYNC_MORE, "Packing Trusted Domain Object\n"));
  270. *BufferSize = 0;
  271. Delta->DeltaType = AddOrChangeLsaTDomain;
  272. Delta->DeltaID.Sid = NULL;
  273. Delta->DeltaUnion.DeltaTDomains = NULL;
  274. //
  275. // open trusted domain
  276. //
  277. STARTLSATIMER;
  278. Status = LsarOpenTrustedDomain(
  279. DBInfo->DBHandle,
  280. (PLSAPR_SID)Sid,
  281. 0,
  282. &TrustedDomainHandle );
  283. STOPLSATIMER;
  284. if (!NT_SUCCESS(Status)) {
  285. TrustedDomainHandle = NULL;
  286. goto Cleanup;
  287. }
  288. QUERY_LSA_SECOBJ_INFO(TrustedDomainHandle);
  289. STARTLSATIMER;
  290. Status = LsarQueryInfoTrustedDomain(
  291. TrustedDomainHandle,
  292. TrustedDomainNameInformation,
  293. &TrustedDomainNameInfo );
  294. STOPLSATIMER;
  295. if (!NT_SUCCESS(Status)) {
  296. TrustedDomainNameInfo = NULL;
  297. goto Cleanup;
  298. }
  299. NlPrint((NL_SYNC_MORE,
  300. "\t Trusted Domain Object name %wZ\n",
  301. (PUNICODE_STRING)&TrustedDomainNameInfo->
  302. TrustedDomainNameInfo.Name ));
  303. STARTLSATIMER;
  304. Status = LsarQueryInfoTrustedDomain(
  305. TrustedDomainHandle,
  306. TrustedPosixOffsetInformation,
  307. &TrustedPosixOffsetInfo );
  308. STOPLSATIMER;
  309. if (!NT_SUCCESS(Status)) {
  310. TrustedPosixOffsetInfo = NULL;
  311. goto Cleanup;
  312. }
  313. //
  314. // Fill in the delta structure
  315. //
  316. //
  317. // copy SID info
  318. //
  319. Delta->DeltaID.Sid = MIDL_user_allocate( RtlLengthSid(Sid) );
  320. if( Delta->DeltaID.Sid == NULL ) {
  321. Status = STATUS_NO_MEMORY;
  322. goto Cleanup;
  323. }
  324. RtlCopyMemory( Delta->DeltaID.Sid, Sid, RtlLengthSid(Sid) );
  325. //
  326. // allocate delta buffer
  327. //
  328. DeltaTDomain = (PNETLOGON_DELTA_TRUSTED_DOMAINS)
  329. MIDL_user_allocate( sizeof(NETLOGON_DELTA_TRUSTED_DOMAINS) );
  330. if( DeltaTDomain == NULL ) {
  331. Status = STATUS_NO_MEMORY;
  332. goto Cleanup;
  333. }
  334. //
  335. // wipe off the buffer so that cleanup will not be in fault.
  336. //
  337. RtlZeroMemory( DeltaTDomain, sizeof(NETLOGON_DELTA_TRUSTED_DOMAINS) );
  338. // INIT_PLACE_HOLDER(DeltaTDomain);
  339. Delta->DeltaUnion.DeltaTDomains = DeltaTDomain;
  340. *BufferSize += sizeof(NETLOGON_DELTA_TRUSTED_DOMAINS);
  341. *BufferSize += NlCopyUnicodeString(
  342. (PUNICODE_STRING)&TrustedDomainNameInfo->
  343. TrustedDomainNameInfo.Name,
  344. &DeltaTDomain->DomainName );
  345. DELTA_SECOBJ_INFO(DeltaTDomain);
  346. //
  347. // send Posix Offset info across using place holder.
  348. //
  349. DeltaTDomain->DummyLong1 =
  350. TrustedPosixOffsetInfo->TrustedPosixOffsetInfo.Offset;
  351. //
  352. // All Done
  353. //
  354. Status = STATUS_SUCCESS;
  355. Cleanup:
  356. STARTLSATIMER;
  357. if ( TrustedDomainHandle != NULL ) {
  358. LsarClose( &TrustedDomainHandle );
  359. }
  360. if ( SecurityDescriptor != NULL ) {
  361. LsaIFree_LSAPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
  362. }
  363. if ( TrustedDomainNameInfo != NULL ) {
  364. LsaIFree_LSAPR_TRUSTED_DOMAIN_INFO(
  365. TrustedDomainNameInformation,
  366. TrustedDomainNameInfo );
  367. }
  368. if ( TrustedPosixOffsetInfo != NULL ) {
  369. LsaIFree_LSAPR_TRUSTED_DOMAIN_INFO(
  370. TrustedPosixOffsetInformation,
  371. TrustedPosixOffsetInfo );
  372. }
  373. STOPLSATIMER;
  374. if( !NT_SUCCESS(Status) ) {
  375. NlFreeDBDelta( Delta );
  376. *BufferSize = 0;
  377. }
  378. STOPPACKTIMER;
  379. NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack TDOMAIN object:\n"));
  380. PRINTPACKTIMER;
  381. PRINTLSATIMER;
  382. return(Status);
  383. }
  384. NTSTATUS
  385. NlPackLsaAccount(
  386. IN PSID Sid,
  387. IN OUT PNETLOGON_DELTA_ENUM Delta,
  388. IN PDB_INFO DBInfo,
  389. IN LPDWORD BufferSize,
  390. IN PSESSION_INFO SessionInfo
  391. )
  392. /*++
  393. Routine Description:
  394. Pack a description of the specified LSA account info into the
  395. specified buffer.
  396. Arguments:
  397. Sid - The SID of the LSA account.
  398. Delta: pointer to the delta structure where the new delta will
  399. be returned.
  400. DBInfo: pointer to the database info structure.
  401. BufferSize: size of MIDL buffer that is consumed for this delta is
  402. returned here.
  403. SessionInfo: Info describing BDC that's calling us
  404. Return Value:
  405. NT status code.
  406. --*/
  407. {
  408. NTSTATUS Status;
  409. PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  410. PNETLOGON_DELTA_ACCOUNTS DeltaAccount = NULL;
  411. LSAPR_HANDLE AccountHandle = NULL;
  412. PLSAPR_PRIVILEGE_SET Privileges = NULL;
  413. ULONG SystemAccessFlags;
  414. PULONG PrivilegeAttributes;
  415. PUNICODE_STRING PrivilegeNames;
  416. LUID MachineAccountPrivilegeLuid;
  417. DWORD CopiedPrivilegeCount;
  418. DWORD i;
  419. DWORD Size;
  420. DEFPACKTIMER;
  421. DEFLSATIMER;
  422. INITPACKTIMER;
  423. INITLSATIMER;
  424. STARTPACKTIMER;
  425. NlPrint((NL_SYNC_MORE, "Packing Lsa Account Object\n"));
  426. *BufferSize = 0;
  427. MachineAccountPrivilegeLuid = RtlConvertLongToLuid(SE_MACHINE_ACCOUNT_PRIVILEGE);
  428. Delta->DeltaType = AddOrChangeLsaAccount;
  429. Delta->DeltaID.Sid = NULL;
  430. Delta->DeltaUnion.DeltaAccounts = NULL;
  431. //
  432. // open lsa account
  433. //
  434. STARTLSATIMER;
  435. Status = LsarOpenAccount(
  436. DBInfo->DBHandle,
  437. (PLSAPR_SID)Sid,
  438. 0,
  439. &AccountHandle );
  440. STOPLSATIMER;
  441. if (!NT_SUCCESS(Status)) {
  442. AccountHandle = NULL;
  443. goto Cleanup;
  444. }
  445. QUERY_LSA_SECOBJ_INFO(AccountHandle);
  446. STARTLSATIMER;
  447. Status = LsarEnumeratePrivilegesAccount(
  448. AccountHandle,
  449. &Privileges );
  450. STOPLSATIMER;
  451. if (!NT_SUCCESS(Status)) {
  452. Privileges = NULL;
  453. goto Cleanup;
  454. }
  455. STARTLSATIMER;
  456. Status = LsarGetSystemAccessAccount(
  457. AccountHandle,
  458. &SystemAccessFlags );
  459. STOPLSATIMER;
  460. if (!NT_SUCCESS(Status)) {
  461. goto Cleanup;
  462. }
  463. //
  464. // Fill in the delta structure
  465. //
  466. //
  467. // copy SID info
  468. //
  469. Delta->DeltaID.Sid = MIDL_user_allocate( RtlLengthSid(Sid) );
  470. if( Delta->DeltaID.Sid == NULL ) {
  471. Status = STATUS_NO_MEMORY;
  472. goto Cleanup;
  473. }
  474. RtlCopyMemory( Delta->DeltaID.Sid, Sid, RtlLengthSid(Sid) );
  475. //
  476. // allocate delta buffer
  477. //
  478. DeltaAccount = (PNETLOGON_DELTA_ACCOUNTS)
  479. MIDL_user_allocate( sizeof(NETLOGON_DELTA_ACCOUNTS) );
  480. if( DeltaAccount == NULL ) {
  481. Status = STATUS_NO_MEMORY;
  482. goto Cleanup;
  483. }
  484. //
  485. // wipe off the buffer so that cleanup will not be in fault.
  486. //
  487. RtlZeroMemory( DeltaAccount, sizeof(NETLOGON_DELTA_ACCOUNTS) );
  488. // INIT_PLACE_HOLDER(DeltaAccount);
  489. Delta->DeltaUnion.DeltaAccounts = DeltaAccount;
  490. *BufferSize += sizeof(NETLOGON_DELTA_ACCOUNTS);
  491. DeltaAccount->PrivilegeControl = Privileges->Control;
  492. DeltaAccount->PrivilegeEntries = 0;
  493. DeltaAccount->PrivilegeAttributes = NULL;
  494. DeltaAccount->PrivilegeNames = NULL;
  495. Size = Privileges->PrivilegeCount * sizeof(ULONG);
  496. PrivilegeAttributes = MIDL_user_allocate( Size );
  497. if( PrivilegeAttributes == NULL ) {
  498. Status = STATUS_NO_MEMORY;
  499. goto Cleanup;
  500. }
  501. DeltaAccount->PrivilegeAttributes = PrivilegeAttributes;
  502. *BufferSize += Size;
  503. Size = Privileges->PrivilegeCount * sizeof(UNICODE_STRING);
  504. PrivilegeNames = MIDL_user_allocate( Size );
  505. if( PrivilegeNames == NULL ) {
  506. Status = STATUS_NO_MEMORY;
  507. goto Cleanup;
  508. }
  509. DeltaAccount->PrivilegeNames = PrivilegeNames;
  510. *BufferSize += Size;
  511. //
  512. // now fill up Privilege Attributes and Names
  513. //
  514. CopiedPrivilegeCount = 0;
  515. for( i = 0; i < Privileges->PrivilegeCount; i++ ) {
  516. //
  517. // Don't replicate SeMachineAccount privilege to NT 3.1. It can't handle it.
  518. // (Use the SUPPORTS_ACCOUNT_LOCKOUT bit so we don't have to consume
  519. // another bit.)
  520. //
  521. if ( (SessionInfo->NegotiatedFlags & NETLOGON_SUPPORTS_ACCOUNT_LOCKOUT) ||
  522. (!RtlEqualLuid((PLUID)(&Privileges->Privilege[i].Luid),
  523. &MachineAccountPrivilegeLuid ))) {
  524. PLSAPR_UNICODE_STRING PrivName = NULL;
  525. *PrivilegeAttributes = Privileges->Privilege[i].Attributes;
  526. //
  527. // convert LUID to Name
  528. //
  529. STARTLSATIMER;
  530. Status = LsarLookupPrivilegeName(
  531. DBInfo->DBHandle,
  532. (PLUID)&Privileges->Privilege[i].Luid,
  533. &PrivName );
  534. STOPLSATIMER;
  535. if (!NT_SUCCESS(Status)) {
  536. goto Cleanup;
  537. }
  538. *BufferSize += NlCopyUnicodeString(
  539. (PUNICODE_STRING)PrivName,
  540. PrivilegeNames );
  541. LsaIFree_LSAPR_UNICODE_STRING( PrivName );
  542. CopiedPrivilegeCount ++;
  543. PrivilegeAttributes++;
  544. PrivilegeNames++;
  545. } else {
  546. NlPrint((NL_SYNC_MORE,
  547. "NlPackLsaAccount: ignored privilege %ld %ld\n",
  548. (PLUID) LongToPtr( (&Privileges->Privilege[i].Luid)->HighPart ),
  549. (PLUID) ULongToPtr( (&Privileges->Privilege[i].Luid)->LowPart ) ));
  550. }
  551. }
  552. DeltaAccount->PrivilegeEntries = CopiedPrivilegeCount;
  553. //
  554. // Send only those bits that NT4.0 BDC understands.
  555. // Otherwise, it will choke on it.
  556. //
  557. DeltaAccount->SystemAccessFlags = SystemAccessFlags & POLICY_MODE_ALL_NT4;
  558. DELTA_SECOBJ_INFO(DeltaAccount);
  559. //
  560. // All Done
  561. //
  562. Status = STATUS_SUCCESS;
  563. Cleanup:
  564. STARTLSATIMER;
  565. if ( AccountHandle != NULL ) {
  566. LsarClose( &AccountHandle );
  567. }
  568. if ( SecurityDescriptor != NULL ) {
  569. LsaIFree_LSAPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
  570. }
  571. if ( Privileges != NULL ) {
  572. LsaIFree_LSAPR_PRIVILEGE_SET( Privileges );
  573. }
  574. STOPLSATIMER;
  575. if( !NT_SUCCESS(Status) ) {
  576. NlFreeDBDelta( Delta );
  577. *BufferSize = 0;
  578. }
  579. STOPPACKTIMER;
  580. NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack LSAACCOUNT object:\n"));
  581. PRINTPACKTIMER;
  582. PRINTLSATIMER;
  583. return(Status);
  584. }
  585. NTSTATUS
  586. NlPackLsaSecret(
  587. IN PUNICODE_STRING Name,
  588. IN OUT PNETLOGON_DELTA_ENUM Delta,
  589. IN PDB_INFO DBInfo,
  590. IN LPDWORD BufferSize,
  591. IN PSESSION_INFO SessionInfo
  592. )
  593. /*++
  594. Routine Description:
  595. Pack a description of the specified LSA secret info into the
  596. specified buffer.
  597. Arguments:
  598. Name - Name of the secret.
  599. Delta: pointer to the delta structure where the new delta will
  600. be returned.
  601. DBInfo: pointer to the database info structure.
  602. BufferSize: size of MIDL buffer that is consumed for this delta is
  603. returned here.
  604. SessionInfo: Information shared between BDC and PDC
  605. Return Value:
  606. NT status code.
  607. --*/
  608. {
  609. NTSTATUS Status;
  610. PLSAPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor = NULL;
  611. LSAPR_HANDLE SecretHandle = NULL;
  612. PNETLOGON_DELTA_SECRET DeltaSecret = NULL;
  613. PLSAPR_CR_CIPHER_VALUE CurrentValue = NULL;
  614. PLSAPR_CR_CIPHER_VALUE OldValue = NULL;
  615. LARGE_INTEGER CurrentValueSetTime;
  616. LARGE_INTEGER OldValueSetTime;
  617. DEFPACKTIMER;
  618. DEFLSATIMER;
  619. INITPACKTIMER;
  620. INITLSATIMER;
  621. STARTPACKTIMER;
  622. NlPrint((NL_SYNC_MORE, "Packing Secret Object: %wZ\n", Name));
  623. //
  624. // we should be packing only GLOBAL secrets
  625. //
  626. NlAssert(
  627. (Name->Length / sizeof(WCHAR) >
  628. LSA_GLOBAL_SECRET_PREFIX_LENGTH ) &&
  629. (_wcsnicmp( Name->Buffer,
  630. LSA_GLOBAL_SECRET_PREFIX,
  631. LSA_GLOBAL_SECRET_PREFIX_LENGTH ) == 0) );
  632. *BufferSize = 0;
  633. Delta->DeltaType = AddOrChangeLsaSecret;
  634. Delta->DeltaID.Name = NULL;
  635. Delta->DeltaUnion.DeltaPolicy = NULL;
  636. //
  637. // open lsa account
  638. //
  639. STARTLSATIMER;
  640. Status = LsarOpenSecret(
  641. DBInfo->DBHandle,
  642. (PLSAPR_UNICODE_STRING)Name,
  643. 0,
  644. &SecretHandle );
  645. STOPLSATIMER;
  646. if (!NT_SUCCESS(Status)) {
  647. SecretHandle = NULL;
  648. goto Cleanup;
  649. }
  650. QUERY_LSA_SECOBJ_INFO(SecretHandle);
  651. STARTLSATIMER;
  652. Status = LsarQuerySecret(
  653. SecretHandle,
  654. &CurrentValue,
  655. &CurrentValueSetTime,
  656. &OldValue,
  657. &OldValueSetTime );
  658. STOPLSATIMER;
  659. if (!NT_SUCCESS(Status)) {
  660. CurrentValue = NULL;
  661. OldValue = NULL;
  662. goto Cleanup;
  663. }
  664. //
  665. // Fill in the delta structure
  666. //
  667. //
  668. // copy ID field
  669. //
  670. Delta->DeltaID.Name =
  671. MIDL_user_allocate( Name->Length + sizeof(WCHAR) );
  672. if( Delta->DeltaID.Name == NULL ) {
  673. Status = STATUS_NO_MEMORY;
  674. goto Cleanup;
  675. }
  676. wcsncpy( Delta->DeltaID.Name,
  677. Name->Buffer,
  678. Name->Length / sizeof(WCHAR) );
  679. //
  680. // terminate string
  681. //
  682. Delta->DeltaID.Name[ Name->Length / sizeof(WCHAR) ] = L'\0';
  683. DeltaSecret = (PNETLOGON_DELTA_SECRET)
  684. MIDL_user_allocate( sizeof(NETLOGON_DELTA_SECRET) );
  685. if( DeltaSecret == NULL ) {
  686. Status = STATUS_NO_MEMORY;
  687. goto Cleanup;
  688. }
  689. //
  690. // wipe off the buffer so that cleanup will not be in fault.
  691. //
  692. RtlZeroMemory( DeltaSecret, sizeof(NETLOGON_DELTA_SECRET) );
  693. // INIT_PLACE_HOLDER(DeltaSecret);
  694. Delta->DeltaUnion.DeltaSecret = DeltaSecret;
  695. *BufferSize += sizeof(NETLOGON_DELTA_SECRET);
  696. NEW_TO_OLD_LARGE_INTEGER(
  697. CurrentValueSetTime,
  698. DeltaSecret->CurrentValueSetTime );
  699. NEW_TO_OLD_LARGE_INTEGER(
  700. OldValueSetTime,
  701. DeltaSecret->OldValueSetTime );
  702. if( CurrentValue != NULL && CurrentValue->Buffer != NULL && CurrentValue->Length != 0) {
  703. //
  704. // Copy the secret into an allocated buffer and encrypt it in place.
  705. // Don't use the LSA's buffer since it a ALLOCATE_ALL_NODES.
  706. //
  707. DeltaSecret->CurrentValue.Buffer =
  708. MIDL_user_allocate( CurrentValue->Length );
  709. if( DeltaSecret->CurrentValue.Buffer == NULL ) {
  710. Status = STATUS_NO_MEMORY;
  711. goto Cleanup;
  712. }
  713. DeltaSecret->CurrentValue.Length =
  714. DeltaSecret->CurrentValue.MaximumLength = CurrentValue->Length;
  715. RtlCopyMemory( DeltaSecret->CurrentValue.Buffer,
  716. CurrentValue->Buffer,
  717. CurrentValue->Length );
  718. //
  719. // secret values are encrypted using session keys.
  720. //
  721. Status = NlEncryptSensitiveData(
  722. (PCRYPT_BUFFER) &DeltaSecret->CurrentValue,
  723. SessionInfo );
  724. if (!NT_SUCCESS(Status)) {
  725. goto Cleanup;
  726. }
  727. } else {
  728. DeltaSecret->CurrentValue.Length = 0;
  729. DeltaSecret->CurrentValue.MaximumLength = 0;
  730. DeltaSecret->CurrentValue.Buffer = NULL;
  731. }
  732. *BufferSize += DeltaSecret->CurrentValue.MaximumLength;
  733. if( OldValue != NULL && OldValue->Buffer != NULL && OldValue->Length != 0 ) {
  734. //
  735. // Copy the secret into an allocated buffer and encrypt it in place.
  736. // Don't use the LSA's buffer since it a ALLOCATE_ALL_NODES.
  737. //
  738. DeltaSecret->OldValue.Buffer =
  739. MIDL_user_allocate( OldValue->Length );
  740. if( DeltaSecret->OldValue.Buffer == NULL ) {
  741. Status = STATUS_NO_MEMORY;
  742. goto Cleanup;
  743. }
  744. DeltaSecret->OldValue.Length =
  745. DeltaSecret->OldValue.MaximumLength = OldValue->Length;
  746. RtlCopyMemory( DeltaSecret->OldValue.Buffer,
  747. OldValue->Buffer,
  748. OldValue->Length );
  749. //
  750. // secret values are encrypted using session keys.
  751. //
  752. Status = NlEncryptSensitiveData(
  753. (PCRYPT_BUFFER) &DeltaSecret->OldValue,
  754. SessionInfo );
  755. if (!NT_SUCCESS(Status)) {
  756. goto Cleanup;
  757. }
  758. } else {
  759. DeltaSecret->OldValue.Length = 0;
  760. DeltaSecret->OldValue.MaximumLength = 0;
  761. DeltaSecret->OldValue.Buffer = NULL;
  762. }
  763. *BufferSize += DeltaSecret->OldValue.MaximumLength;
  764. DELTA_SECOBJ_INFO(DeltaSecret);
  765. //
  766. // All Done
  767. //
  768. Status = STATUS_SUCCESS;
  769. Cleanup:
  770. STARTLSATIMER;
  771. if ( SecretHandle != NULL ) {
  772. LsarClose( &SecretHandle );
  773. }
  774. if ( SecurityDescriptor != NULL ) {
  775. LsaIFree_LSAPR_SR_SECURITY_DESCRIPTOR( SecurityDescriptor );
  776. }
  777. if( CurrentValue != NULL ) {
  778. LsaIFree_LSAPR_CR_CIPHER_VALUE( CurrentValue );
  779. }
  780. if( OldValue != NULL ) {
  781. LsaIFree_LSAPR_CR_CIPHER_VALUE( OldValue );
  782. }
  783. STOPLSATIMER;
  784. if( !NT_SUCCESS(Status) ) {
  785. NlFreeDBDelta( Delta );
  786. *BufferSize = 0;
  787. }
  788. STOPPACKTIMER;
  789. NlPrint((NL_REPL_OBJ_TIME,"Time taken to pack SECRET object:\n"));
  790. PRINTPACKTIMER;
  791. PRINTLSATIMER;
  792. return(Status);
  793. }