1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.authz.support;
21
22
23 import java.util.Collection;
24 import java.util.Iterator;
25
26 import javax.naming.NamingException;
27
28 import org.apache.directory.server.core.entry.ServerEntry;
29 import org.apache.directory.server.core.interceptor.context.OperationContext;
30 import org.apache.directory.server.core.subtree.SubtreeEvaluator;
31 import org.apache.directory.server.schema.registries.Registries;
32 import org.apache.directory.shared.ldap.aci.ACITuple;
33 import org.apache.directory.shared.ldap.aci.MicroOperation;
34 import org.apache.directory.shared.ldap.aci.UserClass;
35 import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
36 import org.apache.directory.shared.ldap.entry.Value;
37 import org.apache.directory.shared.ldap.name.LdapDN;
38 import org.apache.directory.shared.ldap.subtree.SubtreeSpecification;
39
40
41
42
43
44
45
46
47
48 public class RelatedUserClassFilter implements ACITupleFilter
49 {
50 private static final LdapDN ROOTDSE_NAME = LdapDN.EMPTY_LDAPDN;
51
52 private final SubtreeEvaluator subtreeEvaluator;
53
54
55 public RelatedUserClassFilter(SubtreeEvaluator subtreeEvaluator)
56 {
57 this.subtreeEvaluator = subtreeEvaluator;
58 }
59
60
61 public Collection<ACITuple> filter(
62 Registries registries,
63 Collection<ACITuple> tuples,
64 OperationScope scope,
65 OperationContext opContext,
66 Collection<LdapDN> userGroupNames,
67 LdapDN userName,
68 ServerEntry userEntry,
69 AuthenticationLevel authenticationLevel,
70 LdapDN entryName,
71 String attrId,
72 Value<?> attrValue,
73 ServerEntry entry,
74 Collection<MicroOperation> microOperations,
75 ServerEntry entryView )
76 throws NamingException
77 {
78 if ( tuples.size() == 0 )
79 {
80 return tuples;
81 }
82
83 for ( Iterator<ACITuple> ii = tuples.iterator(); ii.hasNext(); )
84 {
85 ACITuple tuple = ii.next();
86
87 if ( tuple.isGrant() )
88 {
89 if ( !isRelated( userGroupNames,
90 userName,
91 userEntry,
92 entryName,
93 tuple.getUserClasses() )
94 || authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) < 0 )
95 {
96 ii.remove();
97 }
98 }
99 else
100
101 {
102 if ( !isRelated( userGroupNames,
103 userName,
104 userEntry,
105 entryName,
106 tuple.getUserClasses() )
107 && authenticationLevel.compareTo( tuple.getAuthenticationLevel() ) >= 0 )
108 {
109 ii.remove();
110 }
111 }
112 }
113
114 return tuples;
115 }
116
117
118 private boolean isRelated( Collection<LdapDN> userGroupNames, LdapDN userName, ServerEntry userEntry,
119 LdapDN entryName, Collection<UserClass> userClasses ) throws NamingException
120 {
121 for ( UserClass userClass : userClasses )
122 {
123 if ( userClass == UserClass.ALL_USERS )
124 {
125 return true;
126 }
127 else if ( userClass == UserClass.THIS_ENTRY )
128 {
129 if ( userName.equals( entryName ) )
130 {
131 return true;
132 }
133 }
134 else if ( userClass == UserClass.PARENT_OF_ENTRY )
135 {
136 if ( entryName.startsWith( userName ) )
137 {
138 return true;
139 }
140 }
141 else if ( userClass instanceof UserClass.Name )
142 {
143 UserClass.Name nameUserClass = ( UserClass.Name ) userClass;
144 if ( nameUserClass.getNames().contains( userName ) )
145 {
146 return true;
147 }
148 }
149 else if ( userClass instanceof UserClass.UserGroup )
150 {
151 UserClass.UserGroup userGroupUserClass = ( UserClass.UserGroup ) userClass;
152
153 for ( LdapDN userGroupName : userGroupNames )
154 {
155 if ( userGroupName != null && userGroupUserClass.getNames().contains( userGroupName ) )
156 {
157 return true;
158 }
159 }
160 }
161 else if ( userClass instanceof UserClass.Subtree )
162 {
163 UserClass.Subtree subtree = ( UserClass.Subtree ) userClass;
164 if ( matchUserClassSubtree( userName, userEntry, subtree ) )
165 {
166 return true;
167 }
168 }
169 else
170 {
171 throw new InternalError( "Unexpected userClass: " + userClass.getClass().getName() );
172 }
173 }
174
175 return false;
176 }
177
178
179 private boolean matchUserClassSubtree( LdapDN userName, ServerEntry userEntry, UserClass.Subtree subtree )
180 throws NamingException
181 {
182 for ( SubtreeSpecification subtreeSpec : subtree.getSubtreeSpecifications() )
183 {
184 if ( subtreeEvaluator.evaluate( subtreeSpec, ROOTDSE_NAME, userName, userEntry ) )
185 {
186 return true;
187 }
188 }
189
190 return false;
191 }
192 }