View Javadoc

1   package org.apache.turbine.services.security.ldap;
2   
3   
4   /*
5    * Copyright 2001-2004 The Apache Software Foundation.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License")
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  
21  import java.util.Hashtable;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Vector;
25  import javax.naming.NameAlreadyBoundException;
26  import javax.naming.NamingEnumeration;
27  import javax.naming.NamingException;
28  import javax.naming.directory.Attribute;
29  import javax.naming.directory.Attributes;
30  import javax.naming.directory.BasicAttribute;
31  import javax.naming.directory.BasicAttributes;
32  import javax.naming.directory.DirContext;
33  import javax.naming.directory.SearchControls;
34  import javax.naming.directory.SearchResult;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.turbine.om.security.Group;
39  import org.apache.turbine.om.security.Permission;
40  import org.apache.turbine.om.security.Role;
41  import org.apache.turbine.om.security.TurbineGroup;
42  import org.apache.turbine.om.security.TurbinePermission;
43  import org.apache.turbine.om.security.TurbineRole;
44  import org.apache.turbine.om.security.User;
45  import org.apache.turbine.services.security.BaseSecurityService;
46  import org.apache.turbine.services.security.TurbineSecurity;
47  import org.apache.turbine.util.security.AccessControlList;
48  import org.apache.turbine.util.security.DataBackendException;
49  import org.apache.turbine.util.security.EntityExistsException;
50  import org.apache.turbine.util.security.GroupSet;
51  import org.apache.turbine.util.security.PermissionSet;
52  import org.apache.turbine.util.security.RoleSet;
53  import org.apache.turbine.util.security.UnknownEntityException;
54  
55  /***
56   * An implementation of SecurityService that uses LDAP as a backend.
57   *
58   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
59   * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi </a>
60   * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy </a>
61   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
62   * @author <a href="mailto:marco@intermeta.de">Marco Kn&uuml;ttel</a>
63   * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
64   * @version $Id: LDAPSecurityService.java 222043 2004-12-06 17:47:33Z painter $
65   */
66  public class LDAPSecurityService extends BaseSecurityService
67  {
68  
69      /*** Logging */
70      private static Log log = LogFactory.getLog(LDAPSecurityService.class);
71  
72      /*
73       * -----------------------------------------------------------------------
74       *  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
75       * -----------------------------------------------------------------------
76       */
77  
78      /***
79       * Constructs an AccessControlList for a specific user.
80       *
81       * This method creates a snapshot of the state of security information
82       * concerning this user, at the moment of invocation and stores it
83       * into an AccessControlList object.
84       *
85       * @param user the user for whom the AccessControlList are to be retrieved
86       * @throws DataBackendException if there was an error accessing the backend.
87       * @throws UnknownEntityException if user account is not present.
88       * @return an AccessControlList for a specific user.
89       */
90      public AccessControlList getACL(User user)
91              throws DataBackendException, UnknownEntityException
92      {
93          if (!TurbineSecurity.accountExists(user))
94          {
95              throw new UnknownEntityException("The account '"
96                      + user.getName() + "' does not exist");
97          }
98          try
99          {
100             Hashtable roles = new Hashtable();
101             Hashtable permissions = new Hashtable();
102 
103             // notify the state modifiers (writers) that we want to create
104             // the snapshot.
105             lockShared();
106 
107             // construct the snapshot:
108             // foreach group in the system
109             Iterator groupsIterator = getAllGroups().iterator();
110 
111             while (groupsIterator.hasNext())
112             {
113                 Group group = (Group) groupsIterator.next();
114 
115                 // get roles of user in the group
116                 RoleSet groupRoles = getRoles(user, group);
117 
118                 // put the Set into roles(group)
119                 roles.put(group, groupRoles);
120                 // collect all permissoins in this group
121                 PermissionSet groupPermissions = new PermissionSet();
122                 // foreach role in Set
123                 Iterator rolesIterator = groupRoles.iterator();
124 
125                 while (rolesIterator.hasNext())
126                 {
127                     Role role = (Role) rolesIterator.next();
128                     // get permissions of the role
129                     PermissionSet rolePermissions = getPermissions(role);
130 
131                     groupPermissions.add(rolePermissions);
132                 }
133                 // put the Set into permissions(group)
134                 permissions.put(group, groupPermissions);
135             }
136             return getAclInstance(roles, permissions);
137         }
138         catch (Exception e)
139         {
140             throw new DataBackendException("Failed to build ACL for user '"
141                     + user.getName() + "'", e);
142         }
143         finally
144         {
145             // notify the state modifiers that we are done creating
146             // the snapshot.
147             unlockShared();
148         }
149     }
150 
151     /*
152      * -----------------------------------------------------------------------
153      * S E C U R I T Y  M A N A G E M E N T
154      * -----------------------------------------------------------------------
155      */
156 
157     /***
158      * Grant an User a Role in a Group.
159      *
160      * @param user the user.
161      * @param group the group.
162      * @param role the role.
163      * @throws DataBackendException if there was an error accessing the backend.
164      * @throws UnknownEntityException if user account, group or role
165      *         is not present.
166      */
167     public synchronized void grant(User user, Group group, Role role)
168             throws DataBackendException, UnknownEntityException
169     {
170         try
171         {
172             lockExclusive();
173 
174             String userName = user.getName();
175             String roleName = role.getName();
176             String groupName = group.getName();
177 
178             if (!accountExists(user))
179             {
180                 throw new UnknownEntityException(
181                         "User '" + userName + "' does not exist");
182             }
183 
184             if (!checkExists(role))
185             {
186                 throw new UnknownEntityException(
187                         "Role '" + roleName + "' does not exist");
188             }
189 
190             if (!checkExists(group))
191             {
192                 throw new UnknownEntityException(
193                         "Group '" + groupName + "' does not exist");
194             }
195 
196             // Make the distinguished name.
197             String dn = "turbineGroupName=" + groupName + ","
198                     + LDAPSecurityConstants.getNameAttribute()
199                     + "=" + userName + ","
200                     + LDAPSecurityConstants.getBaseSearch();
201 
202 
203             // Connect to LDAP.
204             DirContext ctx = LDAPUserManager.bindAsAdmin();
205 
206             // Make the attributes.
207             Attributes attrs = new BasicAttributes();
208 
209             attrs.put(new BasicAttribute("turbineRoleName", roleName));
210             attrs.put(new BasicAttribute("objectClass", "turbineUserGroup"));
211             attrs.put(new BasicAttribute("turbineUserUniqueId", userName));
212             try
213             {
214                 // Add the turbineUserGroup.
215                 ctx.bind(dn, null, attrs);
216             }
217             catch (NameAlreadyBoundException ex)
218             {
219                 // Since turbineUserGroup had already been created
220                 // then just add the role name attribute.
221                 attrs = new BasicAttributes();
222                 attrs.put(new BasicAttribute("turbineRoleName", roleName));
223                 ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs);
224             }
225 
226         }
227         catch (NamingException ex)
228         {
229             throw new DataBackendException("NamingException caught", ex);
230         }
231         finally
232         {
233             unlockExclusive();
234         }
235     }
236 
237     /***
238      * Revoke a Role in a Group from an User.
239      *
240      * @param user the user.
241      * @param group the group.
242      * @param role the role.
243      * @throws DataBackendException if there was an error accessing the backend.
244      * @throws UnknownEntityException if user account, group or role is
245      *         not present.
246      */
247     public synchronized void revoke(User user, Group group, Role role)
248             throws DataBackendException, UnknownEntityException
249     {
250         try
251         {
252             lockExclusive();
253 
254             String userName = user.getName();
255             String roleName = role.getName();
256             String groupName = group.getName();
257 
258             if (!accountExists(user))
259             {
260                 throw new UnknownEntityException(
261                         "User '" + userName + "' does not exist");
262             }
263 
264             if (!checkExists(role))
265             {
266                 throw new UnknownEntityException(
267                         "Role '" + roleName + "' does not exist");
268             }
269 
270             if (!checkExists(group))
271             {
272                 throw new UnknownEntityException(
273                         "Group '" + groupName + "' does not exist");
274             }
275 
276             // Make the distinguished name.
277             String dn = "turbineGroupName=" + groupName + ","
278                     + LDAPSecurityConstants.getNameAttribute()
279                     + "=" + userName + ","
280                     + LDAPSecurityConstants.getBaseSearch();
281 
282             // Make the attributes.
283             Attributes attrs = new BasicAttributes();
284 
285             attrs.put(new BasicAttribute("turbineRoleName", roleName));
286 
287             // Connect to LDAP.
288             DirContext ctx = LDAPUserManager.bindAsAdmin();
289 
290             // Remove the role.
291             ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs);
292 
293         }
294         catch (NamingException ex)
295         {
296             throw new DataBackendException("NamingException caught", ex);
297         }
298         finally
299         {
300             unlockExclusive();
301         }
302     }
303 
304     /***
305      * Grants a Role a Permission
306      *
307      * @param role the Role.
308      * @param permission the Permission.
309      * @throws DataBackendException if there was an error accessing the backend.
310      * @throws UnknownEntityException if role or permission is not present.
311      */
312     public synchronized void grant(Role role, Permission permission)
313             throws DataBackendException, UnknownEntityException
314     {
315         try
316         {
317             lockExclusive();
318 
319             String roleName = role.getName();
320             String permName = permission.getName();
321 
322             if (!checkExists(role))
323             {
324                 throw new UnknownEntityException(
325                         "Role '" + roleName + "' does not exist");
326             }
327 
328             if (!checkExists(permission))
329             {
330                 throw new UnknownEntityException(
331                         "Permission '" + permName + "' does not exist");
332             }
333 
334             // Make the distinguished name.
335             String dn = "turbineRoleName=" + roleName + ","
336                     + LDAPSecurityConstants.getBaseSearch();
337 
338             // Make the attributes.
339             Attributes attrs = new BasicAttributes();
340 
341             attrs.put(new BasicAttribute("turbinePermissionName", permName));
342 
343             // Connect to LDAP.
344             DirContext ctx = LDAPUserManager.bindAsAdmin();
345 
346             // Add the permission.
347             ctx.modifyAttributes(dn, DirContext.ADD_ATTRIBUTE, attrs);
348 
349         }
350         catch (NamingException ex)
351         {
352             throw new DataBackendException("NamingException caught", ex);
353         }
354         finally
355         {
356             unlockExclusive();
357         }
358     }
359 
360     /***
361      * Revokes a Permission from a Role.
362      *
363      * @param role the Role.
364      * @param permission the Permission.
365      * @throws DataBackendException if there was an error accessing the backend.
366      * @throws UnknownEntityException if role or permission is not present.
367      */
368     public synchronized void revoke(Role role, Permission permission)
369             throws DataBackendException, UnknownEntityException
370     {
371         try
372         {
373             lockExclusive();
374 
375             String roleName = role.getName();
376             String permName = permission.getName();
377 
378             if (!checkExists(role))
379             {
380                 throw new UnknownEntityException(
381                         "Role '" + roleName + "' does not exist");
382             }
383 
384             if (!checkExists(permission))
385             {
386                 throw new UnknownEntityException(
387                         "Permission '" + permName + "' does not exist");
388             }
389 
390             // Make the distinguished name.
391             String dn = "turbineRoleName=" + roleName + ","
392                     + LDAPSecurityConstants.getBaseSearch();
393 
394             // Make the attributes.
395             Attributes attrs = new BasicAttributes();
396 
397             attrs.put(new BasicAttribute("turbinePermissionName", permName));
398 
399             // Connect to LDAP.
400             DirContext ctx = LDAPUserManager.bindAsAdmin();
401 
402             // Remove the permission.
403             ctx.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrs);
404 
405         }
406         catch (NamingException ex)
407         {
408             throw new DataBackendException("NamingException caught", ex);
409         }
410         finally
411         {
412             unlockExclusive();
413         }
414     }
415 
416     /*
417      * -----------------------------------------------------------------------
418      * 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
419      * -----------------------------------------------------------------------
420      */
421 
422     /***
423      * Retrieves a new Group. It creates
424      * a new Group based on the Services Group implementation. It does not
425      * create a new Group in the system though. Use addGroup for that.
426      * <strong>Not implemented</strong>
427      *
428      * @param groupName The name of the Group to be retrieved.
429      * @return a Group.
430      */
431     public Group getNewGroup(String groupName)
432     {
433         return (Group) new TurbineGroup(groupName);
434     }
435 
436     /***
437      * Retrieves a new Role. It creates
438      * a new Role based on the Services Role implementation. It does not
439      * create a new Role in the system though. Use addRole for that.
440      * <strong>Not implemented</strong>
441      *
442      * @param roleName The name of the Group to be retrieved.
443      * @return a Role.
444      */
445     public Role getNewRole(String roleName)
446     {
447         return (Role) new TurbineRole(roleName);
448     }
449 
450     /***
451      * Retrieves a new Permission. It creates
452      * a new Permission based on the Services Permission implementation. It
453      * does not create a new Permission in the system though. Use create for
454      * that.
455      * <strong>Not implemented</strong>
456      *
457      * @param permissionName The name of the Permission to be retrieved.
458      * @return a Permission
459      */
460     public Permission getNewPermission(String permissionName)
461     {
462         return (Permission) new TurbinePermission(permissionName);
463     }
464 
465     /***
466      * Retrieve a set of Groups that meet the specified Criteria.
467      *
468      * @param criteria Criteria of Group selection.
469      * @return a set of Groups that meet the specified Criteria.
470      * @throws DataBackendException if there is problem with the Backend.
471      */
472     public GroupSet getGroups(Object criteria)
473             throws DataBackendException
474     {
475         Vector groups = new Vector();
476 
477         try
478         {
479             DirContext ctx = LDAPUserManager.bindAsAdmin();
480 
481             String baseSearch = LDAPSecurityConstants.getBaseSearch();
482             String filter = "(objectclass=turbineGroup)";
483 
484             /*
485              * Create the default search controls.
486              */
487             SearchControls ctls = new SearchControls();
488 
489             NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
490 
491             while (answer.hasMore())
492             {
493                 SearchResult sr = (SearchResult) answer.next();
494                 Attributes attribs = sr.getAttributes();
495                 Attribute attr = attribs.get("turbineGroupName");
496 
497                 if (attr != null && attr.get() != null)
498                 {
499                     Group group = getNewGroup(attr.get().toString());
500 
501                     groups.add(group);
502                 }
503             }
504         }
505         catch (NamingException ex)
506         {
507             throw new DataBackendException("NamingException caught", ex);
508         }
509         return new GroupSet(groups);
510     }
511 
512     /*** Get the Roles that a user belongs in a specific group.
513      * @param user The user.
514      * @param group The group
515      * @throws DataBackendException if there is a problem with
516      *     the LDAP service.
517      * @return a RoleSet.
518      */
519     private RoleSet getRoles(User user, Group group)
520             throws DataBackendException
521     {
522         Vector roles = new Vector(0);
523 
524         try
525         {
526             DirContext ctx = LDAPUserManager.bindAsAdmin();
527 
528             String baseSearch = LDAPSecurityConstants.getBaseSearch();
529             String filter = "(& ";
530 
531             filter += "(objectclass=turbineUserGroup)";
532             filter += "(turbineUserUniqueId=" + user.getName() + ")";
533             filter += "(turbineGroupName=" + group.getName() + ")";
534             filter += ")";
535 
536             /*
537              * Create the default search controls.
538              */
539             SearchControls ctls = new SearchControls();
540 
541             ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
542 
543             NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
544 
545             while (answer.hasMore())
546             {
547                 SearchResult sr = (SearchResult) answer.next();
548                 Attributes attribs = sr.getAttributes();
549                 Attribute attr = attribs.get("turbineRoleName");
550 
551                 if (attr != null)
552                 {
553                     NamingEnumeration values = attr.getAll();
554 
555                     while (values.hasMore())
556                     {
557                         Role role = getNewRole(values.next().toString());
558 
559                         roles.add(role);
560                     }
561                 }
562                 else
563                 {
564                     log.error("Role doesn't have a name");
565                 }
566             }
567         }
568         catch (NamingException ex)
569         {
570             throw new DataBackendException(
571                     "NamingException caught:", ex);
572         }
573 
574         return new RoleSet(roles);
575     }
576 
577     /***
578      * Retrieve a set of Roles that meet the specified Criteria.
579      *
580      * @param criteria Criteria of Roles selection.
581      * @return a set of Roles that meet the specified Criteria.
582      * @throws DataBackendException if there is a problem with the Backend.
583      */
584     public RoleSet getRoles(Object criteria) throws DataBackendException
585     {
586         Vector roles = new Vector(0);
587 
588         try
589         {
590             DirContext ctx = LDAPUserManager.bindAsAdmin();
591 
592             String baseSearch = LDAPSecurityConstants.getBaseSearch();
593             String filter = "(objectclass=turbineRole)";
594 
595             /*
596              * Create the default search controls.
597              */
598             SearchControls ctls = new SearchControls();
599 
600             NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
601 
602             while (answer.hasMore())
603             {
604                 SearchResult sr = (SearchResult) answer.next();
605                 Attributes attribs = sr.getAttributes();
606                 Attribute attr = attribs.get("turbineRoleName");
607 
608                 if (attr != null && attr.get() != null)
609                 {
610                     Role role = getNewRole(attr.get().toString());
611 
612                     roles.add(role);
613                 }
614                 else
615                 {
616                     log.error("Role doesn't have a name");
617                 }
618             }
619         }
620         catch (NamingException ex)
621         {
622             throw new DataBackendException("NamingException caught", ex);
623         }
624 
625         return new RoleSet(roles);
626     }
627 
628     /***
629      * Retrieve a set of Permissions that meet the specified Criteria.
630      *
631      * @param criteria Criteria of Permissions selection.
632      * @return a set of Permissions that meet the specified Criteria.
633      * @throws DataBackendException if there is a problem with the Backend.
634      */
635     public PermissionSet getPermissions(Object criteria)
636             throws DataBackendException
637     {
638         Vector permissions = new Vector();
639 
640         try
641         {
642             DirContext ctx = LDAPUserManager.bindAsAdmin();
643 
644             String baseSearch = LDAPSecurityConstants.getBaseSearch();
645             String filter = "(objectClass=turbinePermission)";
646 
647             /*
648              * Create the default search controls.
649              */
650             SearchControls ctls = new SearchControls();
651 
652             NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
653 
654             while (answer.hasMore())
655             {
656                 SearchResult sr = (SearchResult) answer.next();
657                 Attributes attribs = sr.getAttributes();
658                 Attribute attr = attribs.get("turbinePermissionName");
659 
660                 if (attr != null && attr.get() != null)
661                 {
662                     Permission perm = getNewPermission(attr.get().toString());
663 
664                     permissions.add(perm);
665                 }
666                 else
667                 {
668                     log.error("Permission doesn't have a name");
669                 }
670             }
671         }
672         catch (NamingException ex)
673         {
674             throw new DataBackendException(
675                     "The LDAP server specified is unavailable", ex);
676         }
677         return new PermissionSet(permissions);
678     }
679 
680     /***
681      * Retrieves all permissions associated with a role.
682      *
683      * @param role the role name, for which the permissions are to be retrieved.
684      * @throws DataBackendException if there was an error accessing the backend.
685      * @throws UnknownEntityException if the role is not present.
686      * @return a PermissionSet.
687      */
688     public PermissionSet getPermissions(Role role)
689             throws DataBackendException, UnknownEntityException
690     {
691         Hashtable permissions = new Hashtable();
692 
693         try
694         {
695             DirContext ctx = LDAPUserManager.bindAsAdmin();
696 
697             String baseSearch = LDAPSecurityConstants.getBaseSearch();
698             String filter = "(& ";
699 
700             filter += "(objectClass=turbineRole)";
701             filter += "(turbineRoleName=" + role.getName() + ")";
702             filter += ")";
703 
704             /*
705              * Create the default search controls.
706              */
707             SearchControls ctls = new SearchControls();
708 
709             NamingEnumeration answer = ctx.search(baseSearch, filter, ctls);
710 
711             while (answer.hasMore())
712             {
713                 SearchResult sr = (SearchResult) answer.next();
714                 Attributes attribs = sr.getAttributes();
715                 Attribute attr = attribs.get("turbinePermissionName");
716 
717                 if (attr != null)
718                 {
719                     NamingEnumeration values = attr.getAll();
720 
721                     while (values.hasMore())
722                     {
723                         String permName = values.next().toString();
724                         Permission perm = getNewPermission(permName);
725 
726                         permissions.put(perm.getName(), perm);
727                     }
728                 }
729             }
730         }
731         catch (NamingException ex)
732         {
733             throw new DataBackendException(
734                     "The LDAP server specified is unavailable", ex);
735         }
736         return new PermissionSet(permissions.values());
737     }
738 
739     /***
740      * Stores Group's attributes. The Groups is required to exist in the system.
741      *
742      * @param group The Group to be stored.
743      * @throws DataBackendException if there was an error accessing the backend.
744      * @throws UnknownEntityException if the group does not exist.
745      */
746     public void saveGroup(Group group) throws DataBackendException,
747             UnknownEntityException
748     {
749         // Not implemented yet.
750     }
751 
752     /***
753      * Stores Role's attributes. The Roles is required to exist in the system.
754      *
755      * @param role The Role to be stored.
756      * @throws DataBackendException if there was an error accessing the backend.
757      * @throws UnknownEntityException if the role does not exist.
758      */
759     public void saveRole(Role role) throws DataBackendException,
760             UnknownEntityException
761     {
762         // Not implemented yet.
763     }
764 
765     /***
766      * Stores Permission's attributes. The Permissions is required to exist in
767      * the system.
768      *
769      * @param permission The Permission to be stored.
770      * @throws DataBackendException if there was an error accessing the backend.
771      * @throws UnknownEntityException if the permission does not exist.
772      */
773     public void savePermission(Permission permission)
774             throws DataBackendException, UnknownEntityException
775     {
776         // Not implemented yet.
777     }
778 
779     /***
780      * Creates a new group with specified attributes.
781      * <strong>Not implemented</strong>
782      *
783      * @param group the object describing the group to be created.
784      * @return a new Group object that has id set up properly.
785      * @throws DataBackendException if there was an error accessing the backend.
786      * @throws EntityExistsException if the group already exists.
787      */
788     public synchronized Group addGroup(Group group)
789             throws DataBackendException, EntityExistsException
790     {
791         try
792         {
793             lockExclusive();
794 
795             String groupName = group.getName();
796 
797             if (checkExists(group))
798             {
799                 throw new EntityExistsException(
800                         "Group '" + groupName + "' already exists");
801             }
802 
803             // Make the distinguished name.
804             String dn = "turbineGroupName=" + groupName + ","
805                     + LDAPSecurityConstants.getBaseSearch();
806 
807             // Make the attributes.
808             Attributes attrs = new BasicAttributes();
809 
810             attrs.put(new BasicAttribute("objectClass", "turbineGroup"));
811             attrs.put(new BasicAttribute("turbineGroupName", groupName));
812 
813             // Connect to LDAP.
814             DirContext ctx = LDAPUserManager.bindAsAdmin();
815 
816             // Add the group in LDAP.
817             ctx.bind(dn, null, attrs);
818 
819             // Add the group to system-wide cache.
820             getAllGroups().add(group);
821 
822             return group;
823         }
824         catch (NamingException ex)
825         {
826             throw new DataBackendException("NamingException caught", ex);
827         }
828         finally
829         {
830             unlockExclusive();
831         }
832     }
833 
834     /***
835      * Creates a new role with specified attributes.
836      *
837      * @param role the object describing the role to be created.
838      * @return a new Role object that has id set up properly.
839      * @throws DataBackendException if there was an error accessing the backend.
840      * @throws EntityExistsException if the role already exists.
841      */
842     public synchronized Role addRole(Role role)
843             throws DataBackendException, EntityExistsException
844     {
845         try
846         {
847             lockExclusive();
848 
849             String roleName = role.getName();
850 
851             if (checkExists(role))
852             {
853                 throw new EntityExistsException(
854                         "Role '" + roleName + "' already exists");
855             }
856 
857             // Make the distinguished name.
858             String dn = "turbineRoleName=" + roleName + ","
859                     + LDAPSecurityConstants.getBaseSearch();
860 
861             // Make the attributes.
862             Attributes attrs = new BasicAttributes();
863 
864             attrs.put(new BasicAttribute("objectClass", "turbineRole"));
865             attrs.put(new BasicAttribute("turbineRoleName", roleName));
866 
867             // Connect to LDAP.
868             DirContext ctx = LDAPUserManager.bindAsAdmin();
869 
870             // Add the role in LDAP.
871             ctx.bind(dn, null, attrs);
872 
873             // Add the role to system-wide cache.
874             getAllRoles().add(role);
875 
876             return role;
877         }
878         catch (NamingException ex)
879         {
880             throw new DataBackendException("NamingException caught", ex);
881         }
882         finally
883         {
884             unlockExclusive();
885         }
886     }
887 
888     /***
889      * Creates a new permission with specified attributes.
890      * <strong>Not implemented</strong>
891      *
892      * @param permission the object describing the permission to be created.
893      * @return a new Permission object that has id set up properly.
894      * @throws DataBackendException if there was an error accessing the backend.
895      * @throws EntityExistsException if the permission already exists.
896      */
897     public synchronized Permission addPermission(Permission permission)
898             throws DataBackendException, EntityExistsException
899     {
900         try
901         {
902             lockExclusive();
903 
904             String permName = permission.getName();
905 
906             if (checkExists(permission))
907             {
908                 throw new EntityExistsException(
909                         "Permission '" + permName + "' already exists");
910             }
911 
912             // Make the distinguished name.
913             String dn = "turbinePermissionName=" + permName + ","
914                     + LDAPSecurityConstants.getBaseSearch();
915 
916             // Make the attributes.
917             Attributes attrs = new BasicAttributes();
918 
919             attrs.put(new BasicAttribute("objectClass", "turbinePermission"));
920             attrs.put(new BasicAttribute("turbinePermissionName", permName));
921 
922             DirContext ctx = LDAPUserManager.bindAsAdmin();
923 
924             // Add the permission in LDAP.
925             ctx.bind(dn, null, attrs);
926 
927             // add the permission to system-wide cache
928             getAllPermissions().add(permission);
929 
930             return permission;
931         }
932         catch (NamingException ex)
933         {
934             throw new DataBackendException("NamingException caught", ex);
935         }
936         finally
937         {
938             unlockExclusive();
939         }
940     }
941 
942     /***
943      * Removes a Group from the system.
944      *
945      * @param group object describing group to be removed.
946      * @throws DataBackendException if there was an error accessing the backend.
947      * @throws UnknownEntityException if the group does not exist.
948      */
949     public synchronized void removeGroup(Group group)
950             throws DataBackendException, UnknownEntityException
951     {
952         try
953         {
954             lockExclusive();
955 
956             String groupName = group.getName();
957 
958             if (!checkExists(group))
959             {
960                 throw new UnknownEntityException(
961                         "Group '" + groupName + "' does not exist");
962             }
963 
964             // Make the distinguished name.
965             String dn = "turbineGroupName=" + groupName + ","
966                     + LDAPSecurityConstants.getBaseSearch();
967 
968             DirContext ctx = LDAPUserManager.bindAsAdmin();
969 
970             // Remove the group from LDAP.
971             ctx.unbind(dn);
972 
973             // Remove the group from system-wide cache.
974             getAllGroups().remove(group);
975         }
976         catch (NamingException ex)
977         {
978             throw new DataBackendException("NamingException caught", ex);
979         }
980         finally
981         {
982             unlockExclusive();
983         }
984     }
985 
986     /***
987      * Removes a Role from the system.
988      *
989      * @param role object describing role to be removed.
990      * @throws DataBackendException if there was an error accessing the backend.
991      * @throws UnknownEntityException if the role does not exist.
992      */
993     public synchronized void removeRole(Role role)
994             throws DataBackendException, UnknownEntityException
995     {
996         try
997         {
998             lockExclusive();
999 
1000             String roleName = role.getName();
1001 
1002             if (!checkExists(role))
1003             {
1004                 throw new UnknownEntityException(
1005                         "Role '" + roleName + "' does not exist");
1006             }
1007 
1008             // Make the distinguished name.
1009             String dn = "turbineRoleName=" + roleName + ","
1010                     + LDAPSecurityConstants.getBaseSearch();
1011 
1012             DirContext ctx = LDAPUserManager.bindAsAdmin();
1013 
1014             // Remove the role from LDAP.
1015             ctx.unbind(dn);
1016 
1017             // Remove the role from system-wide cache.
1018             getAllRoles().remove(role);
1019         }
1020         catch (NamingException ex)
1021         {
1022             throw new DataBackendException("NamingException caught", ex);
1023         }
1024         finally
1025         {
1026             unlockExclusive();
1027         }
1028     }
1029 
1030     /***
1031      * Removes a Permission from the system.
1032      *
1033      * @param permission object describing permission to be removed.
1034      * @throws DataBackendException if there was an error accessing the backend.
1035      * @throws UnknownEntityException if the permission does not exist.
1036      */
1037     public synchronized void removePermission(Permission permission)
1038             throws DataBackendException, UnknownEntityException
1039     {
1040         try
1041         {
1042             lockExclusive();
1043 
1044             String permName = permission.getName();
1045 
1046             if (!checkExists(permission))
1047             {
1048                 throw new UnknownEntityException(
1049                         "Permission '" + permName + "' does not exist");
1050             }
1051 
1052             // Make the distinguished name.
1053             String dn = "turbinePermissionName=" + permName + ","
1054                     + LDAPSecurityConstants.getBaseSearch();
1055 
1056             DirContext ctx = LDAPUserManager.bindAsAdmin();
1057 
1058             // Remove the permission in LDAP.
1059             ctx.unbind(dn);
1060 
1061             // Remove the permission from system-wide cache.
1062             getAllPermissions().remove(permission);
1063         }
1064         catch (NamingException ex)
1065         {
1066             throw new DataBackendException("NamingException caught", ex);
1067         }
1068         finally
1069         {
1070             unlockExclusive();
1071         }
1072     }
1073 
1074     /***
1075      * Renames an existing Group.
1076      *
1077      * @param group object describing the group to be renamed.
1078      * @param name the new name for the group.
1079      * @throws DataBackendException if there was an error accessing the backend.
1080      * @throws UnknownEntityException if the group does not exist.
1081      */
1082     public synchronized void renameGroup(Group group, String name)
1083             throws DataBackendException, UnknownEntityException
1084     {
1085         // Not implemented yet.
1086     }
1087 
1088     /***
1089      * Renames an existing Role.
1090      *
1091      * @param role object describing the role to be renamed.
1092      * @param name the new name for the role.
1093      * @throws DataBackendException if there was an error accessing the backend.
1094      * @throws UnknownEntityException if the role does not exist.
1095      */
1096     public synchronized void renameRole(Role role, String name)
1097             throws DataBackendException, UnknownEntityException
1098     {
1099         // Not implemented yet.
1100     }
1101 
1102     /***
1103      * Renames an existing Permission.
1104      *
1105      * @param permission object describing the permission to be renamed.
1106      * @param name the new name for the permission.
1107      * @throws DataBackendException if there was an error accessing the backend.
1108      * @throws UnknownEntityException if the permission does not exist.
1109      */
1110     public synchronized void renamePermission(Permission permission,
1111                                               String name)
1112             throws DataBackendException, UnknownEntityException
1113     {
1114         // Not implemented yet.
1115     }
1116 
1117     /***
1118      * Revoke all the roles to a user
1119      * @param user the user.
1120      * @throws DataBackendException if there is an error with the data backend.
1121      * @throws UnkownEntityException if the role or a permission is not found.
1122      */
1123     public void revokeAll(User user)
1124             throws DataBackendException, UnknownEntityException
1125     {
1126         Iterator groupsIterator = getAllGroups().iterator();
1127         while (groupsIterator.hasNext())
1128         {
1129             Group group = (Group) groupsIterator.next();
1130             Iterator rolesIterator = getRoles(user, group).iterator();
1131             while (rolesIterator.hasNext())
1132             {
1133                 Role role = (Role) rolesIterator.next();
1134                 revoke(user, group, role);
1135             }
1136         }
1137     }
1138 
1139     /***
1140      * Revoke all the permissions to a role.
1141      * @param role the role.
1142      * @throws DataBackendException if there is an error with the data backend.
1143      * @throws UnkownEntityException if the role or a permission is not found.
1144      */
1145     public void revokeAll(Role role)
1146             throws DataBackendException, UnknownEntityException
1147     {
1148         PermissionSet permissions = getPermissions(role);
1149         Iterator permIterator = permissions.iterator();
1150         while (permIterator.hasNext())
1151         {
1152             Permission perm = (Permission) permIterator.next();
1153             revoke(role, perm);
1154         }
1155     }
1156 
1157     /***
1158      * Revoke all the roles to a group.
1159      * @param group the group.
1160      * @throws DataBackendException if there is an error with the data backend.
1161      * @throws UnkownEntityException if the role or a permission is not found.
1162      */
1163     public void revokeAll(Group group)
1164             throws DataBackendException, UnknownEntityException
1165     {
1166         for (Iterator it = getUserList(new Object()).iterator();
1167              it.hasNext();)
1168         {
1169             User user = (User) it.next();
1170             for (Iterator rolesIterator = getRoles(user, group).iterator();
1171                  rolesIterator.hasNext();)
1172             {
1173                 Role role = (Role) rolesIterator.next();
1174                 revoke(user, group, role);
1175             }
1176         }
1177     }
1178 
1179     /***
1180      * Determines if the <code>Role</code> exists in the security system.
1181      *
1182      * @param role a <code>Role</code> value
1183      * @return true if the role exists in the system, false otherwise
1184      * @throws DataBackendException if there is an error with LDAP
1185      */
1186     public boolean checkExists(Role role)
1187             throws DataBackendException
1188     {
1189         RoleSet roleSet = getRoles(new Object());
1190 
1191         return roleSet.contains(role);
1192     }
1193 
1194     /***
1195      * Determines if the <code>Group</code> exists in the security system.
1196      *
1197      * @param group a <code>Group</code> value
1198      * @return true if the group exists in the system, false otherwise
1199      * @throws DataBackendException if there is an error with LDAP
1200      */
1201     public boolean checkExists(Group group)
1202             throws DataBackendException
1203     {
1204         GroupSet groupSet = getGroups(new Object());
1205 
1206         return groupSet.contains(group);
1207     }
1208 
1209     /***
1210      * Determines if the <code>Permission</code> exists in the security system.
1211      *
1212      * @param permission a <code>Permission</code> value
1213      * @return true if the permission exists in the system, false otherwise
1214      * @throws DataBackendException if there is an error with LDAP
1215      */
1216     public boolean checkExists(Permission permission)
1217             throws DataBackendException
1218     {
1219         PermissionSet permissionSet = getPermissions(new Object());
1220 
1221         return permissionSet.contains(permission);
1222     }
1223     
1224     
1225     /* (non-Javadoc)
1226      * @see org.apache.turbine.services.security.SecurityService#getAllGroups()
1227      */
1228     public GroupSet getAllGroups() throws DataBackendException {
1229         // TODO Auto-generated method stub
1230         return null;
1231     }
1232     /* (non-Javadoc)
1233      * @see org.apache.turbine.services.security.SecurityService#getAllPermissions()
1234      */
1235     public PermissionSet getAllPermissions() throws DataBackendException {
1236         // TODO Auto-generated method stub
1237         return null;
1238     }
1239     /* (non-Javadoc)
1240      * @see org.apache.turbine.services.security.SecurityService#getAllRoles()
1241      */
1242     public RoleSet getAllRoles() throws DataBackendException {
1243         // TODO Auto-generated method stub
1244         return null;
1245     }
1246     /* (non-Javadoc)
1247      * @see org.apache.turbine.services.security.SecurityService#getUserList(java.lang.Object)
1248      */
1249     public List getUserList(Object criteria) throws DataBackendException {
1250         // TODO Auto-generated method stub
1251         return null;
1252     }
1253 }