ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

acl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.