ACEpublic class ACE extends Object An Access Control Entry (ACE) is an element in a security descriptor
such as those associated with files and directories. The Windows OS
determines which users have the necessary permissions to access objects
based on these entries.
To fully understand the information exposed by this class a description
of the access check algorithm used by Windows is required. The following
is a basic description of the algorithm. For a more complete description
we recommend reading the section on Access Control in Keith Brown's
"The .NET Developer's Guide to Windows Security" (which is also
available online).
Direct ACEs are evaluated first in order. The SID of the user performing
the operation and the desired access bits are compared to the SID
and access mask of each ACE. If the SID matches, the allow/deny flags
and access mask are considered. If the ACE is a "deny"
ACE and any of the desired access bits match bits in the access
mask of the ACE, the whole access check fails. If the ACE is an "allow"
ACE and all of the bits in the desired access bits match bits in
the access mask of the ACE, the access check is successful. Otherwise,
more ACEs are evaluated until all desired access bits (combined)
are "allowed". If all of the desired access bits are not "allowed"
the then same process is repeated for inherited ACEs.
For example, if user WNET\alice tries to open a file
with desired access bits 0x00000003 (FILE_READ_DATA |
FILE_WRITE_DATA) and the target file has the following security
descriptor ACEs:
Allow WNET\alice 0x001200A9 Direct
Allow Administrators 0x001F01FF Inherited
Allow SYSTEM 0x001F01FF Inherited
the access check would fail because the direct ACE has an access mask
of 0x001200A9 which doesn't have the
FILE_WRITE_DATA bit on (bit 0x00000002). Actually, this isn't quite correct. If
WNET\alice is in the local Administrators group the access check
will succeed because the inherited ACE allows local Administrators
both FILE_READ_DATA and FILE_WRITE_DATA access. |
Fields Summary |
---|
public static final int | FILE_READ_DATA | public static final int | FILE_WRITE_DATA | public static final int | FILE_APPEND_DATA | public static final int | FILE_READ_EA | public static final int | FILE_WRITE_EA | public static final int | FILE_EXECUTE | public static final int | FILE_DELETE | public static final int | FILE_READ_ATTRIBUTES | public static final int | FILE_WRITE_ATTRIBUTES | public static final int | DELETE | public static final int | READ_CONTROL | public static final int | WRITE_DAC | public static final int | WRITE_OWNER | public static final int | SYNCHRONIZE | public static final int | GENERIC_ALL | public static final int | GENERIC_EXECUTE | public static final int | GENERIC_WRITE | public static final int | GENERIC_READ | public static final int | FLAGS_OBJECT_INHERIT | public static final int | FLAGS_CONTAINER_INHERIT | public static final int | FLAGS_NO_PROPAGATE | public static final int | FLAGS_INHERIT_ONLY | public static final int | FLAGS_INHERITED | boolean | allow | int | flags | int | access | SID | sid |
Methods Summary |
---|
void | appendCol(java.lang.StringBuffer sb, java.lang.String str, int width)
sb.append(str);
int count = width - str.length();
for (int i = 0; i < count; i++) {
sb.append(' ");
}
| int | decode(byte[] buf, int bi)
allow = buf[bi++] == (byte)0x00;
flags = buf[bi++] & 0xFF;
int size = ServerMessageBlock.readInt2(buf, bi);
bi += 2;
access = ServerMessageBlock.readInt4(buf, bi);
bi += 4;
sid = new SID(buf, bi);
return size;
| public int | getAccessMask()Returns the access mask accociated with this ACE. Use the
constants for FILE_READ_DATA, FILE_WRITE_DATA,
READ_CONTROL, GENERIC_ALL, etc with bitwise
operators to determine which bits of the mask are on or off.
return access;
| public java.lang.String | getApplyToText()Returns the 'Apply To' text for inheritance of ACEs on
directories such as 'This folder, subfolder and files'. For
files the text is always 'This object only'.
switch (flags & (FLAGS_OBJECT_INHERIT | FLAGS_CONTAINER_INHERIT | FLAGS_INHERIT_ONLY)) {
case 0x00:
return "This folder only";
case 0x03:
return "This folder, subfolders and files";
case 0x0B:
return "Subfolders and files only";
case 0x02:
return "This folder and subfolders";
case 0x0A:
return "Subfolders only";
case 0x01:
return "This folder and files";
case 0x09:
return "Files only";
}
return "Invalid";
| public int | getFlags()Returns the flags for this ACE. The isInherited()
method checks the FLAGS_INHERITED bit in these flags.
return flags;
| public SID | getSID()Return the SID associated with this ACE.
return sid;
| public boolean | isAllow()Returns true if this ACE is an allow ACE and false if it is a deny ACE.
return allow;
| public boolean | isInherited()Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
Note: For reasons not fully understood, FLAGS_INHERITED may
not be set within all security descriptors even though the ACE was in
face inherited. If an inherited ACE is added to a parent the Windows
ACL editor will rebuild all children ACEs and set this flag accordingly.
return (flags & FLAGS_INHERITED) != 0;
| public java.lang.String | toString()Return a string represeting this ACE.
Note: This function should probably be changed to return SDDL
fragments but currently it does not.
int count, i;
String str;
StringBuffer sb = new StringBuffer();
sb.append( isAllow() ? "Allow " : "Deny " );
appendCol(sb, sid.toDisplayString(), 25);
sb.append( " 0x" ).append( Hexdump.toHexString( access, 8 )).append(' ");
sb.append(isInherited() ? "Inherited " : "Direct ");
appendCol(sb, getApplyToText(), 34);
return sb.toString();
|
|