KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jcifs > smb > ACE


1 package jcifs.smb;
2
3 import jcifs.util.Hexdump;
4
5 /**
6  * An Access Control Entry (ACE) is an element in a security descriptor
7  * such as those associated with files and directories. The Windows OS
8  * determines which users have the necessary permissions to access objects
9  * based on these entries.
10  * <p>
11  * To fully understand the information exposed by this class a description
12  * of the access check algorithm used by Windows is required. The following
13  * is a basic description of the algorithm. For a more complete description
14  * we recommend reading the section on Access Control in Keith Brown's
15  * "The .NET Developer's Guide to Windows Security" (which is also
16  * available online).
17  * <p>
18  * Direct ACEs are evaluated first in order. The SID of the user performing
19  * the operation and the desired access bits are compared to the SID
20  * and access mask of each ACE. If the SID matches, the allow/deny flags
21  * and access mask are considered. If the ACE is a "deny"
22  * ACE and <i>any</i> of the desired access bits match bits in the access
23  * mask of the ACE, the whole access check fails. If the ACE is an "allow"
24  * ACE and <i>all</i> of the bits in the desired access bits match bits in
25  * the access mask of the ACE, the access check is successful. Otherwise,
26  * more ACEs are evaluated until all desired access bits (combined)
27  * are "allowed". If all of the desired access bits are not "allowed"
28  * the then same process is repeated for inherited ACEs.
29  * <p>
30  * For example, if user <tt>WNET\alice</tt> tries to open a file
31  * with desired access bits <tt>0x00000003</tt> (<tt>FILE_READ_DATA |
32  * FILE_WRITE_DATA</tt>) and the target file has the following security
33  * descriptor ACEs:
34  * <pre>
35  * Allow WNET\alice 0x001200A9 Direct
36  * Allow Administrators 0x001F01FF Inherited
37  * Allow SYSTEM 0x001F01FF Inherited
38  * </pre>
39  * the access check would fail because the direct ACE has an access mask
40  * of <tt>0x001200A9</tt> which doesn't have the
41  * <tt>FILE_WRITE_DATA</tt> bit on (bit <tt>0x00000002</tt>). Actually, this isn't quite correct. If
42  * <tt>WNET\alice</tt> is in the local <tt>Administrators</tt> group the access check
43  * will succeed because the inherited ACE allows local <tt>Administrators</tt>
44  * both <tt>FILE_READ_DATA</tt> and <tt>FILE_WRITE_DATA</tt> access.
45  */

46
47 public class ACE {
48
49     public static final int FILE_READ_DATA = 0x00000001; // 1
50
public static final int FILE_WRITE_DATA = 0x00000002; // 2
51
public static final int FILE_APPEND_DATA = 0x00000004; // 3
52
public static final int FILE_READ_EA = 0x00000008; // 4
53
public static final int FILE_WRITE_EA = 0x00000010; // 5
54
public static final int FILE_EXECUTE = 0x00000020; // 6
55
public static final int FILE_DELETE = 0x00000040; // 7
56
public static final int FILE_READ_ATTRIBUTES = 0x00000080; // 8
57
public static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9
58
public static final int DELETE = 0x00010000; // 16
59
public static final int READ_CONTROL = 0x00020000; // 17
60
public static final int WRITE_DAC = 0x00040000; // 18
61
public static final int WRITE_OWNER = 0x00080000; // 19
62
public static final int SYNCHRONIZE = 0x00100000; // 20
63
public static final int GENERIC_ALL = 0x10000000; // 28
64
public static final int GENERIC_EXECUTE = 0x20000000; // 29
65
public static final int GENERIC_WRITE = 0x40000000; // 30
66
public static final int GENERIC_READ = 0x80000000; // 31
67

68     public static final int FLAGS_OBJECT_INHERIT = 0x01;
69     public static final int FLAGS_CONTAINER_INHERIT = 0x02;
70     public static final int FLAGS_NO_PROPAGATE = 0x04;
71     public static final int FLAGS_INHERIT_ONLY = 0x08;
72     public static final int FLAGS_INHERITED = 0x10;
73
74     boolean allow;
75     int flags;
76     int access;
77     SID sid;
78
79     /**
80      * Returns true if this ACE is an allow ACE and false if it is a deny ACE.
81      */

82     public boolean isAllow() {
83         return allow;
84     }
85     /**
86      * Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
87      * <p>
88      * Note: For reasons not fully understood, <tt>FLAGS_INHERITED</tt> may
89      * not be set within all security descriptors even though the ACE was in
90      * face inherited. If an inherited ACE is added to a parent the Windows
91      * ACL editor will rebuild all children ACEs and set this flag accordingly.
92      */

93     public boolean isInherited() {
94         return (flags & FLAGS_INHERITED) != 0;
95     }
96     /**
97      * Returns the flags for this ACE. The </tt>isInherited()</tt>
98      * method checks the <tt>FLAGS_INHERITED</tt> bit in these flags.
99      */

100     public int getFlags() {
101         return flags;
102     }
103     /**
104      * Returns the 'Apply To' text for inheritance of ACEs on
105      * directories such as 'This folder, subfolder and files'. For
106      * files the text is always 'This object only'.
107      */

108     public String JavaDoc getApplyToText() {
109         switch (flags & (FLAGS_OBJECT_INHERIT | FLAGS_CONTAINER_INHERIT | FLAGS_INHERIT_ONLY)) {
110             case 0x00:
111                 return "This folder only";
112             case 0x03:
113                 return "This folder, subfolders and files";
114             case 0x0B:
115                 return "Subfolders and files only";
116             case 0x02:
117                 return "This folder and subfolders";
118             case 0x0A:
119                 return "Subfolders only";
120             case 0x01:
121                 return "This folder and files";
122             case 0x09:
123                 return "Files only";
124         }
125         return "Invalid";
126     }
127     /**
128      * Returns the access mask accociated with this ACE. Use the
129      * constants for <tt>FILE_READ_DATA</tt>, <tt>FILE_WRITE_DATA</tt>,
130      * <tt>READ_CONTROL</tt>, <tt>GENERIC_ALL</tt>, etc with bitwise
131      * operators to determine which bits of the mask are on or off.
132      */

133     public int getAccessMask() {
134         return access;
135     }
136
137     /**
138      * Return the SID associated with this ACE.
139      */

140     public SID getSID() {
141         return sid;
142     }
143
144     int decode( byte[] buf, int bi ) {
145         allow = buf[bi++] == (byte)0x00;
146         flags = buf[bi++] & 0xFF;
147         int size = ServerMessageBlock.readInt2(buf, bi);
148         bi += 2;
149         access = ServerMessageBlock.readInt4(buf, bi);
150         bi += 4;
151         sid = new SID(buf, bi);
152         return size;
153     }
154
155     void appendCol(StringBuffer JavaDoc sb, String JavaDoc str, int width) {
156         sb.append(str);
157         int count = width - str.length();
158         for (int i = 0; i < count; i++) {
159             sb.append(' ');
160         }
161     }
162     /**
163      * Return a string represeting this ACE.
164      * <p>
165      * Note: This function should probably be changed to return SDDL
166      * fragments but currently it does not.
167      */

168     public String JavaDoc toString() {
169         int count, i;
170         String JavaDoc str;
171
172         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
173         sb.append( isAllow() ? "Allow " : "Deny " );
174         appendCol(sb, sid.toDisplayString(), 25);
175         sb.append( " 0x" ).append( Hexdump.toHexString( access, 8 )).append(' ');
176         sb.append(isInherited() ? "Inherited " : "Direct ");
177         appendCol(sb, getApplyToText(), 34);
178         return sb.toString();
179     }
180 }
181
Popular Tags