/************************************************************************** * RtlAddAce [NTDLL.@] */ NTSTATUS WINAPI RtlAddAce( PACL acl, DWORD rev, DWORD xnrofaces, PACE_HEADER acestart, DWORD acelen) { PACE_HEADER ace,targetace; int nrofaces; if (acl->AclRevision != ACL_REVISION) return STATUS_REVISION_MISMATCH; if (!RtlFirstFreeAce(acl,&targetace)) { if( targetace == NULL ) return STATUS_INVALID_ACL; else return STATUS_ALLOTTED_SPACE_EXCEEDED; } nrofaces=0;ace=acestart; while (((DWORD)ace-(DWORD)acestart)<acelen) { nrofaces++; ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize); } if ((DWORD)targetace+acelen>(DWORD)acl+acl->AclSize) /* too many aces */ return STATUS_ALLOTTED_SPACE_EXCEEDED; memcpy((LPBYTE)targetace,acestart,acelen); acl->AceCount += nrofaces; return STATUS_SUCCESS; }
/****************************************************************************** * RtlAddAccessDeniedAce [NTDLL.@] */ NTSTATUS WINAPI RtlAddAccessDeniedAce( IN OUT PACL pAcl, IN DWORD dwAceRevision, IN DWORD AccessMask, IN PSID pSid) { DWORD dwSidLength; ACCESS_DENIED_ACE* lpADA; TRACE("(%p,0x%08lx,0x%08lx,%p)!\n", pAcl, dwAceRevision, AccessMask, pSid); if( !RtlValidSid( pSid ) ) { return STATUS_INVALID_SID; } dwSidLength = RtlLengthSid( pSid ) - sizeof( DWORD ); if( !RtlFirstFreeAce( pAcl, (PACE_HEADER*)&lpADA) ) { if( lpADA == NULL ) return STATUS_INVALID_ACL; else return STATUS_ALLOTTED_SPACE_EXCEEDED; } if( ((BYTE*)lpADA + sizeof( *lpADA ) + dwSidLength ) > ((BYTE*)pAcl + pAcl->AclSize) ) { return STATUS_ALLOTTED_SPACE_EXCEEDED; } lpADA->Header.AceType = ACCESS_DENIED_ACE_TYPE; lpADA->Header.AceFlags = 0; /* Not set with RtlAddAccessDeniedAce. */ lpADA->Header.AceSize = sizeof( *lpADA ); lpADA->Mask = AccessMask; memcpy( &lpADA->SidStart, pSid, dwSidLength ); pAcl->AceCount++; return STATUS_SUCCESS; }
NTSTATUS NTAPI RtlpAddKnownAce(IN PACL Acl, IN ULONG Revision, IN ULONG Flags, IN ACCESS_MASK AccessMask, IN PSID Sid, IN UCHAR Type) { PKNOWN_ACE Ace; ULONG AceSize, InvalidFlags; PAGED_CODE_RTL(); /* Check the validity of the SID */ if (!RtlValidSid(Sid)) return STATUS_INVALID_SID; /* Check the validity of the revision */ if ((Acl->AclRevision > ACL_REVISION4) || (Revision > ACL_REVISION4)) { return STATUS_REVISION_MISMATCH; } /* Pick the smallest of the revisions */ if (Revision < Acl->AclRevision) Revision = Acl->AclRevision; /* Validate the flags */ if (Type == SYSTEM_AUDIT_ACE_TYPE) { InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS | SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG); } else { InvalidFlags = Flags & ~VALID_INHERIT_FLAGS; } /* If flags are invalid, bail out */ if (InvalidFlags != 0) return STATUS_INVALID_PARAMETER; /* If ACL is invalid, bail out */ if (!RtlValidAcl(Acl)) return STATUS_INVALID_ACL; /* If there's no free ACE, bail out */ if (!RtlFirstFreeAce(Acl, (PACE*)&Ace)) return STATUS_INVALID_ACL; /* Calculate the size of the ACE and bail out if it's too small */ AceSize = RtlLengthSid(Sid) + sizeof(ACE); if (!(Ace) || ((ULONG_PTR)Ace + AceSize > (ULONG_PTR)Acl + Acl->AclSize)) { return STATUS_ALLOTTED_SPACE_EXCEEDED; } /* Initialize the header and common fields */ Ace->Header.AceFlags = (BYTE)Flags; Ace->Header.AceType = Type; Ace->Header.AceSize = (WORD)AceSize; Ace->Mask = AccessMask; /* Copy the SID */ RtlCopySid(RtlLengthSid(Sid), &Ace->SidStart, Sid); /* Fill out the ACL header and return */ Acl->AceCount++; Acl->AclRevision = (BYTE)Revision; return STATUS_SUCCESS; }