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.

1265 lines
35 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dbinstal.c
  5. Abstract:
  6. LSA Protected Subsystem - Database Installation.
  7. This module contains code which will create an initial LSA Database
  8. if none exists. Temporarily, this code is executed from within
  9. LSA Initialization. This code will form part of the Security
  10. Installation applet when implemented.
  11. WARNING! THE CODE IN THIS MODULE IS TEMPORARY. IT WILL BE REPLACED
  12. BY SYSTEM INSTALLATION FUNCTIONALITY.
  13. Author:
  14. Scott Birrell (ScottBi) August 2, 1991
  15. Environment:
  16. User mode - Does not depend on Windows.
  17. Revision History:
  18. --*/
  19. #include <lsapch2.h>
  20. #include "dbp.h"
  21. VOID
  22. LsapDbSetDomainInfo(
  23. IN PLSAP_DB_ATTRIBUTE *NextAttribute,
  24. IN ULONG *AttributeCount
  25. );
  26. NTSTATUS
  27. LsapDbGetNextValueToken(
  28. IN PUNICODE_STRING Value,
  29. IN OUT PULONG ParseContext,
  30. OUT PUNICODE_STRING *ReturnString
  31. );
  32. NTSTATUS
  33. LsapDbInstallLsaDatabase(
  34. ULONG Pass
  35. )
  36. /*++
  37. Routine Description:
  38. This function installs an initial LSA Database. Any existing database
  39. will be reset to have its initial attributes.
  40. Arguments:
  41. Pass - Either 1 or 2. During pass 1 all information that is
  42. not product type-specific is initialized. In pass 2,
  43. the product type-specific stuff is initialized.
  44. Return Value:
  45. NTSTATUS - Standard Nt Result Code
  46. --*/
  47. {
  48. NTSTATUS Status;
  49. //
  50. // Install the LSA Database Policy Object.
  51. //
  52. Status = LsapDbInstallPolicyObject(Pass);
  53. return(Status);
  54. }
  55. NTSTATUS
  56. LsapDbInstallPolicyObject(
  57. IN ULONG Pass
  58. )
  59. /*++
  60. Routine Description:
  61. This function installs the LSA Database Policy Object, setting its attributes
  62. to the default state. It is called as part of the LSA Database
  63. Installation Procedure.
  64. Arguments:
  65. Pass - Either 1 or 2. During pass 1 all information that is
  66. not product type-specific is initialized. In pass 2,
  67. the product type-specific stuff is initialized.
  68. Return Value:
  69. --*/
  70. {
  71. NTSTATUS Status = STATUS_SUCCESS;
  72. LSAP_DB_OBJECT_INFORMATION ObjectInformation;
  73. LSAP_DB_HANDLE Handle;
  74. POLICY_LSA_SERVER_ROLE ServerRole;
  75. LSAP_DB_POLICY_PRIVATE_DATA PolicyPrivateData;
  76. LSARM_POLICY_AUDIT_EVENTS_INFO InitialAuditEventInformation;
  77. POLICY_AUDIT_LOG_INFO InitialAuditLogInformation;
  78. LSAP_DB_ATTRIBUTE Attributes[21];
  79. PLSAP_DB_ATTRIBUTE NextAttribute;
  80. ULONG AttributeCount = 0;
  81. BOOLEAN ObjectReferenced = FALSE;
  82. ULONG Revision;
  83. LSAP_DB_ENCRYPTION_KEY NewEncryptionKey;
  84. ULONG SyskeyLength;
  85. PVOID Syskey;
  86. QUOTA_LIMITS InstalledQuotaLimits;
  87. NextAttribute = Attributes;
  88. LsapDiagPrint( DB_INIT,
  89. ("LSA (init): Performing pass %d of LSA Policy Initialization\n",
  90. Pass ) );
  91. if (Pass == 1) {
  92. //
  93. // Set up the Object Information for creating the Policy Object.
  94. // Note that we put NULL for Security Quality Of Service since this
  95. // open does not involve impersonation.
  96. //
  97. ObjectInformation.ObjectTypeId = PolicyObject;
  98. ObjectInformation.Sid = NULL;
  99. ObjectInformation.ObjectAttributeNameOnly = FALSE;
  100. InitializeObjectAttributes(
  101. &ObjectInformation.ObjectAttributes,
  102. &LsapDbNames[Policy],
  103. 0L,
  104. NULL,
  105. NULL
  106. );
  107. Handle = LsapDbHandle;
  108. //
  109. // Create the revision attribute
  110. //
  111. Revision = LSAP_DB_REVISION_1_7;
  112. LsapDbInitializeAttribute(
  113. NextAttribute,
  114. &LsapDbNames[PolRevision],
  115. &Revision,
  116. sizeof (ULONG),
  117. FALSE
  118. );
  119. NextAttribute++;
  120. AttributeCount++;
  121. //
  122. // Install initial Private Data. For now, just one ULONG is stored.
  123. //
  124. PolicyPrivateData.NoneDefinedYet = 0;
  125. LsapDbInitializeAttribute(
  126. NextAttribute,
  127. &LsapDbNames[PolState],
  128. &PolicyPrivateData,
  129. sizeof (LSAP_DB_POLICY_PRIVATE_DATA),
  130. FALSE
  131. );
  132. NextAttribute++;
  133. AttributeCount++;
  134. //
  135. // Initialize the Policy Modification Info. Set the Modification
  136. // Id to 1 and set the Database Creation Time to the current time.
  137. //
  138. LsapDbState.PolicyModificationInfo.ModifiedId =
  139. RtlConvertUlongToLargeInteger( (ULONG) 1 );
  140. Status = NtQuerySystemTime(
  141. &LsapDbState.PolicyModificationInfo.DatabaseCreationTime
  142. );
  143. if (!NT_SUCCESS(Status)) {
  144. goto InstallPolicyObjectError;
  145. }
  146. LsapDbInitializeAttribute(
  147. NextAttribute,
  148. &LsapDbNames[PolMod],
  149. &LsapDbState.PolicyModificationInfo,
  150. sizeof (POLICY_MODIFICATION_INFO),
  151. FALSE
  152. );
  153. NextAttribute++;
  154. AttributeCount++;
  155. //
  156. // Initialize Default Event Auditing Options. No auditing is specified
  157. // for any event type. These will be set in the Policy Database later
  158. // when the Policy Object is created.
  159. //
  160. Status = LsapAdtInitializeDefaultAuditing(
  161. (ULONG) 0,
  162. &InitialAuditEventInformation
  163. );
  164. LsapDbInitializeAttribute(
  165. NextAttribute,
  166. &LsapDbNames[PolAdtEv],
  167. &InitialAuditEventInformation,
  168. sizeof (LSARM_POLICY_AUDIT_EVENTS_INFO),
  169. FALSE
  170. );
  171. NextAttribute++;
  172. AttributeCount++;
  173. //
  174. // Create the Containing Directory "Accounts" for the user and group
  175. // accounts objects.
  176. //
  177. LsapDbInitializeAttribute(
  178. NextAttribute,
  179. &LsapDbNames[Accounts],
  180. NULL,
  181. 0L,
  182. FALSE
  183. );
  184. NextAttribute++;
  185. AttributeCount++;
  186. //
  187. // Create the Containing Directory "Domains" for the Trusted Domain
  188. // objects.
  189. //
  190. LsapDbInitializeAttribute(
  191. NextAttribute,
  192. &LsapDbNames[Domains],
  193. NULL,
  194. 0L,
  195. FALSE
  196. );
  197. NextAttribute++;
  198. AttributeCount++;
  199. //
  200. // Create the Containing Directory "Secrets" for the Secret objects.
  201. //
  202. LsapDbInitializeAttribute(
  203. NextAttribute,
  204. &LsapDbNames[Secrets],
  205. NULL,
  206. 0L,
  207. FALSE
  208. );
  209. //
  210. // Create the Lsa Database Policy Object, opening the existing one if
  211. // it exists.
  212. //
  213. NextAttribute++;
  214. AttributeCount++;
  215. //////////////////////////////////////////////////
  216. // //
  217. // ATTRIBUTES BELOW THIS POINT ARE INITIALIZED //
  218. // IN PASS 1, BUT MAY BE CHANGED IN PASS 2. //
  219. // IN GENERAL, THINGS ARE SET FOR A WIN-NT PROD //
  220. // AND CHANGED IN PASS 2 IF NECESSARY. //
  221. // //
  222. //////////////////////////////////////////////////
  223. //
  224. // Initialize the default installed quota limit values
  225. // ALL THIS QUOTA STUFF SHOULD REALLY BE PULLED - it's not used for anything
  226. //
  227. #define LSAP_DB_WINNT_PAGED_POOL (0x02000000L)
  228. #define LSAP_DB_WINNT_NON_PAGED_POOL (0x00100000L)
  229. #define LSAP_DB_WINNT_MIN_WORKING_SET (0x00010000L)
  230. #define LSAP_DB_WINNT_MAX_WORKING_SET (0x0f000000L)
  231. #define LSAP_DB_WINNT_PAGEFILE (0x0f000000L)
  232. InstalledQuotaLimits.PagedPoolLimit = LSAP_DB_WINNT_PAGED_POOL;
  233. InstalledQuotaLimits.NonPagedPoolLimit = LSAP_DB_WINNT_NON_PAGED_POOL;
  234. InstalledQuotaLimits.MinimumWorkingSetSize = LSAP_DB_WINNT_MIN_WORKING_SET;
  235. InstalledQuotaLimits.MaximumWorkingSetSize = LSAP_DB_WINNT_MAX_WORKING_SET;
  236. LsapDbInitializeAttribute(
  237. NextAttribute,
  238. &LsapDbNames[DefQuota],
  239. &InstalledQuotaLimits,
  240. sizeof (QUOTA_LIMITS),
  241. FALSE
  242. );
  243. NextAttribute++;
  244. AttributeCount++;
  245. //
  246. // Initialize the audit log information.
  247. //
  248. InitialAuditLogInformation.MaximumLogSize = 8*1024;
  249. InitialAuditLogInformation.AuditLogPercentFull = 0;
  250. InitialAuditLogInformation.AuditRetentionPeriod.LowPart = 0x823543;
  251. InitialAuditLogInformation.AuditRetentionPeriod.HighPart = 0;
  252. InitialAuditLogInformation.AuditLogFullShutdownInProgress = FALSE;
  253. InitialAuditLogInformation.TimeToShutdown.LowPart = 0x46656;
  254. InitialAuditLogInformation.TimeToShutdown.HighPart = 0;
  255. LsapDbInitializeAttribute(
  256. NextAttribute,
  257. &LsapDbNames[PolAdtLg],
  258. &InitialAuditLogInformation,
  259. sizeof (POLICY_AUDIT_LOG_INFO),
  260. FALSE
  261. );
  262. NextAttribute++;
  263. AttributeCount++;
  264. //
  265. // Initialize the syskey
  266. //
  267. Status = LsapDbSetupInitialSyskey(
  268. &SyskeyLength,
  269. &Syskey
  270. );
  271. if (!NT_SUCCESS(Status)) {
  272. LsapLogError(
  273. "LsapDbInstallPolicyObject: Syskey setup failed 0x%lx\n",
  274. Status
  275. );
  276. goto InstallPolicyObjectError;
  277. }
  278. //
  279. // Initialize the key for secret encryption
  280. //
  281. Status = LsapDbGenerateNewKey(
  282. &NewEncryptionKey
  283. );
  284. if (!NT_SUCCESS(Status)) {
  285. LsapLogError(
  286. "LsapDbInstallPolicyObject: New key generation failed 0x%lx\n",
  287. Status
  288. );
  289. goto InstallPolicyObjectError;
  290. }
  291. //
  292. // Encrypt the key with syskey
  293. //
  294. LsapDbEncryptKeyWithSyskey(
  295. &NewEncryptionKey,
  296. Syskey,
  297. SyskeyLength
  298. );
  299. //
  300. // Set the global variable LsapDbSyskey to reflect this value
  301. //
  302. LsapDbSysKey = Syskey;
  303. //
  304. // Add the attribute for the list of attributes to be added to the database.
  305. //
  306. LsapDbInitializeAttribute(
  307. NextAttribute,
  308. &LsapDbNames[PolSecretEncryptionKey],
  309. &NewEncryptionKey,
  310. sizeof (NewEncryptionKey),
  311. FALSE
  312. );
  313. NextAttribute++;
  314. AttributeCount++;
  315. Status = LsapDbCreateObject(
  316. &ObjectInformation,
  317. GENERIC_ALL,
  318. LSAP_DB_OBJECT_OPEN_IF,
  319. LSAP_DB_TRUSTED,
  320. Attributes,
  321. &AttributeCount,
  322. RTL_NUMBER_OF(Attributes),
  323. &LsapDbHandle
  324. );
  325. if (!NT_SUCCESS(Status)) {
  326. LsapLogError(
  327. "LsapDbInstallPolicyObject: Create Policy object failed 0x%lx\n",
  328. Status
  329. );
  330. LsapDiagPrint( DB_INIT,
  331. ("LSA (init): Attributes passed to CreateObject call:\n\n"
  332. " Count: %d\n"
  333. " Array Address: 0x%lx",
  334. AttributeCount, Attributes) );
  335. ASSERT(NT_SUCCESS(Status)); // Provide a debug opportunity
  336. goto InstallPolicyObjectError;
  337. }
  338. } else if (Pass == 2) {
  339. //
  340. // Set up the account objects necessary to implement the default
  341. // Microsoft Policy for privilege assignment and system access
  342. // capabilities.
  343. //
  344. Status = LsapDbInstallAccountObjects();
  345. if (!NT_SUCCESS(Status)) {
  346. KdPrint(("LSA DB INSTALL: Installation of account objects failed.\n"
  347. " Status: 0x%lx\n", Status));
  348. goto InstallPolicyObjectError;
  349. }
  350. //
  351. // Set up the account domain and primary domain information
  352. // ONLY if the real setup wasn't run. In that case, we are
  353. // doing a pseudo setup as part of a developer's first boot.
  354. //
  355. if (!LsapSetupWasRun) {
  356. LsapDbSetDomainInfo( &NextAttribute, &AttributeCount );
  357. }
  358. if (LsapProductType == NtProductLanManNt) {
  359. //
  360. // Audit log information was set for WinNt product
  361. // in pass 1. Change if necessary in this pass.
  362. //
  363. InitialAuditLogInformation.MaximumLogSize = 20*1024;
  364. InitialAuditLogInformation.AuditLogPercentFull = 0;
  365. InitialAuditLogInformation.AuditRetentionPeriod.LowPart = 0x823543;
  366. InitialAuditLogInformation.AuditRetentionPeriod.HighPart = 0;
  367. InitialAuditLogInformation.AuditLogFullShutdownInProgress = FALSE;
  368. InitialAuditLogInformation.TimeToShutdown.LowPart = 0x46656;
  369. InitialAuditLogInformation.TimeToShutdown.HighPart = 0;
  370. LsapDbInitializeAttribute(
  371. NextAttribute,
  372. &LsapDbNames[PolAdtLg],
  373. &InitialAuditLogInformation,
  374. sizeof (POLICY_AUDIT_LOG_INFO),
  375. FALSE
  376. );
  377. NextAttribute++;
  378. AttributeCount++;
  379. }
  380. if (AttributeCount > 0) {
  381. Status = LsapDbReferenceObject(
  382. LsapDbHandle,
  383. 0,
  384. PolicyObject,
  385. PolicyObject,
  386. LSAP_DB_LOCK | LSAP_DB_START_TRANSACTION
  387. );
  388. if (!NT_SUCCESS(Status)) {
  389. LsapDiagPrint( DB_INIT,
  390. ("LSA (init): Internal reference of Policy object failed.\n"
  391. " Status of LsapDbReferenceObject == 0x%lx\n",
  392. Status) );
  393. goto InstallPolicyObjectError;
  394. }
  395. ObjectReferenced = TRUE;
  396. Status = LsapDbWriteAttributesObject(
  397. LsapDbHandle,
  398. Attributes,
  399. AttributeCount
  400. );
  401. if (!NT_SUCCESS(Status)) {
  402. LsapDiagPrint( DB_INIT,
  403. ("LSA (init): Update of Policy attributes failed.\n"
  404. " Attributes:\n\n"
  405. " Count: %d\n"
  406. " Array Address: 0x%lx",
  407. AttributeCount, Attributes) );
  408. goto InstallPolicyObjectError;
  409. }
  410. Status = LsapDbDereferenceObject(
  411. &LsapDbHandle,
  412. PolicyObject,
  413. PolicyObject,
  414. (LSAP_DB_LOCK |
  415. LSAP_DB_FINISH_TRANSACTION),
  416. (SECURITY_DB_DELTA_TYPE) 0,
  417. STATUS_SUCCESS
  418. );
  419. if (!NT_SUCCESS(Status)) {
  420. LsapLogError(
  421. "LsapDbInstallPolicyObject: Pass 2 DB init failed. 0x%lx\n",
  422. Status
  423. );
  424. goto InstallPolicyObjectError;
  425. }
  426. ObjectReferenced = FALSE;
  427. }
  428. }
  429. InstallPolicyObjectFinish:
  430. //
  431. // If necessary, dereference the Policy Object.
  432. //
  433. if (ObjectReferenced) {
  434. Status = LsapDbDereferenceObject(
  435. &LsapDbHandle,
  436. PolicyObject,
  437. PolicyObject,
  438. (LSAP_DB_LOCK |
  439. LSAP_DB_FINISH_TRANSACTION),
  440. (SECURITY_DB_DELTA_TYPE) 0,
  441. Status
  442. );
  443. }
  444. return(Status);
  445. InstallPolicyObjectError:
  446. if (Pass == 1) {
  447. LsapLogError(
  448. "LsapDbInstallPolicyObject: Pass 1 DB init failed. 0x%lx\n",
  449. Status
  450. );
  451. } else {
  452. LsapLogError(
  453. "LsapDbInstallPolicyObject: Pass 2 DB init failed. 0x%lx\n",
  454. Status
  455. );
  456. }
  457. goto InstallPolicyObjectFinish;
  458. }
  459. NTSTATUS
  460. LsapDbGetConfig (
  461. IN HANDLE KeyHandle,
  462. IN PWSTR Name,
  463. OUT PUNICODE_STRING Value
  464. )
  465. /*++
  466. Routine Description:
  467. This routine obtains configuration information from the registry.
  468. Arguments:
  469. KeyHandle - handle to registry key node containing value.
  470. Name - The name of a value under the specifed key node.
  471. Value - Fills in the string with the value of the parameter. The
  472. returned string is zero terminated. The buffer is allocated in
  473. Process Heap and should be deallocated by the caller.
  474. Return Value:
  475. STATUS_SUCCESS - If the operation was successful.
  476. STATUS_NO_MEMORY - There wasn't enough memory to allocate a buffer
  477. to contain the returned information.
  478. STATUS_OBJECT_NAME_NOT_FOUND - The specifed section or the specified
  479. keyword could not be found.
  480. --*/
  481. {
  482. NTSTATUS Status;
  483. UNICODE_STRING ValueName;
  484. ULONG Length, ResultLength;
  485. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  486. RtlInitUnicodeString( &ValueName, Name );
  487. Length = 512;
  488. KeyValueInformation = RtlAllocateHeap( RtlProcessHeap(), 0, Length );
  489. if (KeyValueInformation == NULL) {
  490. Status = STATUS_NO_MEMORY;
  491. } else {
  492. Status = NtQueryValueKey( KeyHandle,
  493. &ValueName,
  494. KeyValuePartialInformation,
  495. KeyValueInformation,
  496. Length,
  497. &ResultLength
  498. );
  499. if (NT_SUCCESS( Status )) {
  500. if (KeyValueInformation->Type != REG_SZ) {
  501. Status = STATUS_OBJECT_NAME_NOT_FOUND;
  502. }
  503. }
  504. }
  505. if (NT_SUCCESS( Status )) {
  506. Value->MaximumLength = (USHORT)(KeyValueInformation->DataLength);
  507. if (Value->MaximumLength >= sizeof(UNICODE_NULL)) {
  508. Value->Length = (USHORT)KeyValueInformation->DataLength -
  509. sizeof( UNICODE_NULL);
  510. } else {
  511. Value->Length = 0;
  512. }
  513. Value->Buffer = (PWSTR)KeyValueInformation;
  514. RtlMoveMemory( Value->Buffer,
  515. KeyValueInformation->Data,
  516. Value->Length
  517. );
  518. Value->Buffer[ Value->Length / sizeof( WCHAR ) ] = UNICODE_NULL;
  519. KeyValueInformation = NULL;
  520. } else {
  521. #if DEVL
  522. DbgPrint( "LSA DB INSTALL: No '%wZ' value in registry - Status == %x\n", &ValueName, Status);
  523. #endif //DEVL
  524. }
  525. if ( KeyValueInformation != NULL ) {
  526. RtlFreeHeap( RtlProcessHeap(), 0, KeyValueInformation );
  527. }
  528. return Status;
  529. }
  530. NTSTATUS
  531. LsapDbGetNextValueToken(
  532. IN PUNICODE_STRING Value,
  533. IN OUT PULONG ParseContext,
  534. OUT PUNICODE_STRING *ReturnString
  535. )
  536. /*++
  537. Routine Description:
  538. This routine is used to isolate the next token in a registry value.
  539. The token is returned in a single heap buffer containing both the
  540. STRING and the Buffer of that string containing the token. The
  541. caller of this routine is responsible for deallocating the buffer
  542. when it is no longer needed.
  543. The string, although counted, will also be null terminated.
  544. Arguments:
  545. Value - Supplies the value line being parsed.
  546. ParseContext - Is a pointer to a context state value.
  547. The first time this routine is called for a particular
  548. Value line, the value pointed to should be zero. Thereafter,
  549. the value returned from the previous call should be passed.
  550. ReturnString - Returns a pointer to the allocated string.
  551. Return Value:
  552. STATUS_SUCCESS - indicates the next token has been isolated.
  553. STATUS_INVALID_PARAMTER_1 - Indicates there were no more tokens in
  554. the Value line.
  555. STATUS_NO_MEMORY - memory could not be allocated for the token.
  556. --*/
  557. {
  558. ULONG i, j;
  559. ULONG TokenLength;
  560. ULONG AllocSize;
  561. //
  562. // Get to the beginning of the next token
  563. //
  564. for ( i = *ParseContext;
  565. i < (Value->Length/sizeof(WCHAR)) &&
  566. (Value->Buffer[i] == L' ' || Value->Buffer[i] == L'\t');
  567. i++ )
  568. ;
  569. //
  570. // see if we ran off the end of the string..
  571. //
  572. if (i >= (Value->Length/sizeof(WCHAR))) {
  573. return STATUS_INVALID_PARAMETER_1;
  574. }
  575. //
  576. // Now search for the end of the token
  577. //
  578. for ( j = i + 1;
  579. j < (Value->Length/sizeof(WCHAR)) &&
  580. Value->Buffer[j] != L' ' && Value->Buffer[j] != L'\t';
  581. j++ )
  582. ;
  583. *ParseContext = j;
  584. //
  585. // We've either reached the end of the string, or found the end of the
  586. // token.
  587. //
  588. //
  589. // If the caller actually wants the string returned,
  590. // allocate and copy it.
  591. //
  592. if ( ARGUMENT_PRESENT( ReturnString ) ) {
  593. UNICODE_STRING SourceString;
  594. PUNICODE_STRING LocalString;
  595. TokenLength = (j-i) * sizeof(WCHAR);
  596. AllocSize = sizeof(UNICODE_STRING) + (TokenLength + sizeof( UNICODE_NULL ) + 4);
  597. LocalString = RtlAllocateHeap( RtlProcessHeap(), 0, AllocSize );
  598. if ( LocalString == NULL ) {
  599. DbgPrint("LSA DB INSTALL: LsapDbGetNextValueToken: Not enough memory %ld\n",
  600. AllocSize);
  601. return STATUS_NO_MEMORY;
  602. }
  603. LocalString->MaximumLength = (USHORT)(TokenLength + sizeof( UNICODE_NULL ));
  604. LocalString->Length = (USHORT)TokenLength;
  605. LocalString->Buffer = (PWCHAR)(LocalString + 1);
  606. //
  607. // Now copy the token
  608. //
  609. SourceString.MaximumLength = LocalString->Length;
  610. SourceString.Length = LocalString->Length;
  611. SourceString.Buffer = &Value->Buffer[i];
  612. RtlCopyUnicodeString( LocalString, &SourceString );
  613. //
  614. // Add a null terminator
  615. //
  616. LocalString->Buffer[LocalString->Length / sizeof( UNICODE_NULL )] = UNICODE_NULL;
  617. *ReturnString = LocalString;
  618. }
  619. return STATUS_SUCCESS;
  620. }
  621. VOID
  622. LsapDbSetDomainInfo(
  623. IN PLSAP_DB_ATTRIBUTE *NextAttribute,
  624. IN ULONG *AttributeCount
  625. )
  626. /*
  627. This routine is only used for the pseudo setup for internal
  628. developer's use. In a real product installation/setup
  629. situation, The functionality performed by this routine is
  630. performed by the text-mode setup supplemented by the network
  631. setup.
  632. This routine must establish values for the AccountDomain and
  633. PrimaryDomain attributes of the Policy object. These
  634. attributes must be configured as follows:
  635. I. Standalone Win-NT product
  636. AccountDomainName = "Account"
  637. AccountDomainSid = (value assigned by user)
  638. PrimaryDomainName = Name of domain to use for browsing
  639. (this is optional in this case)
  640. PrimaryDomainSid = (None)
  641. II. Non-Standalone Win-NT product
  642. AccountDomainName = "Account"
  643. AccountDomainSid = (value assigned by user)
  644. PrimaryDomainName = (Primary domain's name)
  645. PrimaryDomainSid = (Primary domain's SID)
  646. III. LanMan-NT product
  647. AccountDomainName = (Primary domain's name)
  648. AccountDomainSid = (Primary domain's SID)
  649. PrimaryDomainName = (Primary domain's name)
  650. PrimaryDomainSid = (Primary domain's SID)
  651. This routine only does (II) and (III). The real setup must
  652. be capable of doing (I) as well.
  653. */
  654. {
  655. NTSTATUS Status;
  656. NT_PRODUCT_TYPE ProductType;
  657. BOOLEAN ProductExplicitlySpecified;
  658. UNICODE_STRING PrimaryDomainName, AccountDomainName;
  659. PSID PrimaryDomainSid, AccountDomainSid;
  660. HANDLE KeyHandle = NULL;
  661. OBJECT_ATTRIBUTES ObjectAttributes;
  662. UNICODE_STRING KeyName;
  663. ULONG TempULong = 0 ;
  664. SID_IDENTIFIER_AUTHORITY TmppAuthority;
  665. ULONG DomainSubAuthorities[SID_MAX_SUB_AUTHORITIES];
  666. UCHAR DomainSubAuthorityCount = 0;
  667. ULONG i;
  668. ULONG Context = 0;
  669. PUNICODE_STRING Rid;
  670. ULONG Size;
  671. UNICODE_STRING DomainId;
  672. PrimaryDomainSid = NULL;
  673. AccountDomainSid = NULL;
  674. PrimaryDomainName.Buffer = NULL;
  675. DomainId.Buffer = NULL;
  676. //
  677. // Get the product type
  678. //
  679. ProductExplicitlySpecified =
  680. RtlGetNtProductType( &ProductType );
  681. #if DBG
  682. if (ProductType == NtProductLanManNt) {
  683. DbgPrint("LSA DB INSTALL: Configuring LSA database for LanManNt system.\n");
  684. } else {
  685. DbgPrint("LSA DB INSTALL: Configuring LSA database for WinNt or Dedicated Server product.\n");
  686. }
  687. #endif //DBG
  688. //
  689. // Open a handle to the registry key node that contains the
  690. // interesting domain values (name, id, and account id)
  691. //
  692. RtlInitUnicodeString( &KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanWorkstation\\Parameters" );
  693. InitializeObjectAttributes(
  694. &ObjectAttributes,
  695. &KeyName,
  696. OBJ_CASE_INSENSITIVE,
  697. NULL,
  698. NULL);
  699. Status = NtOpenKey( &KeyHandle, KEY_READ, &ObjectAttributes );
  700. if (!NT_SUCCESS( Status )) {
  701. #if DEVL
  702. DbgPrint( "LSA DB INSTALL: Unable to access registry key (%wZ) - Status == %x\n", &KeyName, Status );
  703. #endif // DBG
  704. goto Exit;
  705. }
  706. //
  707. // Get the primary domain name from the registry
  708. //
  709. Status = LsapDbGetConfig(KeyHandle,
  710. L"Domain",
  711. &PrimaryDomainName);
  712. if ( !NT_SUCCESS( Status ) ) {
  713. goto Exit;
  714. }
  715. //
  716. // get the primary domain's SID
  717. //
  718. Status = LsapDbGetConfig(KeyHandle,
  719. L"DomainId",
  720. &DomainId );
  721. if ( !NT_SUCCESS( Status ) ) {
  722. goto Exit;
  723. }
  724. //
  725. // Get the Authority ID from the registry
  726. //
  727. for (i=0; i < sizeof(TmppAuthority.Value)/sizeof(TmppAuthority.Value[0]); i++ ) {
  728. Status = LsapDbGetNextValueToken( &DomainId, &Context, &Rid );
  729. if (NT_SUCCESS( Status )) {
  730. Status = RtlUnicodeStringToInteger(Rid, 10, &TempULong );
  731. RtlFreeHeap( RtlProcessHeap(), 0, Rid );
  732. }
  733. if ( !NT_SUCCESS( Status ) ) {
  734. #if DBG
  735. DbgPrint("LSA DB INSTALL: domainid - must have at least %ld subauthorities\n",
  736. sizeof(TmppAuthority.Value)/sizeof(TmppAuthority.Value[0]));
  737. #endif //DBG
  738. goto Exit;
  739. }
  740. TmppAuthority.Value[i] = (UCHAR)TempULong;
  741. }
  742. //
  743. // Get some subauthorities from the registry
  744. //
  745. for (i=0; ; i++ ) {
  746. Status = LsapDbGetNextValueToken( &DomainId, &Context, &Rid );
  747. if (NT_SUCCESS( Status )) {
  748. Status = RtlUnicodeStringToInteger(Rid, 10, &TempULong );
  749. RtlFreeHeap( RtlProcessHeap(), 0, Rid );
  750. }
  751. if ( Status == STATUS_INVALID_PARAMETER_1 ) {
  752. break;
  753. }
  754. if ( !NT_SUCCESS( Status )) {
  755. goto Exit;
  756. }
  757. if ( i >= sizeof(DomainSubAuthorities)/sizeof(DomainSubAuthorities[0]) ) {
  758. #if DBG
  759. DbgPrint("LSA DB INSTALL: domainid - "
  760. "Too many Domain subauthorities specified (%ld maximum).\n",
  761. sizeof(DomainSubAuthorities)/sizeof(DomainSubAuthorities[0]));
  762. #endif //DBG
  763. goto Exit;
  764. }
  765. DomainSubAuthorities[i] = TempULong;
  766. DomainSubAuthorityCount ++;
  767. }
  768. //
  769. // Allocate memory to put the domain id in.
  770. //
  771. Size = RtlLengthRequiredSid( DomainSubAuthorityCount );
  772. PrimaryDomainSid = RtlAllocateHeap( RtlProcessHeap(), 0, Size );
  773. if (PrimaryDomainSid == NULL) {
  774. goto Exit;
  775. }
  776. Status = RtlInitializeSid( PrimaryDomainSid,
  777. &TmppAuthority,
  778. DomainSubAuthorityCount );
  779. if ( !NT_SUCCESS( Status )) {
  780. goto Exit;
  781. }
  782. for ( i=0; i < (ULONG) DomainSubAuthorityCount; i++ ) {
  783. *(RtlSubAuthoritySid(PrimaryDomainSid, i)) =
  784. DomainSubAuthorities[i];
  785. }
  786. if (ProductType != NtProductLanManNt) {
  787. DomainSubAuthorityCount = 0;
  788. Context = 0;
  789. //
  790. // if the system is a WinNt product, then get the account domain
  791. // SID from the registry info and set a well known name ("ACCOUNT").
  792. //
  793. RtlInitUnicodeString(&AccountDomainName,L"Account");
  794. //
  795. // Free old DomainId data if it has been allocated previously
  796. //
  797. if (DomainId.Buffer != NULL) {
  798. RtlFreeHeap( RtlProcessHeap(), 0, DomainId.Buffer );
  799. DomainId.Buffer = NULL;
  800. }
  801. Status = LsapDbGetConfig(KeyHandle,
  802. L"AccountDomainId",
  803. &DomainId );
  804. if ( !NT_SUCCESS( Status ) ) {
  805. goto Exit;
  806. }
  807. //
  808. // Get the Authority ID from the registry
  809. //
  810. for (i=0; i<sizeof(TmppAuthority.Value)/sizeof(TmppAuthority.Value[0]); i++ ) {
  811. Status = LsapDbGetNextValueToken( &DomainId, &Context, &Rid );
  812. if (NT_SUCCESS( Status )) {
  813. Status = RtlUnicodeStringToInteger(Rid, 10, &TempULong );
  814. RtlFreeHeap( RtlProcessHeap(), 0, Rid );
  815. }
  816. if ( !NT_SUCCESS( Status ) ) {
  817. #if DBG
  818. DbgPrint("LSA DB INSTALL: AccountDomainId - must have at least %ld subauthorities\n",
  819. sizeof(TmppAuthority.Value)/sizeof(TmppAuthority.Value[0]));
  820. #endif //DBG
  821. goto Exit;
  822. }
  823. TmppAuthority.Value[i] = (UCHAR)TempULong;
  824. }
  825. //
  826. // Get some subauthorities from the registry
  827. //
  828. for (i=0; ; i++ ) {
  829. Status = LsapDbGetNextValueToken( &DomainId, &Context, &Rid );
  830. if (NT_SUCCESS( Status )) {
  831. Status = RtlUnicodeStringToInteger(Rid, 10, &TempULong );
  832. RtlFreeHeap( RtlProcessHeap(), 0, Rid );
  833. }
  834. if ( Status == STATUS_INVALID_PARAMETER_1 ) {
  835. break;
  836. }
  837. if ( !NT_SUCCESS( Status )) {
  838. goto Exit;
  839. }
  840. if ( i >=
  841. sizeof(DomainSubAuthorities)/sizeof(DomainSubAuthorities[0]) ) {
  842. #if DBG
  843. DbgPrint("MsV1_0: NT.CFG: domainid - Too many Domain subauthorities specified (%ld maximum).\n",
  844. sizeof(DomainSubAuthorities)/sizeof(DomainSubAuthorities[0]));
  845. #endif //DBG
  846. goto Exit;
  847. }
  848. DomainSubAuthorities[i] = TempULong;
  849. DomainSubAuthorityCount ++;
  850. }
  851. //
  852. // Allocate memory to put the domain id in.
  853. //
  854. Size = RtlLengthRequiredSid( DomainSubAuthorityCount );
  855. AccountDomainSid = RtlAllocateHeap( RtlProcessHeap(), 0, Size );
  856. if (AccountDomainSid == NULL) {
  857. goto Exit;
  858. }
  859. RtlInitializeSid( AccountDomainSid,
  860. &TmppAuthority,
  861. DomainSubAuthorityCount );
  862. for ( i=0; i < (ULONG) DomainSubAuthorityCount; i++ ) {
  863. *(RtlSubAuthoritySid(AccountDomainSid, i)) =
  864. DomainSubAuthorities[i];
  865. }
  866. } else {
  867. //
  868. // Otherwise, the account domain is set up just like the
  869. // primary domain
  870. //
  871. AccountDomainName = PrimaryDomainName;
  872. Size = RtlLengthSid(PrimaryDomainSid);
  873. AccountDomainSid = RtlAllocateHeap( RtlProcessHeap(), 0, Size );
  874. if (AccountDomainSid == NULL) {
  875. goto Exit;
  876. }
  877. Status = RtlCopySid(
  878. Size,
  879. AccountDomainSid,
  880. PrimaryDomainSid);
  881. if ( !NT_SUCCESS( Status ) ) {
  882. goto Exit;
  883. }
  884. }
  885. //
  886. // Now add the attributes to be initialized in the policy object...
  887. //
  888. //
  889. // Primary domain name/sid
  890. //
  891. Status = LsapDbMakeUnicodeAttribute(
  892. &PrimaryDomainName,
  893. &LsapDbNames[PolPrDmN],
  894. (*NextAttribute)
  895. );
  896. if ( !NT_SUCCESS( Status )) {
  897. goto Exit;
  898. }
  899. (*NextAttribute)++;
  900. (*AttributeCount)++;
  901. Status = LsapDbMakeSidAttribute(
  902. PrimaryDomainSid,
  903. &LsapDbNames[PolPrDmS],
  904. (*NextAttribute)
  905. );
  906. if ( !NT_SUCCESS( Status )) {
  907. goto Exit;
  908. }
  909. PrimaryDomainSid = NULL;
  910. (*NextAttribute)++;
  911. (*AttributeCount)++;
  912. //
  913. // Account domain name/sid
  914. //
  915. Status = LsapDbMakeUnicodeAttribute(
  916. &AccountDomainName,
  917. &LsapDbNames[PolAcDmN],
  918. (*NextAttribute)
  919. );
  920. if ( !NT_SUCCESS( Status )) {
  921. goto Exit;
  922. }
  923. (*NextAttribute)++;
  924. (*AttributeCount)++;
  925. Status = LsapDbMakeSidAttribute(
  926. AccountDomainSid,
  927. &LsapDbNames[PolAcDmS],
  928. (*NextAttribute)
  929. );
  930. if ( !NT_SUCCESS( Status )) {
  931. goto Exit;
  932. }
  933. AccountDomainSid = NULL;
  934. (*NextAttribute)++;
  935. (*AttributeCount)++;
  936. Exit:
  937. if (KeyHandle != NULL) {
  938. NtClose(KeyHandle);
  939. }
  940. if (DomainId.Buffer != NULL) {
  941. RtlFreeHeap( RtlProcessHeap(), 0, DomainId.Buffer );
  942. }
  943. if (PrimaryDomainName.Buffer != NULL) {
  944. RtlFreeHeap( RtlProcessHeap(), 0, PrimaryDomainName.Buffer);
  945. }
  946. if (PrimaryDomainSid != NULL) {
  947. RtlFreeHeap (RtlProcessHeap(), 0, PrimaryDomainSid);
  948. }
  949. if (AccountDomainSid != NULL) {
  950. RtlFreeHeap (RtlProcessHeap(), 0, AccountDomainSid);
  951. }
  952. }