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.

868 lines
23 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dbattr.c
  5. Abstract:
  6. LSA Database Handle Manager - Object Attribute Routines
  7. These routines manipulate or construct LSA Database Object Attributes
  8. or their content.
  9. Author:
  10. Scott Birrell (ScottBi) January 21, 1992
  11. Environment:
  12. Revision History:
  13. --*/
  14. #include <lsapch2.h>
  15. #include "dbp.h"
  16. NTSTATUS
  17. LsapDbMakeUnicodeAttribute(
  18. IN OPTIONAL PUNICODE_STRING UnicodeValue,
  19. IN PUNICODE_STRING AttributeName,
  20. OUT PLSAP_DB_ATTRIBUTE Attribute
  21. )
  22. /*++
  23. Routine Description:
  24. This function constructs Attribute Information for an attribute value
  25. that is in Unicode String form. The Unicode String is converted to
  26. Self-Relative form after validation and the given Attribute
  27. structure is filled in.
  28. If a NULL UnicodeValue, or string of length 0 is specified, NULL is
  29. propagated as the attribute value.
  30. WARNING! - This routine allocates memory for the Self-Relative Unicode
  31. string produced. This memory must be freed after use by calling
  32. MIDL_user_free()
  33. Arguments:
  34. UnicodeValue - Pointer to Unicode String containing the Attribute's
  35. Value. NULL may be specified, in which case, NULL will be stored
  36. in the output Attribute.
  37. AttributeName - Pointer to the Unicode name of the attribute.
  38. Attribute - Pointer to structure that will receive the
  39. attributes's information. This consists of the attribute's name,
  40. value and value length.
  41. Return Value:
  42. NTSTATUS - Standard Nt Result Code
  43. STATUS_INSUFFICIENT_RESOURCES - Insufficient system resources such
  44. as memory to complete the call.
  45. STATUS_INVALID_PARAMETER - The specified AttributeValue is not a
  46. pointer to a Unicode String.
  47. --*/
  48. {
  49. NTSTATUS Status = STATUS_SUCCESS;
  50. PUNICODE_STRING_SR OutputAttributeValue = NULL;
  51. ULONG OutputAttributeValueLength = 0;
  52. RtlZeroMemory( Attribute, sizeof( LSAP_DB_ATTRIBUTE ) );
  53. //
  54. // Mark attribute initially as not having had memory allocated by
  55. // setting MemoryAllocated to FALSE. If routine succeeds and we allocate
  56. // memory via MIDL_user_allocate() change MemoryAllocated field to TRUE.
  57. //
  58. Attribute->MemoryAllocated = FALSE;
  59. if (ARGUMENT_PRESENT(UnicodeValue) && UnicodeValue->Length != 0) {
  60. //
  61. // Validate the string
  62. //
  63. if ( !LsapValidateLsaUnicodeString( UnicodeValue ) ) {
  64. return STATUS_INVALID_PARAMETER;
  65. }
  66. //
  67. // Calculate the size of memory required for a Self-Relative
  68. // Unicode String and allocate the memory.
  69. //
  70. OutputAttributeValueLength =
  71. sizeof(UNICODE_STRING_SR) + (ULONG) UnicodeValue->MaximumLength;
  72. OutputAttributeValue = MIDL_user_allocate(OutputAttributeValueLength);
  73. if (OutputAttributeValue == NULL) {
  74. return(STATUS_INSUFFICIENT_RESOURCES);
  75. }
  76. Attribute->MemoryAllocated = TRUE;
  77. //
  78. // Setup self-relative Unicode String (but with absolute buffer pointer
  79. // referencing buffer following UNICODE_STRING header)
  80. // Copy source Unicode Value to Self-relative Unicode String. Set buffer pointer
  81. // to NULL as it will not be used here.
  82. //
  83. OutputAttributeValue->Length = UnicodeValue->Length;
  84. OutputAttributeValue->MaximumLength = UnicodeValue->MaximumLength;
  85. OutputAttributeValue->Offset = sizeof(UNICODE_STRING_SR);
  86. //
  87. // Copy the Unicode string Buffer
  88. //
  89. RtlCopyMemory( OutputAttributeValue + 1,
  90. UnicodeValue->Buffer,
  91. UnicodeValue->Length );
  92. }
  93. Attribute->AttributeName = AttributeName;
  94. Attribute->AttributeValue = OutputAttributeValue;
  95. Attribute->AttributeValueLength = OutputAttributeValueLength;
  96. return(Status);
  97. }
  98. VOID
  99. LsapDbCopyUnicodeAttributeNoAlloc(
  100. OUT PUNICODE_STRING OutputString,
  101. IN PLSAP_DB_ATTRIBUTE Attribute,
  102. IN BOOLEAN SelfRelative
  103. )
  104. /*++
  105. Routine Description:
  106. This function makes a UNICODE_STRING structure reference the value of
  107. an attribute that has a Unicode String as its value. No memory is allocated
  108. for the attribute values's Unicode Buffer.
  109. Arguments:
  110. OutputString - Pointer to UNICODE_STRING structure that will be made
  111. to reference the attribute value's Unicode Buffer.
  112. Attribute - Pointer to attribute information block whose
  113. AttributeValue field is a pointer to a Unicode String,
  114. or NULL. If NULL or if the string has length 0, the output Unicode
  115. String is initialized with a buffer pointer equal to NULL and a zero
  116. length.
  117. SelfRelative - TRUE if the input Unicode String is expected to be
  118. in Self-Relative form, else FALSE.
  119. Returns:
  120. Nothing
  121. --*/
  122. {
  123. UNICODE_STRING AbsInputUnicodeString;
  124. PUNICODE_STRING InputUnicodeString;
  125. PUNICODE_STRING ReturnedUnicodeString = NULL;
  126. //
  127. // The Length field will be accessed before we know whether we have
  128. // a self-relative string structure.
  129. //
  130. C_ASSERT( FIELD_OFFSET( UNICODE_STRING, Length ) ==
  131. FIELD_OFFSET( UNICODE_STRING_SR, Length ));
  132. //
  133. // Obtain pointer to input Unicode String contained in Attribute.
  134. // Convert it to absolute form if necessary.
  135. //
  136. InputUnicodeString = (PUNICODE_STRING) Attribute->AttributeValue;
  137. if ((InputUnicodeString != NULL) && (InputUnicodeString->Length != 0)) {
  138. if (SelfRelative) {
  139. PUNICODE_STRING_SR InputUnicodeStringSr;
  140. InputUnicodeStringSr =
  141. (PUNICODE_STRING_SR) Attribute->AttributeValue;
  142. AbsInputUnicodeString.Length = InputUnicodeStringSr->Length;
  143. AbsInputUnicodeString.MaximumLength =
  144. InputUnicodeStringSr->MaximumLength;
  145. AbsInputUnicodeString.Buffer =
  146. (PWSTR)
  147. (((PUCHAR)(InputUnicodeStringSr)) +
  148. InputUnicodeStringSr->Offset);
  149. InputUnicodeString = &AbsInputUnicodeString;
  150. }
  151. OutputString->Buffer = InputUnicodeString->Buffer;
  152. OutputString->Length = InputUnicodeString->Length;
  153. OutputString->MaximumLength = InputUnicodeString->MaximumLength;
  154. } else {
  155. //
  156. // The attribute contains a NULL Unicode String or one of length
  157. // 0. Set the output Unicode String to NULL.
  158. //
  159. OutputString->Length = OutputString->MaximumLength = 0;
  160. OutputString->Buffer = (PWSTR) NULL;
  161. }
  162. }
  163. NTSTATUS
  164. LsapDbCopyUnicodeAttribute(
  165. OUT PUNICODE_STRING OutputString,
  166. IN PLSAP_DB_ATTRIBUTE Attribute,
  167. IN BOOLEAN SelfRelative
  168. )
  169. /*++
  170. Routine Description:
  171. This function makes a UNICODE_STRING structure reference the value of
  172. an attribute that has a Unicode String as its value. Memory for the
  173. attribute values's Unicode Buffer is allocated via MIDL_user_allocate.
  174. Arguments:
  175. OutputString - Pointer to UNICODE_STRING structure that will be made
  176. to reference the attribute value's Unicode Buffer.
  177. Attribute - Pointer to attribute information block whose
  178. AttributeValue field is a pointer to a Unicode String,
  179. or NULL. If NULL or if the string has length 0, the output Unicode String is initialized
  180. with a buffer pointer equal to NULL and a zero length.
  181. SelfRelative - TRUE if the input Unicode String is expected to be
  182. in Self-Relative form, else FALSE.
  183. Return Value:
  184. NTSTATUS - Standard Nt Result Code
  185. STATUS_SUCCESS - The call was successful
  186. STATUS_INSUFFICIENT_RESOURCES - Insufficient system resources
  187. such as memory to complete the call.
  188. --*/
  189. {
  190. NTSTATUS Status = STATUS_SUCCESS;
  191. UNICODE_STRING AbsInputUnicodeString;
  192. PUNICODE_STRING InputUnicodeString;
  193. PUNICODE_STRING_SR InputUnicodeStringSr;
  194. PUNICODE_STRING ReturnedUnicodeString = NULL;
  195. //
  196. // The Length field will be accessed before we know whether we have
  197. // a self-relative string structure.
  198. //
  199. C_ASSERT( FIELD_OFFSET( UNICODE_STRING, Length ) ==
  200. FIELD_OFFSET( UNICODE_STRING_SR, Length ));
  201. //
  202. // Obtain pointer to input Unicode String contained in Attribute.
  203. // Convert it to absolute form if necessary.
  204. //
  205. InputUnicodeString = (PUNICODE_STRING) Attribute->AttributeValue;
  206. if ((InputUnicodeString != NULL) && (InputUnicodeString->Length != 0)) {
  207. if (SelfRelative) {
  208. InputUnicodeStringSr =
  209. (PUNICODE_STRING_SR) Attribute->AttributeValue;
  210. AbsInputUnicodeString.Length = InputUnicodeStringSr->Length;
  211. AbsInputUnicodeString.MaximumLength =
  212. InputUnicodeStringSr->MaximumLength;
  213. AbsInputUnicodeString.Buffer =
  214. (PWSTR)
  215. (((PUCHAR)(InputUnicodeStringSr)) +
  216. InputUnicodeStringSr->Offset);
  217. InputUnicodeString = &AbsInputUnicodeString;
  218. }
  219. //
  220. // Now allocate memory for the Unicode String Buffer.
  221. //
  222. OutputString->Buffer =
  223. MIDL_user_allocate(InputUnicodeString->MaximumLength);
  224. if (OutputString->Buffer == NULL) {
  225. return(STATUS_INSUFFICIENT_RESOURCES);
  226. }
  227. //
  228. // Initialize UNICODE_STRING header
  229. //
  230. OutputString->Length = InputUnicodeString->Length;
  231. OutputString->MaximumLength = InputUnicodeString->MaximumLength;
  232. //
  233. // Copy the input Unicode String
  234. //
  235. RtlCopyUnicodeString( OutputString, InputUnicodeString );
  236. } else {
  237. //
  238. // The attribute contains a NULL Unicode String or one of length
  239. // 0. Set the output Unicode String to NULL.
  240. //
  241. OutputString->Length = OutputString->MaximumLength = 0;
  242. OutputString->Buffer = (PWSTR) NULL;
  243. }
  244. return(Status);
  245. }
  246. NTSTATUS
  247. LsapDbMakeSidAttribute(
  248. IN OPTIONAL PSID Sid,
  249. IN PUNICODE_STRING AttributeName,
  250. OUT PLSAP_DB_ATTRIBUTE Attribute
  251. )
  252. /*++
  253. Routine Description:
  254. This function constructs Attribute Information for an attribute value
  255. that is in Sid form. The Sid is validated and the given
  256. Attribute structure is filled in.
  257. Arguments:
  258. Sid - Pointer to the Sid or NULL.
  259. AttributeName - Pointer to the Unicode name of the attribute.
  260. Attribute - Pointer to structure that will receive the
  261. attributes's information. This consists of the attribute's name,
  262. value and value length.
  263. Return Value:
  264. NTSTATUS - Standard Nt Result Code
  265. STATUS_INVALID_PARAMETER - The specified AttributeValue is not a
  266. pointer to a syntactically valid Sid, or NULL.
  267. --*/
  268. {
  269. NTSTATUS Status = STATUS_SUCCESS;
  270. RtlZeroMemory( Attribute, sizeof( LSAP_DB_ATTRIBUTE ) );
  271. Attribute->AttributeName = AttributeName;
  272. Attribute->MemoryAllocated = FALSE;
  273. if (ARGUMENT_PRESENT(Sid)) {
  274. if (RtlValidSid(Sid)) {
  275. Attribute->AttributeValue = Sid;
  276. Attribute->AttributeValueLength = RtlLengthSid(Sid);
  277. return(Status);
  278. }
  279. Status = STATUS_INVALID_PARAMETER;
  280. }
  281. //
  282. // The supplied Sid is NULL or invalid.
  283. //
  284. Attribute->AttributeValue = NULL;
  285. Attribute->AttributeValueLength = 0;
  286. return(Status);
  287. }
  288. NTSTATUS
  289. LsapDbMakeGuidAttribute(
  290. IN OPTIONAL GUID *Guid,
  291. IN PUNICODE_STRING AttributeName,
  292. OUT PLSAP_DB_ATTRIBUTE Attribute
  293. )
  294. /*++
  295. Routine Description:
  296. This function constructs Attribute Information for an attribute value
  297. that is in GUID form. The given Attribute structure is filled in.
  298. Arguments:
  299. Guid - Pointer to the GUID or NULL.
  300. AttributeName - Pointer to the Unicode name of the attribute.
  301. Attribute - Pointer to structure that will receive the
  302. attributes's information. This consists of the attribute's name,
  303. value and value length.
  304. Return Value:
  305. NTSTATUS - Standard Nt Result Code
  306. STATUS_INVALID_PARAMETER - The specified AttributeValue is not a
  307. pointer to a syntactically valid Sid, or NULL.
  308. --*/
  309. {
  310. NTSTATUS Status = STATUS_SUCCESS;
  311. RtlZeroMemory( Attribute, sizeof( LSAP_DB_ATTRIBUTE ) );
  312. Attribute->AttributeName = AttributeName;
  313. Attribute->MemoryAllocated = FALSE;
  314. if (ARGUMENT_PRESENT(Guid)) {
  315. Attribute->AttributeValue = Guid;
  316. Attribute->AttributeValueLength = sizeof(GUID);
  317. return(Status);
  318. }
  319. //
  320. // The supplied GUID is NULL
  321. //
  322. Attribute->AttributeValue = NULL;
  323. Attribute->AttributeValueLength = 0;
  324. return(Status);
  325. }
  326. NTSTATUS
  327. LsapDbReadAttribute(
  328. IN LSAPR_HANDLE ObjectHandle,
  329. IN OUT PLSAP_DB_ATTRIBUTE Attribute
  330. )
  331. /*++
  332. Routine Description:
  333. This function reads an attribute of an object, allocating memory if
  334. requested for the buffer containing the attribute's value.
  335. Arguments:
  336. ObjectHandle - Handle to object obtained from LsapDbCreateObject or
  337. LsapDbOpenObject
  338. Attributes - Pointer to an array of Attribute Information blocks each
  339. containing pointers to the attribute's Unicode Name, an optional
  340. pointer to a buffer that will receive the value and an optional
  341. length of the value expected in bytes.
  342. If the AttributeValue field in this structure is specified as non-NULL,
  343. the attribute's data will be returned in the specified buffer. In
  344. this case, the AttributeValueLength field must specify a sufficiently
  345. large buffer size in bytes. If the specified size is too small,
  346. a warning is returned and the buffer size required is returned in
  347. AttributeValueLength.
  348. If the AttributeValue field in this structure is NULL, the routine
  349. will allocate memory for the attribute value's buffer, via MIDL_user_allocate(). If
  350. the AttributeValueLength field is non-zero, the number of bytes specified
  351. will be allocated. If the size of buffer allocated is too small to
  352. hold the attribute's value, a warning is returned. If the
  353. AttributeValuelength field is 0, the routine will first query the size
  354. of buffer required and then allocate its memory.
  355. In all success cases and buffer overflow cases, the
  356. AttributeValueLength is set upon exit to the size of data required.
  357. Return Value:
  358. NTSTATUS - Standard Nt Result Code
  359. --*/
  360. {
  361. NTSTATUS Status = STATUS_SUCCESS;
  362. LSAP_DB_ATTRIBUTE DsAttribute;
  363. if (Attribute->AttributeValue != NULL) {
  364. if (Attribute->AttributeValueLength == 0) {
  365. return(STATUS_INVALID_PARAMETER);
  366. }
  367. }
  368. //
  369. // Deal with the Ds case seperately
  370. //
  371. if ( LsapDsIsWriteDs( ObjectHandle ) &&
  372. Attribute->DbNameIndex != SecDesc ) {
  373. RtlCopyMemory( &DsAttribute, Attribute, sizeof( LSAP_DB_ATTRIBUTE ) );
  374. //
  375. // Now, do the read...
  376. //
  377. Status = LsapDsReadAttributes( &((LSAP_DB_HANDLE)ObjectHandle)->PhysicalNameDs,
  378. LSAPDS_OP_NO_LOCK,
  379. &DsAttribute,
  380. 1 );
  381. if ( NT_SUCCESS( Status ) ) {
  382. Attribute->AttributeValueLength = DsAttribute.AttributeValueLength;
  383. if ( Attribute->AttributeValue != NULL ) {
  384. if ( Attribute->AttributeValueLength >= DsAttribute.AttributeValueLength ) {
  385. RtlCopyMemory( Attribute->AttributeValue, DsAttribute.AttributeValue,
  386. DsAttribute.AttributeValueLength );
  387. } else {
  388. Status = STATUS_BUFFER_OVERFLOW;
  389. }
  390. } else {
  391. Attribute->AttributeValue = DsAttribute.AttributeValue;
  392. DsAttribute.AttributeValue = NULL;
  393. }
  394. MIDL_user_free( DsAttribute.AttributeValue );
  395. }
  396. return( Status );
  397. }
  398. Attribute->MemoryAllocated = FALSE;
  399. //
  400. // If an explicit buffer pointer is given, verify that the length
  401. // specified is non-zero and attempt to use that buffer.
  402. //
  403. if (Attribute->AttributeValue != NULL) {
  404. if (Attribute->AttributeValueLength == 0) {
  405. return(STATUS_INVALID_PARAMETER);
  406. }
  407. Status = LsapDbReadAttributeObject(
  408. ObjectHandle,
  409. Attribute->AttributeName,
  410. Attribute->AttributeValue,
  411. &Attribute->AttributeValueLength
  412. );
  413. if (!NT_SUCCESS(Status)) {
  414. goto ReadAttributeError;
  415. }
  416. return(Status);
  417. }
  418. //
  419. // No output buffer pointer has been given. If a zero buffer
  420. // size is given, query size of memory required. Since the
  421. // buffer length is 0, STATUS_SUCCESS should be returned rather
  422. // than STATUS_BUFFER_OVERFLOW.
  423. //
  424. if (Attribute->AttributeValueLength == 0) {
  425. Status = LsapDbReadAttributeObject(
  426. ObjectHandle,
  427. Attribute->AttributeName,
  428. NULL,
  429. &Attribute->AttributeValueLength
  430. );
  431. if (!NT_SUCCESS(Status)) {
  432. goto ReadAttributeError;
  433. }
  434. Status = STATUS_SUCCESS;
  435. }
  436. //
  437. // If the attribute value size needed is 0, return NULL pointer
  438. //
  439. if (Attribute->AttributeValueLength == 0) {
  440. Attribute->AttributeValue = NULL;
  441. return(STATUS_SUCCESS);
  442. }
  443. //
  444. // Allocate memory for the buffer.
  445. //
  446. Attribute->AttributeValue =
  447. MIDL_user_allocate(Attribute->AttributeValueLength);
  448. if (Attribute->AttributeValue == NULL) {
  449. Status = STATUS_INSUFFICIENT_RESOURCES;
  450. goto ReadAttributeError;
  451. }
  452. Attribute->MemoryAllocated = TRUE;
  453. //
  454. // Now read the attribute into the buffer.
  455. //
  456. Status = LsapDbReadAttributeObject(
  457. ObjectHandle,
  458. Attribute->AttributeName,
  459. Attribute->AttributeValue,
  460. &Attribute->AttributeValueLength
  461. );
  462. if (!NT_SUCCESS(Status)) {
  463. goto ReadAttributeError;
  464. }
  465. ReadAttributeFinish:
  466. return(Status);
  467. ReadAttributeError:
  468. //
  469. // If memory was allocated for any values read, it must be freed.
  470. //
  471. if (Attribute->MemoryAllocated) {
  472. MIDL_user_free( Attribute->AttributeValue );
  473. }
  474. goto ReadAttributeFinish;
  475. }
  476. NTSTATUS
  477. LsapDbFreeAttributes(
  478. IN ULONG Count,
  479. IN PLSAP_DB_ATTRIBUTE Attributes
  480. )
  481. /*++
  482. Routine Description:
  483. This function frees memory allocated for Attribute Values in an
  484. array of attributes.
  485. Arguments:
  486. Count - Count of attributes in the array
  487. Attributes - Pointer to array of attributes. Only those attributes
  488. in which MemoryAllocated is set to TRUE will have their
  489. Attribute Value buffers freed. For these attributes, MemoryAllocated
  490. will be set to false.
  491. --*/
  492. {
  493. NTSTATUS Status = STATUS_SUCCESS;
  494. ULONG Index;
  495. for (Index = 0; Index < Count; Index++) {
  496. if (Attributes[Index].MemoryAllocated) {
  497. MIDL_user_free(Attributes[Index].AttributeValue);
  498. Attributes[Index].MemoryAllocated = FALSE;
  499. Attributes[Index].AttributeValue = NULL;
  500. Attributes[Index].AttributeValueLength = 0;
  501. }
  502. }
  503. return(Status);
  504. }
  505. NTSTATUS
  506. LsapDbMakeUnicodeAttributeDs(
  507. IN OPTIONAL PUNICODE_STRING UnicodeValue,
  508. IN LSAP_DB_NAMES Name,
  509. OUT PLSAP_DB_ATTRIBUTE Attribute
  510. )
  511. {
  512. NTSTATUS Status = LsapDbMakeUnicodeAttribute( UnicodeValue,
  513. &LsapDbNames[Name],
  514. Attribute );
  515. if ( NT_SUCCESS( Status ) ) {
  516. Attribute->DsAttId = LsapDbDsAttInfo[Name].AttributeId;
  517. Attribute->AttribType = LsapDbDsAttInfo[Name].AttributeType;
  518. Attribute->DbNameIndex = Name;
  519. }
  520. return( Status );
  521. }
  522. NTSTATUS
  523. LsapDbMakeSidAttributeDs(
  524. IN PSID Sid,
  525. IN IN LSAP_DB_NAMES Name,
  526. OUT PLSAP_DB_ATTRIBUTE Attribute
  527. )
  528. {
  529. NTSTATUS Status = LsapDbMakeSidAttribute( Sid,
  530. &LsapDbNames[Name],
  531. Attribute );
  532. if ( NT_SUCCESS( Status ) ) {
  533. Attribute->DsAttId = LsapDbDsAttInfo[Name].AttributeId;
  534. Attribute->AttribType = LsapDbDsAttInfo[Name].AttributeType;
  535. Attribute->DbNameIndex = Name;
  536. }
  537. return( Status );
  538. }
  539. NTSTATUS
  540. LsapDbMakeGuidAttributeDs(
  541. IN GUID *Guid,
  542. IN LSAP_DB_NAMES Name,
  543. OUT PLSAP_DB_ATTRIBUTE Attribute
  544. )
  545. {
  546. NTSTATUS Status = LsapDbMakeGuidAttribute( Guid,
  547. &LsapDbNames[Name],
  548. Attribute );
  549. if ( NT_SUCCESS( Status ) ) {
  550. Attribute->DsAttId = LsapDbDsAttInfo[Name].AttributeId;
  551. Attribute->AttribType = LsapDbDsAttInfo[Name].AttributeType;
  552. Attribute->DbNameIndex = Name;
  553. }
  554. return( Status );
  555. }
  556. NTSTATUS
  557. LsapDbMakePByteAttributeDs(
  558. IN OPTIONAL PBYTE Buffer,
  559. IN ULONG BufferLength,
  560. IN LSAP_DB_ATTRIB_TYPE AttribType,
  561. IN PUNICODE_STRING AttributeName,
  562. OUT PLSAP_DB_ATTRIBUTE Attribute
  563. )
  564. /*++
  565. Routine Description:
  566. This function constructs Attribute Information for an attribute value
  567. that is in Sid form. The Sid is validated and the given
  568. Attribute structure is filled in.
  569. Arguments:
  570. Sid - Pointer to the Sid or NULL.
  571. AttributeName - Pointer to the Unicode name of the attribute.
  572. Attribute - Pointer to structure that will receive the
  573. attributes's information. This consists of the attribute's name,
  574. value and value length.
  575. Return Value:
  576. NTSTATUS - Standard Nt Result Code
  577. STATUS_INVALID_PARAMETER - The specified AttributeValue is not a
  578. pointer to a syntactically valid Sid, or NULL.
  579. --*/
  580. {
  581. NTSTATUS Status = STATUS_SUCCESS;
  582. Attribute->AttributeName = AttributeName;
  583. Attribute->MemoryAllocated = FALSE;
  584. if (ARGUMENT_PRESENT(Buffer)) {
  585. Attribute->AttributeValue = Buffer;
  586. Attribute->AttributeValueLength = BufferLength;
  587. } else {
  588. //
  589. // The supplied Sid is NULL or invalid.
  590. //
  591. Attribute->AttributeValue = NULL;
  592. Attribute->AttributeValueLength = 0;
  593. }
  594. Attribute->DsAttId = LsapDbDsAttInfo[Name].AttributeId;
  595. Attribute->AttribType = AttribType;
  596. Attribute->DbNameIndex = Name;
  597. return(Status);
  598. }