1 17 package org.apache.ldap.server.authz; 18 19 20 import org.apache.ldap.common.exception.LdapNoPermissionException; 21 import org.apache.ldap.common.name.DnParser; 22 import org.apache.ldap.server.BackingStore; 23 import org.apache.ldap.server.SystemPartition; 24 import org.apache.ldap.server.interceptor.BaseInterceptor; 25 import org.apache.ldap.server.interceptor.InterceptorContext; 26 import org.apache.ldap.server.interceptor.NextInterceptor; 27 import org.apache.ldap.server.db.ResultFilteringEnumeration; 28 import org.apache.ldap.server.db.SearchResultFilter; 29 import org.apache.ldap.server.invocation.*; 30 import org.apache.ldap.server.jndi.ServerContext; 31 import org.apache.ldap.server.schema.AttributeTypeRegistry; 32 import org.apache.ldap.server.schema.ConcreteNameComponentNormalizer; 33 34 import javax.naming.Name ; 35 import javax.naming.NamingEnumeration ; 36 import javax.naming.NamingException ; 37 import javax.naming.directory.Attributes ; 38 import javax.naming.directory.SearchControls ; 39 import javax.naming.directory.SearchResult ; 40 import javax.naming.ldap.LdapContext ; 41 42 43 52 public class AuthorizationService extends BaseInterceptor 53 { 54 57 private static final Name ADMIN_DN = SystemPartition.getAdminDn(); 58 59 62 private static final Name USER_BASE_DN = SystemPartition.getUsersBaseDn(); 63 64 67 private static final Name GROUP_BASE_DN = SystemPartition.getGroupsBaseDn(); 68 69 72 private DnParser dnParser; 73 74 75 78 public AuthorizationService() 79 { 80 } 81 82 83 public void init( InterceptorContext ctx ) throws NamingException 84 { 85 AttributeTypeRegistry atr = ctx.getGlobalRegistries().getAttributeTypeRegistry(); 86 dnParser = new DnParser( new ConcreteNameComponentNormalizer( atr ) ); 87 } 88 89 90 public void destroy() 91 { 92 } 93 94 95 public void process( NextInterceptor nextInterceptor, Invocation call ) throws NamingException 96 { 97 super.process( nextInterceptor, call ); 98 } 99 100 104 protected void process( NextInterceptor nextInterceptor, Delete call ) throws NamingException 105 { 106 Name name = call.getName(); 107 Name principalDn = getPrincipal( call ).getDn(); 108 109 if ( name.toString().equals( "" ) ) 110 { 111 String msg = "The rootDSE cannot be deleted!"; 112 throw new LdapNoPermissionException( msg ); 113 } 114 115 if ( name == ADMIN_DN || name.equals( ADMIN_DN ) ) 116 { 117 String msg = "User " + principalDn; 118 msg += " does not have permission to delete the admin account."; 119 msg += " No one not even the admin can delete this account!"; 120 throw new LdapNoPermissionException( msg ); 121 } 122 123 if ( name.size() > 2 && name.startsWith( USER_BASE_DN ) 124 && !principalDn.equals( ADMIN_DN ) ) 125 { 126 String msg = "User " + principalDn; 127 msg += " does not have permission to delete the user account: "; 128 msg += name + ". Only the admin can delete user accounts."; 129 throw new LdapNoPermissionException( msg ); 130 } 131 132 if ( name.size() > 2 && name.startsWith( GROUP_BASE_DN ) 133 && !principalDn.equals( ADMIN_DN ) ) 134 { 135 String msg = "User " + principalDn; 136 msg += " does not have permission to delete the group entry: "; 137 msg += name + ". Only the admin can delete groups."; 138 throw new LdapNoPermissionException( msg ); 139 } 140 141 nextInterceptor.process( call ); 142 } 143 144 145 151 protected void process( NextInterceptor nextInterceptor, HasEntry call ) throws NamingException 152 { 153 super.process( nextInterceptor, call ); 154 } 155 156 157 161 162 168 protected void process( NextInterceptor nextInterceptor, Modify call ) throws NamingException 169 { 170 protectModifyAlterations( call, call.getName() ); 171 nextInterceptor.process( call ); 172 } 173 174 175 181 protected void process( NextInterceptor nextInterceptor, ModifyMany call ) throws NamingException 182 { 183 protectModifyAlterations( call, call.getName() ); 184 nextInterceptor.process( call ); 185 } 186 187 188 private void protectModifyAlterations( Invocation call, Name dn ) throws LdapNoPermissionException 189 { 190 Name principalDn = getPrincipal( call ).getDn(); 191 192 if ( dn.toString().equals( "" ) ) 193 { 194 String msg = "The rootDSE cannot be modified!"; 195 throw new LdapNoPermissionException( msg ); 196 } 197 198 if ( !principalDn.equals( ADMIN_DN ) ) 199 { 200 if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) ) 201 { 202 String msg = "User " + principalDn; 203 msg += " does not have permission to modify the admin account."; 204 throw new LdapNoPermissionException( msg ); 205 } 206 207 if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) ) 208 { 209 String msg = "User " + principalDn; 210 msg += " does not have permission to modify the account of the"; 211 msg += " user " + dn + ".\nEven the owner of an account cannot"; 212 msg += " modify it.\nUser accounts can only be modified by the"; 213 msg += " administrator."; 214 throw new LdapNoPermissionException( msg ); 215 } 216 217 if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN ) ) 218 { 219 String msg = "User " + principalDn; 220 msg += " does not have permission to modify the group entry "; 221 msg += dn + ".\nGroups can only be modified by the admin."; 222 throw new LdapNoPermissionException( msg ); 223 } 224 } 225 } 226 227 228 237 238 protected void process( NextInterceptor nextInterceptor, ModifyRN call ) throws NamingException 239 { 240 protectDnAlterations( call, call.getName() ); 241 nextInterceptor.process( call ); 242 } 243 244 245 protected void process( NextInterceptor nextInterceptor, Move call ) throws NamingException 246 { 247 protectDnAlterations( call, call.getName() ); 248 nextInterceptor.process( call ); 249 } 250 251 252 protected void process( NextInterceptor nextInterceptor, MoveAndModifyRN call ) throws NamingException 253 { 254 protectDnAlterations( call, call.getName() ); 255 nextInterceptor.process( call ); 256 } 257 258 259 private void protectDnAlterations( Invocation call, Name dn ) throws LdapNoPermissionException 260 { 261 Name principalDn = getPrincipal( call ).getDn(); 262 263 if ( dn.toString().equals( "" ) ) 264 { 265 String msg = "The rootDSE cannot be moved or renamed!"; 266 throw new LdapNoPermissionException( msg ); 267 } 268 269 if ( dn == ADMIN_DN || dn.equals( ADMIN_DN ) ) 270 { 271 String msg = "User '" + principalDn; 272 msg += "' does not have permission to move or rename the admin"; 273 msg += " account. No one not even the admin can move or"; 274 msg += " rename " + dn + "!"; 275 throw new LdapNoPermissionException( msg ); 276 } 277 278 if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) && !principalDn.equals( ADMIN_DN ) ) 279 { 280 String msg = "User '" + principalDn; 281 msg += "' does not have permission to move or rename the user"; 282 msg += " account: " + dn + ". Only the admin can move or"; 283 msg += " rename user accounts."; 284 throw new LdapNoPermissionException( msg ); 285 } 286 287 if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN ) && !principalDn.equals( ADMIN_DN ) ) 288 { 289 String msg = "User " + principalDn; 290 msg += " does not have permission to move or rename the group entry "; 291 msg += dn + ".\nGroups can only be moved or renamed by the admin."; 292 throw new LdapNoPermissionException( msg ); 293 } 294 } 295 296 297 protected void process( NextInterceptor nextInterceptor, Lookup call ) throws NamingException 298 { 299 super.process( nextInterceptor, call ); 300 301 Attributes attributes = ( Attributes ) call.getReturnValue(); 302 if ( attributes == null ) 303 { 304 return; 305 } 306 307 Attributes retval = ( Attributes ) attributes.clone(); 308 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 309 protectLookUp( ctx, call.getName() ); 310 call.setReturnValue( retval ); 311 } 312 313 314 protected void process( NextInterceptor nextInterceptor, LookupWithAttrIds call ) throws NamingException 315 { 316 super.process( nextInterceptor, call ); 317 318 Attributes attributes = ( Attributes ) call.getReturnValue(); 319 if ( attributes == null ) 320 { 321 return; 322 } 323 324 Attributes retval = ( Attributes ) attributes.clone(); 325 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 326 protectLookUp( ctx, call.getName() ); 327 call.setReturnValue( retval ); 328 } 329 330 331 private void protectLookUp( LdapContext ctx, Name dn ) throws NamingException 332 { 333 Name principalDn = ( ( ServerContext ) ctx ).getPrincipal().getDn(); 334 335 if ( !principalDn.equals( ADMIN_DN ) ) 336 { 337 if ( dn.size() > 2 && dn.startsWith( USER_BASE_DN ) ) 338 { 339 if ( dn.toString().equals( principalDn.toString() ) ) 341 { 342 return; 343 } 344 345 String msg = "Access to user account '" + dn + "' not permitted"; 346 msg += " for user '" + principalDn + "'. Only the admin can"; 347 msg += " access user account information"; 348 throw new LdapNoPermissionException( msg ); 349 } 350 351 if ( dn.size() > 2 && dn.startsWith( GROUP_BASE_DN ) ) 352 { 353 if ( dn.toString().equals( principalDn.toString() ) ) 355 { 356 return; 357 } 358 359 String msg = "Access to group '" + dn + "' not permitted"; 360 msg += " for user '" + principalDn + "'. Only the admin can"; 361 msg += " access group information"; 362 throw new LdapNoPermissionException( msg ); 363 } 364 365 if ( dn.equals( ADMIN_DN ) ) 366 { 367 if ( dn.toString().equals( principalDn.toString() ) ) 369 { 370 return; 371 } 372 373 String msg = "Access to admin account not permitted for user '"; 374 msg += principalDn + "'. Only the admin can"; 375 msg += " access admin account information"; 376 throw new LdapNoPermissionException( msg ); 377 } 378 } 379 } 380 381 382 protected void process( NextInterceptor nextInterceptor, Search call ) throws NamingException 383 { 384 super.process( nextInterceptor, call ); 385 386 SearchControls searchControls = call.getControls(); 387 if ( searchControls.getReturningAttributes() != null ) 388 { 389 return; 390 } 391 392 NamingEnumeration e; 393 ResultFilteringEnumeration retval; 394 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 395 e = ( NamingEnumeration ) call.getReturnValue(); 396 retval = new ResultFilteringEnumeration( e, searchControls, ctx, 397 new SearchResultFilter() 398 { 399 public boolean accept( LdapContext ctx, SearchResult result, 400 SearchControls controls ) 401 throws NamingException 402 { 403 return AuthorizationService.this.isSearchable( ctx, result ); 404 } 405 } ); 406 407 call.setReturnValue( retval ); 408 } 409 410 411 protected void process( NextInterceptor nextInterceptor, List call ) throws NamingException 412 { 413 super.process( nextInterceptor, call ); 414 415 NamingEnumeration e; 416 ResultFilteringEnumeration retval; 417 LdapContext ctx = ( LdapContext ) call.getContextStack().peek(); 418 e = ( NamingEnumeration ) call.getReturnValue(); 419 retval = new ResultFilteringEnumeration( e, null, ctx, 420 new SearchResultFilter() 421 { 422 public boolean accept( LdapContext ctx, SearchResult result, 423 SearchControls controls ) 424 throws NamingException 425 { 426 return AuthorizationService.this.isSearchable( ctx, result ); 427 } 428 } ); 429 430 call.setReturnValue( retval ); 431 } 432 433 434 private boolean isSearchable( LdapContext ctx, SearchResult result ) 435 throws NamingException 436 { 437 Name dn; 438 439 synchronized ( dnParser ) 440 { 441 dn = dnParser.parse( result.getName() ); 442 } 443 444 Name principalDn = ( ( ServerContext ) ctx ).getPrincipal().getDn(); 445 if ( !principalDn.equals( ADMIN_DN ) ) 446 { 447 if ( dn.size() > 2 ) 448 { 449 if ( dn.startsWith( USER_BASE_DN ) || dn.startsWith( GROUP_BASE_DN ) ) 450 { 451 return false; 452 } 453 } 454 455 if ( dn.equals( ADMIN_DN ) ) 456 { 457 return false; 458 } 459 460 } 461 462 return true; 463 } 464 } 465 | Popular Tags |