Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenacl.c
Go to the documentation of this file.
00001 /* COPYRIGHT: See COPYING in the top level directory 00002 * PROJECT: ReactOS system libraries 00003 * PURPOSE: Security manager 00004 * FILE: lib/rtl/acl.c 00005 * PROGRAMER: David Welch <welch@cwcom.net> 00006 */ 00007 00008 /* INCLUDES *****************************************************************/ 00009 00010 #include <rtl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS ***************************************************************/ 00016 00017 BOOLEAN 00018 NTAPI 00019 RtlFirstFreeAce( 00020 PACL Acl, 00021 PACE* Ace) 00022 { 00023 PACE Current; 00024 ULONG_PTR AclEnd; 00025 ULONG i; 00026 PAGED_CODE_RTL(); 00027 00028 Current = (PACE)(Acl + 1); 00029 *Ace = NULL; 00030 00031 if (Acl->AceCount == 0) 00032 { 00033 *Ace = Current; 00034 return TRUE; 00035 } 00036 00037 i = 0; 00038 AclEnd = (ULONG_PTR)Acl + Acl->AclSize; 00039 do 00040 { 00041 if ((ULONG_PTR)Current >= AclEnd) 00042 { 00043 return FALSE; 00044 } 00045 if (Current->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE && 00046 Acl->AclRevision < ACL_REVISION3) 00047 { 00048 return FALSE; 00049 } 00050 Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize); 00051 } 00052 while (++i < Acl->AceCount); 00053 00054 if ((ULONG_PTR)Current < AclEnd) 00055 { 00056 *Ace = Current; 00057 } 00058 00059 return TRUE; 00060 } 00061 00062 00063 /* 00064 * @implemented 00065 */ 00066 NTSTATUS 00067 NTAPI 00068 RtlGetAce( 00069 PACL Acl, 00070 ULONG AceIndex, 00071 PVOID *Ace) 00072 { 00073 ULONG i; 00074 PAGED_CODE_RTL(); 00075 00076 if (Acl->AclRevision < MIN_ACL_REVISION || 00077 Acl->AclRevision > MAX_ACL_REVISION || 00078 AceIndex >= Acl->AceCount) 00079 { 00080 return STATUS_INVALID_PARAMETER; 00081 } 00082 00083 *Ace = (PVOID)((PACE)(Acl + 1)); 00084 00085 for (i = 0; i < AceIndex; i++) 00086 { 00087 if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize) 00088 { 00089 return STATUS_INVALID_PARAMETER; 00090 } 00091 *Ace = (PVOID)((PACE)((ULONG_PTR)(*Ace) + ((PACE)(*Ace))->Header.AceSize)); 00092 } 00093 00094 if ((ULONG_PTR)*Ace >= (ULONG_PTR)Acl + Acl->AclSize) 00095 { 00096 return STATUS_INVALID_PARAMETER; 00097 } 00098 00099 return STATUS_SUCCESS; 00100 } 00101 00102 00103 static 00104 NTSTATUS 00105 RtlpAddKnownAce( 00106 PACL Acl, 00107 ULONG Revision, 00108 ULONG Flags, 00109 ACCESS_MASK AccessMask, 00110 GUID *ObjectTypeGuid OPTIONAL, 00111 GUID *InheritedObjectTypeGuid OPTIONAL, 00112 PSID Sid, 00113 UCHAR Type) 00114 { 00115 PACE Ace; 00116 PSID SidStart; 00117 ULONG AceSize, InvalidFlags; 00118 ULONG AceObjectFlags = 0; 00119 PAGED_CODE_RTL(); 00120 00121 #if DBG 00122 /* check if RtlpAddKnownAce was called incorrectly */ 00123 if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL) 00124 { 00125 ASSERT(Type == ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE || 00126 Type == ACCESS_ALLOWED_OBJECT_ACE_TYPE || 00127 Type == ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE || 00128 Type == ACCESS_DENIED_OBJECT_ACE_TYPE || 00129 Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE || 00130 Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE); 00131 } 00132 else 00133 { 00134 ASSERT(Type != ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE && 00135 Type != ACCESS_ALLOWED_OBJECT_ACE_TYPE && 00136 Type != ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE && 00137 Type != ACCESS_DENIED_OBJECT_ACE_TYPE && 00138 Type != SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE && 00139 Type != SYSTEM_AUDIT_OBJECT_ACE_TYPE); 00140 } 00141 #endif 00142 00143 if (!RtlValidSid(Sid)) 00144 { 00145 return STATUS_INVALID_SID; 00146 } 00147 00148 if (Type == SYSTEM_MANDATORY_LABEL_ACE_TYPE) 00149 { 00150 static const SID_IDENTIFIER_AUTHORITY MandatoryLabelAuthority = {SECURITY_MANDATORY_LABEL_AUTHORITY}; 00151 00152 /* The SID's identifier authority must be SECURITY_MANDATORY_LABEL_AUTHORITY! */ 00153 if (RtlCompareMemory(&((PISID)Sid)->IdentifierAuthority, 00154 &MandatoryLabelAuthority, 00155 sizeof(MandatoryLabelAuthority)) != sizeof(MandatoryLabelAuthority)) 00156 { 00157 return STATUS_INVALID_PARAMETER; 00158 } 00159 } 00160 00161 if (Acl->AclRevision > MAX_ACL_REVISION || 00162 Revision > MAX_ACL_REVISION) 00163 { 00164 return STATUS_UNKNOWN_REVISION; 00165 } 00166 00167 if (Revision < Acl->AclRevision) 00168 { 00169 Revision = Acl->AclRevision; 00170 } 00171 00172 /* Validate the flags */ 00173 if (Type == SYSTEM_AUDIT_ACE_TYPE || 00174 Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE || 00175 Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE) 00176 { 00177 InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS | 00178 SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG); 00179 } 00180 else 00181 { 00182 InvalidFlags = Flags & ~VALID_INHERIT_FLAGS; 00183 } 00184 00185 if (InvalidFlags != 0) 00186 { 00187 return STATUS_INVALID_PARAMETER; 00188 } 00189 00190 if (!RtlFirstFreeAce(Acl, &Ace)) 00191 { 00192 return STATUS_INVALID_ACL; 00193 } 00194 if (Ace == NULL) 00195 { 00196 return STATUS_ALLOTTED_SPACE_EXCEEDED; 00197 } 00198 00199 /* Calculate the size of the ACE */ 00200 AceSize = RtlLengthSid(Sid) + sizeof(ACE); 00201 if (ObjectTypeGuid != NULL) 00202 { 00203 AceObjectFlags |= ACE_OBJECT_TYPE_PRESENT; 00204 AceSize += sizeof(GUID); 00205 } 00206 if (InheritedObjectTypeGuid != NULL) 00207 { 00208 AceObjectFlags |= ACE_INHERITED_OBJECT_TYPE_PRESENT; 00209 AceSize += sizeof(GUID); 00210 } 00211 00212 if (AceObjectFlags != 0) 00213 { 00214 /* Don't forget the ACE object flags 00215 (corresponds to the Flags field in the *_OBJECT_ACE structures) */ 00216 AceSize += sizeof(ULONG); 00217 } 00218 00219 if ((ULONG_PTR)Ace + AceSize > 00220 (ULONG_PTR)Acl + Acl->AclSize) 00221 { 00222 return STATUS_ALLOTTED_SPACE_EXCEEDED; 00223 } 00224 00225 /* initialize the header and common fields */ 00226 Ace->Header.AceFlags = (BYTE)Flags; 00227 Ace->Header.AceType = Type; 00228 Ace->Header.AceSize = (WORD)AceSize; 00229 Ace->AccessMask = AccessMask; 00230 00231 if (AceObjectFlags != 0) 00232 { 00233 /* Write the ACE flags to the ACE 00234 (corresponds to the Flags field in the *_OBJECT_ACE structures) */ 00235 *(PULONG)(Ace + 1) = AceObjectFlags; 00236 SidStart = (PSID)((ULONG_PTR)(Ace + 1) + sizeof(ULONG)); 00237 } 00238 else 00239 SidStart = (PSID)(Ace + 1); 00240 00241 /* copy the GUIDs */ 00242 if (ObjectTypeGuid != NULL) 00243 { 00244 RtlCopyMemory(SidStart, ObjectTypeGuid, sizeof(GUID)); 00245 SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID)); 00246 } 00247 if (InheritedObjectTypeGuid != NULL) 00248 { 00249 RtlCopyMemory(SidStart, InheritedObjectTypeGuid, sizeof(GUID)); 00250 SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID)); 00251 } 00252 00253 /* copy the SID */ 00254 RtlCopySid(RtlLengthSid(Sid), SidStart, Sid); 00255 Acl->AceCount++; 00256 Acl->AclRevision = (BYTE)Revision; 00257 00258 return STATUS_SUCCESS; 00259 } 00260 00261 00262 /* 00263 * @implemented 00264 */ 00265 NTSTATUS 00266 NTAPI 00267 RtlAddAccessAllowedAce( 00268 IN OUT PACL Acl, 00269 IN ULONG Revision, 00270 IN ACCESS_MASK AccessMask, 00271 IN PSID Sid) 00272 { 00273 PAGED_CODE_RTL(); 00274 00275 return RtlpAddKnownAce(Acl, 00276 Revision, 00277 0, 00278 AccessMask, 00279 NULL, 00280 NULL, 00281 Sid, 00282 ACCESS_ALLOWED_ACE_TYPE); 00283 } 00284 00285 00286 /* 00287 * @implemented 00288 */ 00289 NTSTATUS 00290 NTAPI 00291 RtlAddAccessAllowedAceEx( 00292 IN OUT PACL Acl, 00293 IN ULONG Revision, 00294 IN ULONG Flags, 00295 IN ACCESS_MASK AccessMask, 00296 IN PSID Sid) 00297 { 00298 PAGED_CODE_RTL(); 00299 00300 return RtlpAddKnownAce(Acl, 00301 Revision, 00302 Flags, 00303 AccessMask, 00304 NULL, 00305 NULL, 00306 Sid, 00307 ACCESS_ALLOWED_ACE_TYPE); 00308 } 00309 00310 00311 /* 00312 * @implemented 00313 */ 00314 NTSTATUS 00315 NTAPI 00316 RtlAddAccessAllowedObjectAce( 00317 IN OUT PACL Acl, 00318 IN ULONG Revision, 00319 IN ULONG Flags, 00320 IN ACCESS_MASK AccessMask, 00321 IN GUID *ObjectTypeGuid OPTIONAL, 00322 IN GUID *InheritedObjectTypeGuid OPTIONAL, 00323 IN PSID Sid) 00324 { 00325 UCHAR Type; 00326 PAGED_CODE_RTL(); 00327 00328 /* make sure we call RtlpAddKnownAce correctly */ 00329 if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL) 00330 Type = ACCESS_ALLOWED_OBJECT_ACE_TYPE; 00331 else 00332 Type = ACCESS_ALLOWED_ACE_TYPE; 00333 00334 return RtlpAddKnownAce(Acl, 00335 Revision, 00336 Flags, 00337 AccessMask, 00338 ObjectTypeGuid, 00339 InheritedObjectTypeGuid, 00340 Sid, 00341 Type); 00342 } 00343 00344 00345 /* 00346 * @implemented 00347 */ 00348 NTSTATUS 00349 NTAPI 00350 RtlAddAccessDeniedAce( 00351 PACL Acl, 00352 ULONG Revision, 00353 ACCESS_MASK AccessMask, 00354 PSID Sid) 00355 { 00356 PAGED_CODE_RTL(); 00357 00358 return RtlpAddKnownAce(Acl, 00359 Revision, 00360 0, 00361 AccessMask, 00362 NULL, 00363 NULL, 00364 Sid, 00365 ACCESS_DENIED_ACE_TYPE); 00366 } 00367 00368 00369 /* 00370 * @implemented 00371 */ 00372 NTSTATUS 00373 NTAPI 00374 RtlAddAccessDeniedAceEx( 00375 IN OUT PACL Acl, 00376 IN ULONG Revision, 00377 IN ULONG Flags, 00378 IN ACCESS_MASK AccessMask, 00379 IN PSID Sid) 00380 { 00381 PAGED_CODE_RTL(); 00382 00383 return RtlpAddKnownAce(Acl, 00384 Revision, 00385 Flags, 00386 AccessMask, 00387 NULL, 00388 NULL, 00389 Sid, 00390 ACCESS_DENIED_ACE_TYPE); 00391 } 00392 00393 00394 /* 00395 * @implemented 00396 */ 00397 NTSTATUS 00398 NTAPI 00399 RtlAddAccessDeniedObjectAce( 00400 IN OUT PACL Acl, 00401 IN ULONG Revision, 00402 IN ULONG Flags, 00403 IN ACCESS_MASK AccessMask, 00404 IN GUID *ObjectTypeGuid OPTIONAL, 00405 IN GUID *InheritedObjectTypeGuid OPTIONAL, 00406 IN PSID Sid) 00407 { 00408 UCHAR Type; 00409 PAGED_CODE_RTL(); 00410 00411 /* make sure we call RtlpAddKnownAce correctly */ 00412 if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL) 00413 Type = ACCESS_DENIED_OBJECT_ACE_TYPE; 00414 else 00415 Type = ACCESS_DENIED_ACE_TYPE; 00416 00417 return RtlpAddKnownAce(Acl, 00418 Revision, 00419 Flags, 00420 AccessMask, 00421 ObjectTypeGuid, 00422 InheritedObjectTypeGuid, 00423 Sid, 00424 Type); 00425 } 00426 00427 00428 static 00429 VOID 00430 RtlpAddData( 00431 PVOID AceList, 00432 ULONG AceListLength, 00433 PVOID Ace, 00434 ULONG Offset) 00435 { 00436 if (Offset > 0) 00437 { 00438 RtlCopyMemory((PVOID)((ULONG_PTR)Ace + AceListLength), 00439 Ace, 00440 Offset); 00441 } 00442 00443 if (AceListLength != 0) 00444 { 00445 RtlCopyMemory(Ace, AceList, AceListLength); 00446 } 00447 } 00448 00449 00450 /* 00451 * @implemented 00452 */ 00453 NTSTATUS 00454 NTAPI 00455 RtlAddAce( 00456 PACL Acl, 00457 ULONG AclRevision, 00458 ULONG StartingIndex, 00459 PVOID AceList, 00460 ULONG AceListLength) 00461 { 00462 PACE Ace; 00463 PACE Current; 00464 WORD NewAceCount; 00465 ULONG Index; 00466 PAGED_CODE_RTL(); 00467 00468 /* Make sure, the ACL is valid */ 00469 if (Acl->AclRevision < MIN_ACL_REVISION || 00470 Acl->AclRevision > MAX_ACL_REVISION || 00471 !RtlFirstFreeAce(Acl, &Ace)) 00472 { 00473 return STATUS_INVALID_PARAMETER; 00474 } 00475 00476 /* Check if the ACL revision is smaller than the given one */ 00477 if (Acl->AclRevision <= AclRevision) 00478 { 00479 /* Update the revision to the given one */ 00480 AclRevision = Acl->AclRevision; 00481 } 00482 00483 if (((ULONG_PTR)AceList + AceListLength) <= (ULONG_PTR)AceList) 00484 { 00485 return STATUS_INVALID_PARAMETER; 00486 } 00487 00488 for (Current = AceList, NewAceCount = 0; 00489 (ULONG_PTR)Current < ((ULONG_PTR)AceList + AceListLength); 00490 Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize), 00491 ++NewAceCount) 00492 { 00493 if (((PACE)AceList)->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE && 00494 AclRevision < ACL_REVISION3) 00495 { 00496 return STATUS_INVALID_PARAMETER; 00497 } 00498 } 00499 00500 if (Ace == NULL || 00501 ((ULONG_PTR)Ace + AceListLength) > ((ULONG_PTR)Acl + Acl->AclSize)) 00502 { 00503 return STATUS_BUFFER_TOO_SMALL; 00504 } 00505 00506 Current = (PACE)(Acl + 1); 00507 for (Index = 0; Index < StartingIndex && Index < Acl->AceCount; Index++) 00508 { 00509 Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize); 00510 } 00511 00512 RtlpAddData(AceList, 00513 AceListLength, 00514 Current, 00515 (ULONG)((ULONG_PTR)Ace - (ULONG_PTR)Current)); 00516 00517 Acl->AceCount = Acl->AceCount + NewAceCount; 00518 Acl->AclRevision = (BYTE)AclRevision; 00519 00520 return STATUS_SUCCESS; 00521 } 00522 00523 00524 /* 00525 * @implemented 00526 */ 00527 NTSTATUS 00528 NTAPI 00529 RtlAddAuditAccessAce( 00530 PACL Acl, 00531 ULONG Revision, 00532 ACCESS_MASK AccessMask, 00533 PSID Sid, 00534 BOOLEAN Success, 00535 BOOLEAN Failure) 00536 { 00537 ULONG Flags = 0; 00538 PAGED_CODE_RTL(); 00539 00540 if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; 00541 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG; 00542 00543 return RtlpAddKnownAce(Acl, 00544 Revision, 00545 Flags, 00546 AccessMask, 00547 NULL, 00548 NULL, 00549 Sid, 00550 SYSTEM_AUDIT_ACE_TYPE); 00551 } 00552 00553 00554 /* 00555 * @implemented 00556 */ 00557 NTSTATUS 00558 NTAPI 00559 RtlAddAuditAccessAceEx( 00560 PACL Acl, 00561 ULONG Revision, 00562 ULONG Flags, 00563 ACCESS_MASK AccessMask, 00564 PSID Sid, 00565 BOOLEAN Success, 00566 BOOLEAN Failure) 00567 { 00568 if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; 00569 if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG; 00570 00571 return RtlpAddKnownAce(Acl, 00572 Revision, 00573 Flags, 00574 AccessMask, 00575 NULL, 00576 NULL, 00577 Sid, 00578 SYSTEM_AUDIT_ACE_TYPE); 00579 } 00580 00581 00582 /* 00583 * @implemented 00584 */ 00585 NTSTATUS 00586 NTAPI 00587 RtlAddAuditAccessObjectAce( 00588 PACL Acl, 00589 ULONG Revision, 00590 ULONG Flags, 00591 ACCESS_MASK AccessMask, 00592 IN GUID *ObjectTypeGuid OPTIONAL, 00593 IN GUID *InheritedObjectTypeGuid OPTIONAL, 00594 PSID Sid, 00595 BOOLEAN Success, 00596 BOOLEAN Failure) 00597 { 00598 UCHAR Type; 00599 00600 if (Success) 00601 { 00602 Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; 00603 } 00604 00605 if (Failure) 00606 { 00607 Flags |= FAILED_ACCESS_ACE_FLAG; 00608 } 00609 00610 /* make sure we call RtlpAddKnownAce correctly */ 00611 if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL) 00612 Type = SYSTEM_AUDIT_OBJECT_ACE_TYPE; 00613 else 00614 Type = SYSTEM_AUDIT_ACE_TYPE; 00615 00616 return RtlpAddKnownAce(Acl, 00617 Revision, 00618 Flags, 00619 AccessMask, 00620 ObjectTypeGuid, 00621 InheritedObjectTypeGuid, 00622 Sid, 00623 Type); 00624 } 00625 00626 00627 /* 00628 * @implemented 00629 */ 00630 NTSTATUS 00631 NTAPI 00632 RtlAddMandatoryAce( 00633 IN OUT PACL Acl, 00634 IN ULONG Revision, 00635 IN ULONG Flags, 00636 IN ULONG MandatoryFlags, 00637 IN UCHAR AceType, 00638 IN PSID LabelSid) 00639 { 00640 if (MandatoryFlags & ~SYSTEM_MANDATORY_LABEL_VALID_MASK) 00641 return STATUS_INVALID_PARAMETER; 00642 00643 if (AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) 00644 return STATUS_INVALID_PARAMETER; 00645 00646 return RtlpAddKnownAce(Acl, 00647 Revision, 00648 Flags, 00649 (ACCESS_MASK)MandatoryFlags, 00650 NULL, 00651 NULL, 00652 LabelSid, 00653 AceType); 00654 } 00655 00656 00657 static 00658 VOID 00659 RtlpDeleteData( 00660 PVOID Ace, 00661 ULONG AceSize, 00662 ULONG Offset) 00663 { 00664 if (AceSize < Offset) 00665 { 00666 RtlMoveMemory(Ace, 00667 (PVOID)((ULONG_PTR)Ace + AceSize), 00668 Offset - AceSize); 00669 } 00670 00671 if (Offset - AceSize < Offset) 00672 { 00673 RtlZeroMemory((PVOID)((ULONG_PTR)Ace + Offset - AceSize), AceSize); 00674 } 00675 } 00676 00677 00678 /* 00679 * @implemented 00680 */ 00681 NTSTATUS 00682 NTAPI 00683 RtlDeleteAce( 00684 PACL Acl, 00685 ULONG AceIndex) 00686 { 00687 PACE Ace; 00688 PACE Current; 00689 PAGED_CODE_RTL(); 00690 00691 if (Acl->AclRevision < MIN_ACL_REVISION || 00692 Acl->AclRevision > MAX_ACL_REVISION || 00693 Acl->AceCount <= AceIndex || 00694 !RtlFirstFreeAce(Acl, &Ace)) 00695 { 00696 return STATUS_INVALID_PARAMETER; 00697 } 00698 00699 Current = (PACE)(Acl + 1); 00700 00701 while(AceIndex--) 00702 { 00703 Current = (PACE)((ULONG_PTR)Current + Current->Header.AceSize); 00704 } 00705 00706 RtlpDeleteData(Current, 00707 Current->Header.AceSize, 00708 (ULONG)((ULONG_PTR)Ace - (ULONG_PTR)Current)); 00709 Acl->AceCount--; 00710 00711 return STATUS_SUCCESS; 00712 } 00713 00714 00715 /* 00716 * @implemented 00717 */ 00718 NTSTATUS 00719 NTAPI 00720 RtlCreateAcl( 00721 PACL Acl, 00722 ULONG AclSize, 00723 ULONG AclRevision) 00724 { 00725 PAGED_CODE_RTL(); 00726 00727 if (AclSize < sizeof(ACL)) 00728 { 00729 return STATUS_BUFFER_TOO_SMALL; 00730 } 00731 00732 if (AclRevision < MIN_ACL_REVISION || 00733 AclRevision > MAX_ACL_REVISION || 00734 AclSize > 0xffff) 00735 { 00736 return STATUS_INVALID_PARAMETER; 00737 } 00738 00739 AclSize = ROUND_UP(AclSize, 4); 00740 Acl->AclSize = (WORD)AclSize; 00741 Acl->AclRevision = (BYTE)AclRevision; 00742 Acl->AceCount = 0; 00743 Acl->Sbz1 = 0; 00744 Acl->Sbz2 = 0; 00745 00746 return STATUS_SUCCESS; 00747 } 00748 00749 00750 /* 00751 * @implemented 00752 */ 00753 NTSTATUS 00754 NTAPI 00755 RtlQueryInformationAcl( 00756 PACL Acl, 00757 PVOID Information, 00758 ULONG InformationLength, 00759 ACL_INFORMATION_CLASS InformationClass) 00760 { 00761 PACE Ace; 00762 PAGED_CODE_RTL(); 00763 00764 if (Acl->AclRevision < MIN_ACL_REVISION || 00765 Acl->AclRevision > MAX_ACL_REVISION) 00766 { 00767 return STATUS_INVALID_PARAMETER; 00768 } 00769 00770 switch (InformationClass) 00771 { 00772 case AclRevisionInformation: 00773 { 00774 PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information; 00775 00776 if (InformationLength < sizeof(ACL_REVISION_INFORMATION)) 00777 { 00778 return STATUS_BUFFER_TOO_SMALL; 00779 } 00780 Info->AclRevision = Acl->AclRevision; 00781 } 00782 break; 00783 00784 case AclSizeInformation: 00785 { 00786 PACL_SIZE_INFORMATION Info = (PACL_SIZE_INFORMATION)Information; 00787 00788 if (InformationLength < sizeof(ACL_SIZE_INFORMATION)) 00789 { 00790 return STATUS_BUFFER_TOO_SMALL; 00791 } 00792 00793 if (!RtlFirstFreeAce(Acl, &Ace)) 00794 { 00795 return STATUS_INVALID_PARAMETER; 00796 } 00797 00798 Info->AceCount = Acl->AceCount; 00799 if (Ace != NULL) 00800 { 00801 Info->AclBytesInUse = (DWORD)((ULONG_PTR)Ace - (ULONG_PTR)Acl); 00802 Info->AclBytesFree = Acl->AclSize - Info->AclBytesInUse; 00803 } 00804 else 00805 { 00806 Info->AclBytesInUse = Acl->AclSize; 00807 Info->AclBytesFree = 0; 00808 } 00809 } 00810 break; 00811 00812 default: 00813 return STATUS_INVALID_INFO_CLASS; 00814 } 00815 00816 return STATUS_SUCCESS; 00817 } 00818 00819 00820 /* 00821 * @implemented 00822 */ 00823 NTSTATUS NTAPI 00824 RtlSetInformationAcl(PACL Acl, 00825 PVOID Information, 00826 ULONG InformationLength, 00827 ACL_INFORMATION_CLASS InformationClass) 00828 { 00829 PAGED_CODE_RTL(); 00830 00831 if (Acl->AclRevision < MIN_ACL_REVISION || 00832 Acl->AclRevision > MAX_ACL_REVISION) 00833 { 00834 return STATUS_INVALID_PARAMETER; 00835 } 00836 00837 switch (InformationClass) 00838 { 00839 case AclRevisionInformation: 00840 { 00841 PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information; 00842 00843 if (InformationLength < sizeof(ACL_REVISION_INFORMATION)) 00844 { 00845 return STATUS_BUFFER_TOO_SMALL; 00846 } 00847 00848 if (Acl->AclRevision >= Info->AclRevision) 00849 { 00850 return STATUS_INVALID_PARAMETER; 00851 } 00852 00853 Acl->AclRevision = (BYTE)Info->AclRevision; 00854 } 00855 break; 00856 00857 default: 00858 return STATUS_INVALID_INFO_CLASS; 00859 } 00860 00861 return STATUS_SUCCESS; 00862 } 00863 00864 00865 /* 00866 * @implemented 00867 */ 00868 BOOLEAN 00869 NTAPI 00870 RtlValidAcl(PACL Acl) 00871 { 00872 PACE Ace; 00873 USHORT Size; 00874 PAGED_CODE_RTL(); 00875 00876 Size = ROUND_UP(Acl->AclSize, 4); 00877 00878 if (Acl->AclRevision < MIN_ACL_REVISION || 00879 Acl->AclRevision > MAX_ACL_REVISION) 00880 { 00881 return FALSE; 00882 } 00883 00884 if (Size != Acl->AclSize) 00885 { 00886 return FALSE; 00887 } 00888 00889 return RtlFirstFreeAce(Acl, &Ace); 00890 } 00891 00892 /* EOF */ Generated on Fri May 25 2012 04:34:50 for ReactOS by
1.7.6.1
|