View Javadoc

1   package org.apache.turbine.services.security.ldap;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
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  /***
54   * An implementation of SecurityService that uses LDAP as a backend.
55   *
56   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
57   * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi </a>
58   * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy </a>
59   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
60   * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
61   * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
62   * @version $Id: LDAPSecurityService.java 264148 2005-08-29 14:21:04Z henning $
63   */
64  public class LDAPSecurityService extends BaseSecurityService
65  {
66  
67      /*** Logging */
68      private static Log log = LogFactory.getLog(LDAPSecurityService.class);
69  
70      /*
71       * -----------------------------------------------------------------------
72       *  C R E A T I O N  O F  A C C E S S  C O N T R O L  L I S T
73       * -----------------------------------------------------------------------
74       */
75  
76      /***
77       * Constructs an AccessControlList for a specific user.
78       *
79       * This method creates a snapshot of the state of security information
80       * concerning this user, at the moment of invocation and stores it
81       * into an AccessControlList object.
82       *
83       * @param user the user for whom the AccessControlList are to be retrieved
84       * @throws DataBackendException if there was an error accessing the backend.
85       * @throws UnknownEntityException if user account is not present.
86       * @return an AccessControlList for a specific user.
87       */
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             // notify the state modifiers (writers) that we want to create
102             // the snapshot.
103             lockShared();
104 
105             // construct the snapshot:
106             // foreach group in the system
107             Iterator groupsIterator = getAllGroups().iterator();
108 
109             while (groupsIterator.hasNext())
110             {
111                 Group group = (Group) groupsIterator.next();
112 
113                 // get roles of user in the group
114                 RoleSet groupRoles = getRoles(user, group);
115 
116                 // put the Set into roles(group)
117                 roles.put(group, groupRoles);
118                 // collect all permissoins in this group
119                 PermissionSet groupPermissions = new PermissionSet();
120                 // foreach role in Set
121                 Iterator rolesIterator = groupRoles.iterator();
122 
123                 while (rolesIterator.hasNext())
124                 {
125                     Role role = (Role) rolesIterator.next();
126                     // get permissions of the role
127                     PermissionSet rolePermissions = getPermissions(role);
128 
129                     groupPermissions.add(rolePermissions);
130                 }
131                 // put the Set into permissions(group)
132                 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             // notify the state modifiers that we are done creating
144             // the snapshot.
145             unlockShared();
146         }
147     }
148 
149     /*
150      * -----------------------------------------------------------------------
151      * S E C U R I T Y  M A N A G E M E N T
152      * -----------------------------------------------------------------------
153      */
154 
155     /***
156      * Grant an User a Role in a Group.
157      *
158      * @param user the user.
159      * @param group the group.
160      * @param role the role.
161      * @throws DataBackendException if there was an error accessing the backend.
162      * @throws UnknownEntityException if user account, group or role
163      *         is not present.
164      */
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             // Make the distinguished name.
195             String dn = "turbineGroupName=" + groupName + ","
196                     + LDAPSecurityConstants.getNameAttribute()
197                     + "=" + userName + ","
198                     + LDAPSecurityConstants.getBaseSearch();
199 
200 
201             // Connect to LDAP.
202             DirContext ctx = LDAPUserManager.bindAsAdmin();
203 
204             // Make the attributes.
205             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                 // Add the turbineUserGroup.
213                 ctx.bind(dn, null, attrs);
214             }
215             catch (NameAlreadyBoundException ex)
216             {
217                 // Since turbineUserGroup had already been created
218                 // then just add the role name attribute.
219                 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     /***
236      * Revoke a Role in a Group from an User.
237      *
238      * @param user the user.
239      * @param group the group.
240      * @param role the role.
241      * @throws DataBackendException if there was an error accessing the backend.
242      * @throws UnknownEntityException if user account, group or role is
243      *         not present.
244      */
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             // Make the distinguished name.
275             String dn = "turbineGroupName=" + groupName + ","
276                     + LDAPSecurityConstants.getNameAttribute()
277                     + "=" + userName + ","
278                     + LDAPSecurityConstants.getBaseSearch();
279 
280             // Make the attributes.
281             Attributes attrs = new BasicAttributes();
282 
283             attrs.put(new BasicAttribute("turbineRoleName", roleName));
284 
285             // Connect to LDAP.
286             DirContext ctx = LDAPUserManager.bindAsAdmin();
287 
288             // Remove the role.
289             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     /***
303      * Grants a Role a Permission
304      *
305      * @param role the Role.
306      * @param permission the Permission.
307      * @throws DataBackendException if there was an error accessing the backend.
308      * @throws UnknownEntityException if role or permission is not present.
309      */
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             // Make the distinguished name.
333             String dn = "turbineRoleName=" + roleName + ","
334                     + LDAPSecurityConstants.getBaseSearch();
335 
336             // Make the attributes.
337             Attributes attrs = new BasicAttributes();
338 
339             attrs.put(new BasicAttribute("turbinePermissionName", permName));
340 
341             // Connect to LDAP.
342             DirContext ctx = LDAPUserManager.bindAsAdmin();
343 
344             // Add the permission.
345             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     /***
359      * Revokes a Permission from a Role.
360      *
361      * @param role the Role.
362      * @param permission the Permission.
363      * @throws DataBackendException if there was an error accessing the backend.
364      * @throws UnknownEntityException if role or permission is not present.
365      */
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             // Make the distinguished name.
389             String dn = "turbineRoleName=" + roleName + ","
390                     + LDAPSecurityConstants.getBaseSearch();
391 
392             // Make the attributes.
393             Attributes attrs = new BasicAttributes();
394 
395             attrs.put(new BasicAttribute("turbinePermissionName", permName));
396 
397             // Connect to LDAP.
398             DirContext ctx = LDAPUserManager.bindAsAdmin();
399 
400             // Remove the permission.
401             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     /*
415      * -----------------------------------------------------------------------
416      * G R O U P / R O L E / P E R M I S S I O N  M A N A G E M E N T
417      * -----------------------------------------------------------------------
418      */
419 
420     /***
421      * Retrieves a new Group. It creates
422      * a new Group based on the Services Group implementation. It does not
423      * create a new Group in the system though. Use addGroup for that.
424      * <strong>Not implemented</strong>
425      *
426      * @param groupName The name of the Group to be retrieved.
427      * @return a Group.
428      */
429     public Group getNewGroup(String groupName)
430     {
431         return (Group) new TurbineGroup(groupName);
432     }
433 
434     /***
435      * Retrieves a new Role. It creates
436      * a new Role based on the Services Role implementation. It does not
437      * create a new Role in the system though. Use addRole for that.
438      * <strong>Not implemented</strong>
439      *
440      * @param roleName The name of the Group to be retrieved.
441      * @return a Role.
442      */
443     public Role getNewRole(String roleName)
444     {
445         return (Role) new TurbineRole(roleName);
446     }
447 
448     /***
449      * Retrieves a new Permission. It creates
450      * a new Permission based on the Services Permission implementation. It
451      * does not create a new Permission in the system though. Use create for
452      * that.
453      * <strong>Not implemented</strong>
454      *
455      * @param permissionName The name of the Permission to be retrieved.
456      * @return a Permission
457      */
458     public Permission getNewPermission(String permissionName)
459     {
460         return (Permission) new TurbinePermission(permissionName);
461     }
462 
463     /***
464      * Retrieve a set of Groups that meet the specified Criteria.
465      *
466      * @param criteria Criteria of Group selection.
467      * @return a set of Groups that meet the specified Criteria.
468      * @throws DataBackendException if there is problem with the Backend.
469      */
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             /*
483              * Create the default search controls.
484              */
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     /*** Get the Roles that a user belongs in a specific group.
511      * @param user The user.
512      * @param group The group
513      * @throws DataBackendException if there is a problem with
514      *     the LDAP service.
515      * @return a RoleSet.
516      */
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             /*
535              * Create the default search controls.
536              */
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     /***
576      * Retrieve a set of Roles that meet the specified Criteria.
577      *
578      * @param criteria Criteria of Roles selection.
579      * @return a set of Roles that meet the specified Criteria.
580      * @throws DataBackendException if there is a problem with the Backend.
581      */
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             /*
594              * Create the default search controls.
595              */
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     /***
627      * Retrieve a set of Permissions that meet the specified Criteria.
628      *
629      * @param criteria Criteria of Permissions selection.
630      * @return a set of Permissions that meet the specified Criteria.
631      * @throws DataBackendException if there is a problem with the Backend.
632      */
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             /*
646              * Create the default search controls.
647              */
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     /***
679      * Retrieves all permissions associated with a role.
680      *
681      * @param role the role name, for which the permissions are to be retrieved.
682      * @throws DataBackendException if there was an error accessing the backend.
683      * @throws UnknownEntityException if the role is not present.
684      * @return a PermissionSet.
685      */
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             /*
703              * Create the default search controls.
704              */
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 ex)
730         {
731             throw new DataBackendException(
732                     "The LDAP server specified is unavailable", ex);
733         }
734         return new PermissionSet(permissions.values());
735     }
736 
737     /***
738      * Stores Group's attributes. The Groups is required to exist in the system.
739      *
740      * @param group The Group to be stored.
741      * @throws DataBackendException if there was an error accessing the backend.
742      * @throws UnknownEntityException if the group does not exist.
743      */
744     public void saveGroup(Group group) throws DataBackendException,
745             UnknownEntityException
746     {
747         // Not implemented yet.
748     }
749 
750     /***
751      * Stores Role's attributes. The Roles is required to exist in the system.
752      *
753      * @param role The Role to be stored.
754      * @throws DataBackendException if there was an error accessing the backend.
755      * @throws UnknownEntityException if the role does not exist.
756      */
757     public void saveRole(Role role) throws DataBackendException,
758             UnknownEntityException
759     {
760         // Not implemented yet.
761     }
762 
763     /***
764      * Stores Permission's attributes. The Permissions is required to exist in
765      * the system.
766      *
767      * @param permission The Permission to be stored.
768      * @throws DataBackendException if there was an error accessing the backend.
769      * @throws UnknownEntityException if the permission does not exist.
770      */
771     public void savePermission(Permission permission)
772             throws DataBackendException, UnknownEntityException
773     {
774         // Not implemented yet.
775     }
776 
777     /***
778      * Creates a new group with specified attributes.
779      * <strong>Not implemented</strong>
780      *
781      * @param group the object describing the group to be created.
782      * @return a new Group object that has id set up properly.
783      * @throws DataBackendException if there was an error accessing the backend.
784      * @throws EntityExistsException if the group already exists.
785      */
786     public synchronized Group addGroup(Group group)
787             throws DataBackendException, EntityExistsException
788     {
789         try
790         {
791             lockExclusive();
792 
793             String groupName = group.getName();
794 
795             if (checkExists(group))
796             {
797                 throw new EntityExistsException(
798                         "Group '" + groupName + "' already exists");
799             }
800 
801             // Make the distinguished name.
802             String dn = "turbineGroupName=" + groupName + ","
803                     + LDAPSecurityConstants.getBaseSearch();
804 
805             // Make the attributes.
806             Attributes attrs = new BasicAttributes();
807 
808             attrs.put(new BasicAttribute("objectClass", "turbineGroup"));
809             attrs.put(new BasicAttribute("turbineGroupName", groupName));
810 
811             // Connect to LDAP.
812             DirContext ctx = LDAPUserManager.bindAsAdmin();
813 
814             // Add the group in LDAP.
815             ctx.bind(dn, null, attrs);
816 
817             // Add the group to system-wide cache.
818             getAllGroups().add(group);
819 
820             return group;
821         }
822         catch (NamingException ex)
823         {
824             throw new DataBackendException("NamingException caught", ex);
825         }
826         finally
827         {
828             unlockExclusive();
829         }
830     }
831 
832     /***
833      * Creates a new role with specified attributes.
834      *
835      * @param role the object describing the role to be created.
836      * @return a new Role object that has id set up properly.
837      * @throws DataBackendException if there was an error accessing the backend.
838      * @throws EntityExistsException if the role already exists.
839      */
840     public synchronized Role addRole(Role role)
841             throws DataBackendException, EntityExistsException
842     {
843         try
844         {
845             lockExclusive();
846 
847             String roleName = role.getName();
848 
849             if (checkExists(role))
850             {
851                 throw new EntityExistsException(
852                         "Role '" + roleName + "' already exists");
853             }
854 
855             // Make the distinguished name.
856             String dn = "turbineRoleName=" + roleName + ","
857                     + LDAPSecurityConstants.getBaseSearch();
858 
859             // Make the attributes.
860             Attributes attrs = new BasicAttributes();
861 
862             attrs.put(new BasicAttribute("objectClass", "turbineRole"));
863             attrs.put(new BasicAttribute("turbineRoleName", roleName));
864 
865             // Connect to LDAP.
866             DirContext ctx = LDAPUserManager.bindAsAdmin();
867 
868             // Add the role in LDAP.
869             ctx.bind(dn, null, attrs);
870 
871             // Add the role to system-wide cache.
872             getAllRoles().add(role);
873 
874             return role;
875         }
876         catch (NamingException ex)
877         {
878             throw new DataBackendException("NamingException caught", ex);
879         }
880         finally
881         {
882             unlockExclusive();
883         }
884     }
885 
886     /***
887      * Creates a new permission with specified attributes.
888      * <strong>Not implemented</strong>
889      *
890      * @param permission the object describing the permission to be created.
891      * @return a new Permission object that has id set up properly.
892      * @throws DataBackendException if there was an error accessing the backend.
893      * @throws EntityExistsException if the permission already exists.
894      */
895     public synchronized Permission addPermission(Permission permission)
896             throws DataBackendException, EntityExistsException
897     {
898         try
899         {
900             lockExclusive();
901 
902             String permName = permission.getName();
903 
904             if (checkExists(permission))
905             {
906                 throw new EntityExistsException(
907                         "Permission '" + permName + "' already exists");
908             }
909 
910             // Make the distinguished name.
911             String dn = "turbinePermissionName=" + permName + ","
912                     + LDAPSecurityConstants.getBaseSearch();
913 
914             // Make the attributes.
915             Attributes attrs = new BasicAttributes();
916 
917             attrs.put(new BasicAttribute("objectClass", "turbinePermission"));
918             attrs.put(new BasicAttribute("turbinePermissionName", permName));
919 
920             DirContext ctx = LDAPUserManager.bindAsAdmin();
921 
922             // Add the permission in LDAP.
923             ctx.bind(dn, null, attrs);
924 
925             // add the permission to system-wide cache
926             getAllPermissions().add(permission);
927 
928             return permission;
929         }
930         catch (NamingException ex)
931         {
932             throw new DataBackendException("NamingException caught", ex);
933         }
934         finally
935         {
936             unlockExclusive();
937         }
938     }
939 
940     /***
941      * Removes a Group from the system.
942      *
943      * @param group object describing group to be removed.
944      * @throws DataBackendException if there was an error accessing the backend.
945      * @throws UnknownEntityException if the group does not exist.
946      */
947     public synchronized void removeGroup(Group group)
948             throws DataBackendException, UnknownEntityException
949     {
950         try
951         {
952             lockExclusive();
953 
954             String groupName = group.getName();
955 
956             if (!checkExists(group))
957             {
958                 throw new UnknownEntityException(
959                         "Group '" + groupName + "' does not exist");
960             }
961 
962             // Make the distinguished name.
963             String dn = "turbineGroupName=" + groupName + ","
964                     + LDAPSecurityConstants.getBaseSearch();
965 
966             DirContext ctx = LDAPUserManager.bindAsAdmin();
967 
968             // Remove the group from LDAP.
969             ctx.unbind(dn);
970 
971             // Remove the group from system-wide cache.
972             getAllGroups().remove(group);
973         }
974         catch (NamingException ex)
975         {
976             throw new DataBackendException("NamingException caught", ex);
977         }
978         finally
979         {
980             unlockExclusive();
981         }
982     }
983 
984     /***
985      * Removes a Role from the system.
986      *
987      * @param role object describing role to be removed.
988      * @throws DataBackendException if there was an error accessing the backend.
989      * @throws UnknownEntityException if the role does not exist.
990      */
991     public synchronized void removeRole(Role role)
992             throws DataBackendException, UnknownEntityException
993     {
994         try
995         {
996             lockExclusive();
997 
998             String roleName = role.getName();
999 
1000             if (!checkExists(role))
1001             {
1002                 throw new UnknownEntityException(
1003                         "Role '" + roleName + "' does not exist");
1004             }
1005 
1006             // Make the distinguished name.
1007             String dn = "turbineRoleName=" + roleName + ","
1008                     + LDAPSecurityConstants.getBaseSearch();
1009 
1010             DirContext ctx = LDAPUserManager.bindAsAdmin();
1011 
1012             // Remove the role from LDAP.
1013             ctx.unbind(dn);
1014 
1015             // Remove the role from system-wide cache.
1016             getAllRoles().remove(role);
1017         }
1018         catch (NamingException ex)
1019         {
1020             throw new DataBackendException("NamingException caught", ex);
1021         }
1022         finally
1023         {
1024             unlockExclusive();
1025         }
1026     }
1027 
1028     /***
1029      * Removes a Permission from the system.
1030      *
1031      * @param permission object describing permission to be removed.
1032      * @throws DataBackendException if there was an error accessing the backend.
1033      * @throws UnknownEntityException if the permission does not exist.
1034      */
1035     public synchronized void removePermission(Permission permission)
1036             throws DataBackendException, UnknownEntityException
1037     {
1038         try
1039         {
1040             lockExclusive();
1041 
1042             String permName = permission.getName();
1043 
1044             if (!checkExists(permission))
1045             {
1046                 throw new UnknownEntityException(
1047                         "Permission '" + permName + "' does not exist");
1048             }
1049 
1050             // Make the distinguished name.
1051             String dn = "turbinePermissionName=" + permName + ","
1052                     + LDAPSecurityConstants.getBaseSearch();
1053 
1054             DirContext ctx = LDAPUserManager.bindAsAdmin();
1055 
1056             // Remove the permission in LDAP.
1057             ctx.unbind(dn);
1058 
1059             // Remove the permission from system-wide cache.
1060             getAllPermissions().remove(permission);
1061         }
1062         catch (NamingException ex)
1063         {
1064             throw new DataBackendException("NamingException caught", ex);
1065         }
1066         finally
1067         {
1068             unlockExclusive();
1069         }
1070     }
1071 
1072     /***
1073      * Renames an existing Group.
1074      *
1075      * @param group object describing the group to be renamed.
1076      * @param name the new name for the group.
1077      * @throws DataBackendException if there was an error accessing the backend.
1078      * @throws UnknownEntityException if the group does not exist.
1079      */
1080     public synchronized void renameGroup(Group group, String name)
1081             throws DataBackendException, UnknownEntityException
1082     {
1083         // Not implemented yet.
1084     }
1085 
1086     /***
1087      * Renames an existing Role.
1088      *
1089      * @param role object describing the role to be renamed.
1090      * @param name the new name for the role.
1091      * @throws DataBackendException if there was an error accessing the backend.
1092      * @throws UnknownEntityException if the role does not exist.
1093      */
1094     public synchronized void renameRole(Role role, String name)
1095             throws DataBackendException, UnknownEntityException
1096     {
1097         // Not implemented yet.
1098     }
1099 
1100     /***
1101      * Renames an existing Permission.
1102      *
1103      * @param permission object describing the permission to be renamed.
1104      * @param name the new name for the permission.
1105      * @throws DataBackendException if there was an error accessing the backend.
1106      * @throws UnknownEntityException if the permission does not exist.
1107      */
1108     public synchronized void renamePermission(Permission permission,
1109                                               String name)
1110             throws DataBackendException, UnknownEntityException
1111     {
1112         // Not implemented yet.
1113     }
1114 
1115     /***
1116      * Revoke all the roles to a user
1117      * @param user the user.
1118      * @throws DataBackendException if there is an error with the data backend.
1119      * @throws UnkownEntityException if the role or a permission is not found.
1120      */
1121     public void revokeAll(User user)
1122             throws DataBackendException, UnknownEntityException
1123     {
1124         Iterator groupsIterator = getAllGroups().iterator();
1125         while (groupsIterator.hasNext())
1126         {
1127             Group group = (Group) groupsIterator.next();
1128             Iterator rolesIterator = getRoles(user, group).iterator();
1129             while (rolesIterator.hasNext())
1130             {
1131                 Role role = (Role) rolesIterator.next();
1132                 revoke(user, group, role);
1133             }
1134         }
1135     }
1136 
1137     /***
1138      * Revoke all the permissions to a role.
1139      * @param role the role.
1140      * @throws DataBackendException if there is an error with the data backend.
1141      * @throws UnkownEntityException if the role or a permission is not found.
1142      */
1143     public void revokeAll(Role role)
1144             throws DataBackendException, UnknownEntityException
1145     {
1146         PermissionSet permissions = getPermissions(role);
1147         Iterator permIterator = permissions.iterator();
1148         while (permIterator.hasNext())
1149         {
1150             Permission perm = (Permission) permIterator.next();
1151             revoke(role, perm);
1152         }
1153     }
1154 
1155     /***
1156      * Revoke all the roles to a group.
1157      * @param group the group.
1158      * @throws DataBackendException if there is an error with the data backend.
1159      * @throws UnkownEntityException if the role or a permission is not found.
1160      */
1161     public void revokeAll(Group group)
1162             throws DataBackendException, UnknownEntityException
1163     {
1164         for (Iterator it = getUserList(new Criteria()).iterator();
1165              it.hasNext();)
1166         {
1167             User user = (User) it.next();
1168             for (Iterator rolesIterator = getRoles(user, group).iterator();
1169                  rolesIterator.hasNext();)
1170             {
1171                 Role role = (Role) rolesIterator.next();
1172                 revoke(user, group, role);
1173             }
1174         }
1175     }
1176 
1177     /***
1178      * Determines if the <code>Role</code> exists in the security system.
1179      *
1180      * @param role a <code>Role</code> value
1181      * @return true if the role exists in the system, false otherwise
1182      * @throws DataBackendException if there is an error with LDAP
1183      */
1184     public boolean checkExists(Role role)
1185             throws DataBackendException
1186     {
1187         RoleSet roleSet = getRoles(new Criteria());
1188 
1189         return roleSet.contains(role);
1190     }
1191 
1192     /***
1193      * Determines if the <code>Group</code> exists in the security system.
1194      *
1195      * @param group a <code>Group</code> value
1196      * @return true if the group exists in the system, false otherwise
1197      * @throws DataBackendException if there is an error with LDAP
1198      */
1199     public boolean checkExists(Group group)
1200             throws DataBackendException
1201     {
1202         GroupSet groupSet = getGroups(new Criteria());
1203 
1204         return groupSet.contains(group);
1205     }
1206 
1207     /***
1208      * Determines if the <code>Permission</code> exists in the security system.
1209      *
1210      * @param permission a <code>Permission</code> value
1211      * @return true if the permission exists in the system, false otherwise
1212      * @throws DataBackendException if there is an error with LDAP
1213      */
1214     public boolean checkExists(Permission permission)
1215             throws DataBackendException
1216     {
1217         PermissionSet permissionSet = getPermissions(new Criteria());
1218 
1219         return permissionSet.contains(permission);
1220     }
1221 }