IT:AD:Design:Investigations:Security:Authorisation:DAC:Design
Summary
TODO
Deleting SD's still needs work.
Generic Rights
- Items:
- Summarize
- Read
- Write
- Delete
- Execute
- Link
- Unlink
* Collections:
- List
Access Tokens
MUST: The IIdentity.IsInRole will have to correctly list the Groups the user is in, as well as child Groups, by implication.
Notes
Schema
SD [ID, ObjectType,ObjectRef,OwnerSID] TargetType [ID, Name] ACETYPE [ID, IsHierarchical, Name] ACE [ID, SDFK, AceTypeFK, ObjectTypeCanBeParent, IsInherited,InheritedFromAceFK,TrusteeSID, BitMask] SID [ID, PID, Type, Name]
Queries
Creating and Updating
-- UPSERT THE SD (see: [[IT/AD/SQL Server/HowTo/SQL/DML/Inserts]]):
UPDATE SD
SET OwnerSID=@ownerSID
WHERE ObjectType=@objectType
AND ObjectRef=@objectRef
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO SD (ObjectType, ObjectRef, OwnerSID)
VALUES (@objectType, @objectRef, @ownerSID)
-- Could use a distributed Guid, but if an int:
--SELECT FROM SD ID
-- WHERE ObjectType=@objectType
-- AND OwnerSID=@ownerSID
-- AND ObjectRef=@objectRef
-- SELECT @@IDENTITY
SELECT SCOPE_IDENTITY()
END
-- We are updating a single ACE within the SD.
-- But is there an ACE for the given SD, ACE Type, and Trustee?
SELECT TOP 1
ACE.IsEnherited, InheritedFromAceID
FROM ACE
INNER JOIN SD ON SD.ID = ACE.SDID
WHERE SD.ObjectType = @objectType
AND ACE.Type=? --Accept/Deny
AND SD.ObjectRef =@objectRef
AND ACE.SID= @SID
-- And was it Inherited or not?
-- We need to know this, as:
-- If already not inherited, great. it could be the parent for all child elements.
-- Have to find all ACE's with IsInherited=true, and InheritedFromAceFK with id of this ACE.
-- If inherited...bugger, we have recurse through children, width first, and point it back to this element.
-- If it has CanBeParent=true (ie, not a Db Record, but a FileSystem entry) then have to recurse through those as well.
-- But how to recurse can't be determined from DAC alone...so it's slow.
-- UPSERT THE ACE (see: [[IT/AD/SQL Server/HowTo/SQL/DML/Inserts]]):
UPDATE ACE SET
Type=@aceType, IsEnherited=@isEnherited,
InheritedFromAceID=@inheritedFromAceID,
TrusteeSID=@trusteeSID, BitMask=@bitMask
WHERE
OwnerSID=@sid
IF @@rowcount = 0
BEGIN
INSERT INTO ACE (OwnerSID, Type, IsEnherited, InheritedFromAceID,TrusteeSID,BitMask)
VALUES (@aceType, @isEnherited, @inheritedFromAceID, @trusteeSID, @bitMask)
END
-- SELECT
SELECT FROM ACE
WHERE InheritedFromACEFK=? (this last one updated)
AND OBJECTTYPECANBEPARENT=true
Retrieving
Checking for a single object at a time:
-- SELECT ACEs for a Single Object, Ordered by DENY before ACCEPT: -- Use to Iterate over, using TrusteeSID to look up whether member. -- Get out on first DENY -- If Survive past that get out on first ACCEPT. SELECT SDID, Type, TrusteeSID, BitMask FROM Ace INNER JOIN SD ON SD.ID = ACE.SDID WHERE SD.ObjectType = ? AND SD.OBjectRef = ? ORDER BY ACE.Type ASC, ACE.TrusteeSID DESC
Checking for a page of similar objects (eg: a db query) :
SELECT SDID, Type, TrusteeSID, BitMask FROM Ace INNER JOIN SD ON SD.ID = ACE.SDID WHERE SD.ObjectType = ? AND SD.OBjectRef IN (....) ORDER BY SD.ObjectRef DESC, ACE.Type ASC, ACE.TrusteeSID DESC
Deleting
Deleting an inherited ACE causes no problems, as child elements are pointing to the same exact InheritedFromAceID.
If the element is NonInherited, it could be the parent SD for something else.
Deleting it means we have to make those pointing to this ACE, update to point to a parent ACE of this one…
But where to get that info?
- The SD is not appropriate, as we're talking about individual ACEs (it is possible that an SD has ACEs inheriting from different ascestors). The ACE could…
- The ACE Could have a PID value, but it would mean:
- the ACE's PID would have to be updated by all File System moves.
- the ACE's PID would have to be updated to point to the parent Contact entry (a Contact record is a child ACE of the Contact Type).
- ie, this get's brittle fast.
Another point: Before deleting it, get a list of all ACE's pointing to this OBject, so that after a) figuring out who is the new hierarchical root, we can update them all to point to it.
### Business Rules ###
- DENY always has precedence.
- No SD means total access.
- Note that No SD != SD with no ACE's in its ACL. An empy ACL is the same as:
- Trustee for whom no rule exists has no access.
Implications for the design of Public Websites:T
herefore ensure that in a public site, unauthenticated users are given an IIdentity anyway (Anonymous witin IIS_IUSRS) and an ACE is given to all Objects in the public system.