3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/acl.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
9 * 26/07/98: Added stubs for security functions
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
16 #include <ntdll/ntdll.h>
18 /* FUNCTIONS ***************************************************************/
21 RtlFirstFreeAce(PACL Acl,
28 Current = (PACE)(Acl + 1);
31 if (Acl->AceCount == 0)
36 AclEnd = Acl->AclSize + (PVOID)Acl;
39 if ((PVOID)Current >= AclEnd)
43 if (Current->Header.AceType == 4)
45 if (Acl->AclRevision < 3)
50 Current = (PACE)((PVOID)Current + (ULONG)Current->Header.AceSize);
53 while (i < Acl->AceCount);
55 if ((PVOID)Current < AclEnd)
71 *Ace = (PACE)(Acl + 1);
73 if (Acl->AclRevision != 2 &&
74 Acl->AclRevision != 3)
76 return(STATUS_INVALID_PARAMETER);
79 if (AceIndex >= Acl->AceCount)
81 return(STATUS_INVALID_PARAMETER);
84 for (i = 0; i < AceIndex; i++)
86 if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize)
88 return(STATUS_INVALID_PARAMETER);
90 *Ace = (PACE)((PVOID)(*Ace) + (ULONG)(*Ace)->Header.AceSize);
93 if ((PVOID)*Ace >= (PVOID)Acl + Acl->AclSize)
95 return(STATUS_INVALID_PARAMETER);
98 return(STATUS_SUCCESS);
103 RtlpAddKnownAce(PACL Acl,
105 ACCESS_MASK AccessMask,
111 if (!RtlValidSid(Sid))
113 return(STATUS_INVALID_SID);
115 if (Acl->AclRevision > 3 ||
118 return(STATUS_UNKNOWN_REVISION);
120 if (Revision < Acl->AclRevision)
122 Revision = Acl->AclRevision;
124 if (!RtlFirstFreeAce(Acl, &Ace))
126 return(STATUS_INVALID_ACL);
130 return(STATUS_ALLOTTED_SPACE_EXCEEDED);
132 if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >=
133 ((PVOID)Acl + Acl->AclSize))
135 return(STATUS_ALLOTTED_SPACE_EXCEEDED);
137 Ace->Header.AceFlags = 0;
138 Ace->Header.AceType = Type;
139 Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
140 Ace->AccessMask = AccessMask;
141 RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
143 Acl->AclRevision = Revision;
144 return(STATUS_SUCCESS);
149 RtlAddAccessAllowedAce(PACL Acl,
151 ACCESS_MASK AccessMask,
154 return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 0));
159 RtlAddAccessDeniedAce(PACL Acl,
161 ACCESS_MASK AccessMask,
164 return(RtlpAddKnownAce(Acl, Revision, AccessMask, Sid, 1));
169 RtlpAddData(PVOID AceList,
176 memcpy((PUCHAR)Ace + AceListLength,
181 if (AceListLength != 0)
202 if (Acl->AclRevision != 2 &&
203 Acl->AclRevision != 3)
205 return(STATUS_INVALID_PARAMETER);
208 if (!RtlFirstFreeAce(Acl,&Ace))
210 return(STATUS_INVALID_PARAMETER);
213 if (Acl->AclRevision <= AclRevision)
215 AclRevision = Acl->AclRevision;
218 if (((PVOID)AceList + AceListLength) <= (PVOID)AceList)
220 return(STATUS_INVALID_PARAMETER);
224 Current = (PACE)(Acl + 1);
225 while ((PVOID)Current < ((PVOID)AceList + AceListLength))
227 if (AceList->Header.AceType == 4 &&
230 return(STATUS_INVALID_PARAMETER);
232 Current = (PACE)((PVOID)Current + Current->Header.AceSize);
237 return(STATUS_BUFFER_TOO_SMALL);
240 if (((PVOID)Ace + AceListLength) >= ((PVOID)Acl + Acl->AclSize))
242 return(STATUS_BUFFER_TOO_SMALL);
245 if (StartingIndex != 0)
247 if (Acl->AceCount > 0)
249 Current = (PACE)(Acl + 1);
250 for (j = 0; j < StartingIndex; j++)
252 Current = (PACE)((PVOID)Current + Current->Header.AceSize);
260 (ULONG)Ace - (ULONG)Current);
261 Acl->AceCount = Acl->AceCount + i;
262 Acl->AclRevision = AclRevision;
264 return(STATUS_SUCCESS);
269 RtlAddAuditAccessAce(PACL Acl,
271 ACCESS_MASK AccessMask,
279 if (Success != FALSE)
281 Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
284 if (Failure != FALSE)
286 Flags |= FAILED_ACCESS_ACE_FLAG;
289 if (!RtlValidSid(Sid))
291 return(STATUS_INVALID_SID);
294 if (Acl->AclRevision > 3 ||
297 return(STATUS_REVISION_MISMATCH);
300 if (Revision < Acl->AclRevision)
302 Revision = Acl->AclRevision;
305 if (!RtlFirstFreeAce(Acl, &Ace))
307 return(STATUS_INVALID_ACL);
312 return(STATUS_ALLOTTED_SPACE_EXCEEDED);
315 if (((PVOID)Ace + RtlLengthSid(Sid) + sizeof(ACE)) >= ((PVOID)Acl + Acl->AclSize))
317 return(STATUS_ALLOTTED_SPACE_EXCEEDED);
320 Ace->Header.AceFlags = Flags;
321 Ace->Header.AceType = 2;
322 Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
323 Ace->AccessMask = AccessMask;
324 RtlCopySid(RtlLengthSid(Sid),
328 Acl->AclRevision = Revision;
330 return(STATUS_SUCCESS);
335 RtlpDeleteData(PVOID Ace,
339 if (AceSize < Offset)
342 (PUCHAR)Ace + AceSize,
346 if (Offset - AceSize < Offset)
348 memset((PUCHAR)Ace + Offset - AceSize,
356 RtlDeleteAce(PACL Acl,
362 if (Acl->AclRevision != 2 &&
363 Acl->AclRevision != 3)
365 return(STATUS_INVALID_PARAMETER);
368 if (Acl->AceCount <= AceIndex)
370 return(STATUS_INVALID_PARAMETER);
373 if (!RtlFirstFreeAce(Acl, &Ace))
375 return(STATUS_INVALID_PARAMETER);
378 Current = (PACE)(Acl + 1);
382 Current = (PACE)((PVOID)Current + Current->Header.AceSize);
385 RtlpDeleteData(Current,
386 Current->Header.AceSize,
390 return(STATUS_SUCCESS);
395 RtlCreateAcl(PACL Acl,
401 return(STATUS_BUFFER_TOO_SMALL);
404 if (AclRevision != 2 &&
407 return(STATUS_INVALID_PARAMETER);
410 if (AclSize > 0xffff)
412 return(STATUS_INVALID_PARAMETER);
415 AclSize = AclSize & ~(0x3);
416 Acl->AclSize = AclSize;
417 Acl->AclRevision = AclRevision;
422 return(STATUS_SUCCESS);
427 RtlQueryInformationAcl(PACL Acl,
429 ULONG InformationLength,
430 ACL_INFORMATION_CLASS InformationClass)
434 if (Acl->AclRevision != 2 &&
435 Acl->AclRevision != 3)
437 return(STATUS_INVALID_PARAMETER);
440 switch (InformationClass)
442 case AclRevisionInformation:
444 PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
446 if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
448 return(STATUS_BUFFER_TOO_SMALL);
450 Info->AclRevision = Acl->AclRevision;
454 case AclSizeInformation:
456 PACL_SIZE_INFORMATION Info = (PACL_SIZE_INFORMATION)Information;
458 if (InformationLength < sizeof(ACL_SIZE_INFORMATION))
460 return(STATUS_BUFFER_TOO_SMALL);
463 if (!RtlFirstFreeAce(Acl, &Ace))
465 return(STATUS_INVALID_PARAMETER);
468 Info->AceCount = Acl->AceCount;
471 Info->AclBytesInUse = (PVOID)Ace - (PVOID)Acl;
472 Info->AclBytesFree = Acl->AclSize - Info->AclBytesInUse;
476 Info->AclBytesInUse = Acl->AclSize;
477 Info->AclBytesFree = 0;
483 return(STATUS_INVALID_INFO_CLASS);
486 return(STATUS_SUCCESS);
491 RtlSetInformationAcl(PACL Acl,
493 ULONG InformationLength,
494 ACL_INFORMATION_CLASS InformationClass)
496 if (Acl->AclRevision != 2 &&
497 Acl->AclRevision != 3)
499 return(STATUS_INVALID_PARAMETER);
502 switch (InformationClass)
504 case AclRevisionInformation:
506 PACL_REVISION_INFORMATION Info = (PACL_REVISION_INFORMATION)Information;
508 if (InformationLength < sizeof(ACL_REVISION_INFORMATION))
510 return(STATUS_BUFFER_TOO_SMALL);
513 if (Acl->AclRevision >= Info->AclRevision)
515 return(STATUS_INVALID_PARAMETER);
518 Acl->AclRevision = Info->AclRevision;
523 return(STATUS_INVALID_INFO_CLASS);
526 return(STATUS_SUCCESS);
531 RtlValidAcl(PACL Acl)
536 Size = (Acl->AclSize + 3) & ~3;
538 if (Acl->AclRevision != 2 &&
539 Acl->AclRevision != 3)
544 if (Size != Acl->AclSize)
549 return(RtlFirstFreeAce(Acl, &Ace));