| 1 package org.apache.turbine.services.security.ldap; 2 3 18 19 import java.util.Hashtable ; 20 import java.util.Iterator ; 21 import java.util.Vector ; 22 import javax.naming.NameAlreadyBoundException ; 23 import javax.naming.NamingEnumeration ; 24 import javax.naming.NamingException ; 25 import javax.naming.directory.Attribute ; 26 import javax.naming.directory.Attributes ; 27 import javax.naming.directory.BasicAttribute ; 28 import javax.naming.directory.BasicAttributes ; 29 import javax.naming.directory.DirContext ; 30 import javax.naming.directory.SearchControls ; 31 import javax.naming.directory.SearchResult ; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.apache.torque.util.Criteria; 36 import org.apache.turbine.om.security.Group; 37 import org.apache.turbine.om.security.Permission; 38 import org.apache.turbine.om.security.Role; 39 import org.apache.turbine.om.security.TurbineGroup; 40 import org.apache.turbine.om.security.TurbinePermission; 41 import org.apache.turbine.om.security.TurbineRole; 42 import org.apache.turbine.om.security.User; 43 import org.apache.turbine.services.security.BaseSecurityService; 44 import org.apache.turbine.services.security.TurbineSecurity; 45 import org.apache.turbine.util.security.AccessControlList; 46 import org.apache.turbine.util.security.DataBackendException; 47 import org.apache.turbine.util.security.EntityExistsException; 48 import org.apache.turbine.util.security.GroupSet; 49 import org.apache.turbine.util.security.PermissionSet; 50 import org.apache.turbine.util.security.RoleSet; 51 import org.apache.turbine.util.security.UnknownEntityException; 52 53 64 public class LDAPSecurityService extends BaseSecurityService 65 { 66 67 68 private static Log log = LogFactory.getLog(LDAPSecurityService.class); 69 70 75 76 88 public AccessControlList getACL(User user) 89 throws DataBackendException, UnknownEntityException 90 { 91 if (!TurbineSecurity.accountExists(user)) 92 { 93 throw new UnknownEntityException("The account '" 94 + user.getName() + "' does not exist"); 95 } 96 try 97 { 98 Hashtable roles = new Hashtable (); 99 Hashtable permissions = new Hashtable (); 100 101 lockShared(); 104 105 Iterator groupsIterator = getAllGroups().iterator(); 108 109 while (groupsIterator.hasNext()) 110 { 111 Group group = (Group) groupsIterator.next(); 112 113 RoleSet groupRoles = getRoles(user, group); 115 116 roles.put(group, groupRoles); 118 PermissionSet groupPermissions = new PermissionSet(); 120 Iterator rolesIterator = groupRoles.iterator(); 122 123 while (rolesIterator.hasNext()) 124 { 125 Role role = (Role) rolesIterator.next(); 126 PermissionSet rolePermissions = getPermissions(role); 128 129 groupPermissions.add(rolePermissions); 130 } 131 permissions.put(group, groupPermissions); 133 } 134 return getAclInstance(roles, permissions); 135 } 136 catch (Exception e) 137 { 138 throw new DataBackendException("Failed to build ACL for user '" 139 + user.getName() + "'", e); 140 } 141 finally 142 { 143 unlockShared(); 146 } 147 } 148 149 154 155 165 public synchronized void grant(User user, Group group, Role role) 166 throws DataBackendException, UnknownEntityException 167 { 168 try 169 { 170 lockExclusive(); 171 172 String userName = user.getName(); 173 String roleName = role.getName(); 174 String groupName = group.getName(); 175 176 if (!accountExists(user)) 177 { 178 throw new UnknownEntityException( 179 "User '" + userName + "' does not exist"); 180 } 181 182 if (!checkExists(role)) 183 { 184 throw new UnknownEntityException( 185 "Role '" + roleName + "' does not exist"); 186 } 187 188 if (!checkExists(group)) 189 { 190 throw new UnknownEntityException( 191 "Group '" + groupName + "' does not exist"); 192 } 193 194 String dn = "turbineGroupName=" + groupName + "," 196 + LDAPSecurityConstants.getNameAttribute() 197 + "=" + userName + "," 198 + LDAPSecurityConstants.getBaseSearch(); 199 200 201 DirContext ctx = LDAPUserManager.bindAsAdmin(); 203 204 Attributes attrs = new BasicAttributes (); 206 207 attrs.put(new BasicAttribute ("turbineRoleName", roleName)); 208 attrs.put(new BasicAttribute ("objectClass", "turbineUserGroup")); 209 attrs.put(new BasicAttribute ("turbineUserUniqueId", userName)); 210 try 211 { 212 ctx.bind(dn, null, attrs); 214 } 215 catch (NameAlreadyBoundException ex) 216 { 217 attrs = new BasicAttributes (); 220 attrs.put(new BasicAttribute ("turbineRoleName", roleName)); 221 ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs); 222 } 223 224 } 225 catch (NamingException ex) 226 { 227 throw new DataBackendException("NamingException caught", ex); 228 } 229 finally 230 { 231 unlockExclusive(); 232 } 233 } 234 235 245 public synchronized void revoke(User user, Group group, Role role) 246 throws DataBackendException, UnknownEntityException 247 { 248 try 249 { 250 lockExclusive(); 251 252 String userName = user.getName(); 253 String roleName = role.getName(); 254 String groupName = group.getName(); 255 256 if (!accountExists(user)) 257 { 258 throw new UnknownEntityException( 259 "User '" + userName + "' does not exist"); 260 } 261 262 if (!checkExists(role)) 263 { 264 throw new UnknownEntityException( 265 "Role '" + roleName + "' does not exist"); 266 } 267 268 if (!checkExists(group)) 269 { 270 throw new UnknownEntityException( 271 "Group '" + groupName + "' does not exist"); 272 } 273 274 String dn = "turbineGroupName=" + groupName + "," 276 + LDAPSecurityConstants.getNameAttribute() 277 + "=" + userName + "," 278 + LDAPSecurityConstants.getBaseSearch(); 279 280 Attributes attrs = new BasicAttributes (); 282 283 attrs.put(new BasicAttribute ("turbineRoleName", roleName)); 284 285 DirContext ctx = LDAPUserManager.bindAsAdmin(); 287 288 ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs); 290 291 } 292 catch (NamingException ex) 293 { 294 throw new DataBackendException("NamingException caught", ex); 295 } 296 finally 297 { 298 unlockExclusive(); 299 } 300 } 301 302 310 public synchronized void grant(Role role, Permission permission) 311 throws DataBackendException, UnknownEntityException 312 { 313 try 314 { 315 lockExclusive(); 316 317 String roleName = role.getName(); 318 String permName = permission.getName(); 319 320 if (!checkExists(role)) 321 { 322 throw new UnknownEntityException( 323 "Role '" + roleName + "' does not exist"); 324 } 325 326 if (!checkExists(permission)) 327 { 328 throw new UnknownEntityException( 329 "Permission '" + permName + "' does not exist"); 330 } 331 332 String dn = "turbineRoleName=" + roleName + "," 334 + LDAPSecurityConstants.getBaseSearch(); 335 336 Attributes attrs = new BasicAttributes (); 338 339 attrs.put(new BasicAttribute ("turbinePermissionName", permName)); 340 341 DirContext ctx = LDAPUserManager.bindAsAdmin(); 343 344 ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs); 346 347 } 348 catch (NamingException ex) 349 { 350 throw new DataBackendException("NamingException caught", ex); 351 } 352 finally 353 { 354 unlockExclusive(); 355 } 356 } 357 358 366 public synchronized void revoke(Role role, Permission permission) 367 throws DataBackendException, UnknownEntityException 368 { 369 try 370 { 371 lockExclusive(); 372 373 String roleName = role.getName(); 374 String permName = permission.getName(); 375 376 if (!checkExists(role)) 377 { 378 throw new UnknownEntityException( 379 "Role '" + roleName + "' does not exist"); 380 } 381 382 if (!checkExists(permission)) 383 { 384 throw new UnknownEntityException( 385 "Permission '" + permName + "' does not exist"); 386 } 387 388 String dn = "turbineRoleName=" + roleName + "," 390 + LDAPSecurityConstants.getBaseSearch(); 391 392 Attributes attrs = new BasicAttributes (); 394 395 attrs.put(new BasicAttribute ("turbinePermissionName", permName)); 396 397 DirContext ctx = LDAPUserManager.bindAsAdmin(); 399 400 ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs); 402 403 } 404 catch (NamingException ex) 405 { 406 throw new DataBackendException("NamingException caught", ex); 407 } 408 finally 409 { 410 unlockExclusive(); 411 } 412 } 413 414 419 420 429 public Group getNewGroup(String groupName) 430 { 431 return (Group) new TurbineGroup(groupName); 432 } 433 434 443 public Role getNewRole(String roleName) 444 { 445 return (Role) new TurbineRole(roleName); 446 } 447 448 458 public Permission getNewPermission(String permissionName) 459 { 460 return (Permission) new TurbinePermission(permissionName); 461 } 462 463 470 public GroupSet getGroups(Criteria criteria) 471 throws DataBackendException 472 { 473 Vector groups = new Vector (); 474 475 try 476 { 477 DirContext ctx = LDAPUserManager.bindAsAdmin(); 478 479 String baseSearch = LDAPSecurityConstants.getBaseSearch(); 480 String filter = "(objectclass=turbineGroup)"; 481 482 485 SearchControls ctls = new SearchControls (); 486 487 NamingEnumeration answer = ctx.search(baseSearch, filter, ctls); 488 489 while (answer.hasMore()) 490 { 491 SearchResult sr = (SearchResult ) answer.next(); 492 Attributes attribs = sr.getAttributes(); 493 Attribute attr = attribs.get("turbineGroupName"); 494 495 if (attr != null && attr.get() != null) 496 { 497 Group group = getNewGroup(attr.get().toString()); 498 499 groups.add(group); 500 } 501 } 502 } 503 catch (NamingException ex) 504 { 505 throw new DataBackendException("NamingException caught", ex); 506 } 507 return new GroupSet(groups); 508 } 509 510 517 private RoleSet getRoles(User user, Group group) 518 throws DataBackendException 519 { 520 Vector roles = new Vector (0); 521 522 try 523 { 524 DirContext ctx = LDAPUserManager.bindAsAdmin(); 525 526 String baseSearch = LDAPSecurityConstants.getBaseSearch(); 527 String filter = "(& "; 528 529 filter += "(objectclass=turbineUserGroup)"; 530 filter += "(turbineUserUniqueId=" + user.getName() + ")"; 531 filter += "(turbineGroupName=" + group.getName() + ")"; 532 filter += ")"; 533 534 537 SearchControls ctls = new SearchControls (); 538 539 ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); 540 541 NamingEnumeration answer = ctx.search(baseSearch, filter, ctls); 542 543 while (answer.hasMore()) 544 { 545 SearchResult sr = (SearchResult ) answer.next(); 546 Attributes attribs = sr.getAttributes(); 547 Attribute attr = attribs.get("turbineRoleName"); 548 549 if (attr != null) 550 { 551 NamingEnumeration values = attr.getAll(); 552 553 while (values.hasMore()) 554 { 555 Role role = getNewRole(values.next().toString()); 556 557 roles.add(role); 558 } 559 } 560 else 561 { 562 log.error("Role doesn't have a name"); 563 } 564 } 565 } 566 catch (NamingException ex) 567 { 568 throw new DataBackendException( 569 "NamingException caught:", ex); 570 } 571 572 return new RoleSet(roles); 573 } 574 575 582 public RoleSet getRoles(Criteria criteria) throws DataBackendException 583 { 584 Vector roles = new Vector (0); 585 586 try 587 { 588 DirContext ctx = LDAPUserManager.bindAsAdmin(); 589 590 String baseSearch = LDAPSecurityConstants.getBaseSearch(); 591 String filter = "(objectclass=turbineRole)"; 592 593 596 SearchControls ctls = new SearchControls (); 597 598 NamingEnumeration answer = ctx.search(baseSearch, filter, ctls); 599 600 while (answer.hasMore()) 601 { 602 SearchResult sr = (SearchResult ) answer.next(); 603 Attributes attribs = sr.getAttributes(); 604 Attribute attr = attribs.get("turbineRoleName"); 605 606 if (attr != null && attr.get() != null) 607 { 608 Role role = getNewRole(attr.get().toString()); 609 610 roles.add(role); 611 } 612 else 613 { 614 log.error("Role doesn't have a name"); 615 } 616 } 617 } 618 catch (NamingException ex) 619 { 620 throw new DataBackendException("NamingException caught", ex); 621 } 622 623 return new RoleSet(roles); 624 } 625 626 633 public PermissionSet getPermissions(Criteria criteria) 634 throws DataBackendException 635 { 636 Vector permissions = new Vector (); 637 638 try 639 { 640 DirContext ctx = LDAPUserManager.bindAsAdmin(); 641 642 String baseSearch = LDAPSecurityConstants.getBaseSearch(); 643 String filter = "(objectClass=turbinePermission)"; 644 645 648 SearchControls ctls = new SearchControls (); 649 650 NamingEnumeration answer = ctx.search(baseSearch, filter, ctls); 651 652 while (answer.hasMore()) 653 { 654 SearchResult sr = (SearchResult ) answer.next(); 655 Attributes attribs = sr.getAttributes(); 656 Attribute attr = attribs.get("turbinePermissionName"); 657 658 if (attr != null && attr.get() != null) 659 { 660 Permission perm = getNewPermission(attr.get().toString()); 661 662 permissions.add(perm); 663 } 664 else 665 { 666 log.error("Permission doesn't have a name"); 667 } 668 } 669 } 670 catch (NamingException ex) 671 { 672 throw new DataBackendException( 673 "The LDAP server specified is unavailable", ex); 674 } 675 return new PermissionSet(permissions); 676 } 677 678 686 public PermissionSet getPermissions(Role role) 687 throws DataBackendException, UnknownEntityException 688 { 689 Hashtable permissions = new Hashtable (); 690 691 try 692 { 693 DirContext ctx = LDAPUserManager.bindAsAdmin(); 694 695 String baseSearch = LDAPSecurityConstants.getBaseSearch(); 696 String filter = "(& "; 697 698 filter += "(objectClass=turbineRole)"; 699 filter += "(turbineRoleName=" + role.getName() + ")"; 700 filter += ")"; 701 702 705 SearchControls ctls = new SearchControls (); 706 707 NamingEnumeration answer = ctx.search(baseSearch, filter, ctls); 708 709 while (answer.hasMore()) 710 { 711 SearchResult sr = (SearchResult ) answer.next(); 712 Attributes attribs = sr.getAttributes(); 713 Attribute attr = attribs.get("turbinePermissionName"); 714 715 if (attr != null) 716 { 717 NamingEnumeration values = attr.getAll(); 718 719 while (values.hasMore()) 720 { 721 String permName = values.next().toString(); 722 Permission perm = getNewPermission(permName); 723 724 permissions.put(perm.getName(), perm); 725 } 726 } 727 } 728 } 729 catch (NamingException  |