View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  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,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.userrepository;
21  
22  import org.apache.avalon.framework.activity.Initializable;
23  import org.apache.avalon.framework.configuration.Configurable;
24  import org.apache.avalon.framework.configuration.Configuration;
25  import org.apache.avalon.framework.configuration.ConfigurationException;
26  import org.apache.avalon.framework.context.Context;
27  import org.apache.avalon.framework.context.ContextException;
28  import org.apache.avalon.framework.context.Contextualizable;
29  import org.apache.avalon.framework.logger.AbstractLogEnabled;
30  import org.apache.avalon.framework.service.ServiceManager;
31  import org.apache.avalon.framework.service.Serviceable;
32  import org.apache.james.Constants;
33  import org.apache.james.services.User;
34  import org.apache.james.services.UsersRepository;
35  
36  import javax.naming.AuthenticationException;
37  import javax.naming.NamingEnumeration;
38  import javax.naming.NamingException;
39  import javax.naming.directory.Attribute;
40  import javax.naming.directory.Attributes;
41  import javax.naming.directory.BasicAttribute;
42  import javax.naming.directory.BasicAttributes;
43  import javax.naming.directory.DirContext;
44  import javax.naming.directory.InitialDirContext;
45  import javax.naming.directory.ModificationItem;
46  import javax.naming.directory.SearchControls;
47  import javax.naming.directory.SearchResult;
48  
49  import java.util.ArrayList;
50  import java.util.Hashtable;
51  import java.util.Iterator;
52  import java.util.List;
53  
54  /***
55   * Implementation of a Repository to store users.
56   *
57   * This clas is a dummy for the proposal!
58   *
59   * @version This is $Revision: 494012 $
60   */
61  public class UsersLDAPRepository
62      extends AbstractLogEnabled
63      implements UsersRepository, Serviceable, Configurable, Contextualizable, Initializable{
64  
65      private DirContext ctx;
66  
67      private String LDAPHost;
68      private String rootNodeDN;
69      private String rootURL;
70      private String serverRDN;
71      private String baseNodeDN;
72      private String baseURL;
73      private String mailAddressAttr;
74      private String identAttr;
75      private String authType;
76      private String principal;
77      private String password;
78      private String usersDomain;
79      private String membersAttr;
80      private boolean manageGroupAttr;
81      private String groupAttr;
82      private boolean managePasswordAttr;
83      private String passwordAttr;
84  
85      /***
86       * @see org.apache.avalon.framework.context.Contextualizable#contextualize(Context)
87       */
88      public void contextualize(Context context)
89          throws ContextException {
90          usersDomain = (String)context.get(Constants.DEFAULT_DOMAIN);
91      }
92  
93      /***
94       * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
95       */
96      public void service(ServiceManager compMgr) {
97          // this.comp = compMgr;
98      }
99  
100     /***
101      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
102      */
103     public void configure(Configuration conf)
104         throws ConfigurationException {
105 
106         LDAPHost = conf.getChild("LDAPServer").getValue();
107         rootNodeDN = conf.getChild("LDAPRoot").getValue();
108         serverRDN = conf.getChild("ThisServerRDN").getValue();
109         mailAddressAttr
110             = conf.getChild("MailAddressAttribute").getValue();
111         identAttr = conf.getChild("IdentityAttribute").getValue();
112         authType = conf.getChild("AuthenticationType").getValue();
113         principal = conf.getChild("Principal").getValue();
114         password = conf.getChild("Password").getValue();
115 
116         membersAttr = conf.getChild("MembersAttribute").getValue();
117         manageGroupAttr
118             = conf.getChild("ManageGroupAttribute").getValueAsBoolean( false );
119         groupAttr = conf.getChild("GroupAttribute").getValue();
120         managePasswordAttr = conf.getChild("ManagePasswordAttribute").getValueAsBoolean( false );
121         passwordAttr = conf.getChild("PasswordAttribute").getValue();
122     }
123 
124     public void setServerRoot() {
125         StringBuffer serverRootBuffer =
126             new StringBuffer(128)
127                     .append(serverRDN)
128                     .append(", ")
129                     .append(rootNodeDN);
130         this.setBase(serverRootBuffer.toString());
131     }
132 
133     public void setBase(String base) {
134         baseNodeDN = base;
135     }
136 
137     /***
138      * @see org.apache.avalon.framework.activity.Initializable#initialize()
139      */
140     public void initialize() throws Exception {
141         //setServerRoot();
142         StringBuffer urlBuffer =
143             new StringBuffer(128)
144                     .append(LDAPHost)
145                     .append("/");
146         rootURL = urlBuffer.toString() + rootNodeDN;
147         baseURL = urlBuffer.toString() + baseNodeDN;
148 
149         getLogger().info("Creating initial context from " + baseURL);
150         //System.out.println("Creating initial context from " + baseURL);
151 
152         Hashtable env = new Hashtable();
153         env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
154                 "com.sun.jndi.ldap.LdapCtxFactory");
155         env.put(javax.naming.Context.PROVIDER_URL, baseURL);
156 
157         try {
158             ctx = new InitialDirContext(env); // Could throw a NamingExcpetion
159         } catch (Exception e) {
160             getLogger().error("Exception creating InitialDirContext: ", e);
161         }
162 
163         getLogger().info("Initial context initialized from " + baseURL);
164     }
165 
166 
167 
168     public String getChildDestination(String childName) {
169 
170         String destination = null;
171         String filter = "cn=" + childName;
172         SearchControls ctls = new SearchControls();
173 
174         try {
175 
176             NamingEnumeration result  = ctx.search("", filter, ctls);
177 
178             if (result.hasMore()) {
179                 StringBuffer destinationBuffer =
180                     new StringBuffer(128)
181                             .append("cn=")
182                             .append(childName)
183                             .append(", ")
184                             .append(baseNodeDN);
185                 destination = destinationBuffer.toString();
186                 getLogger().info("Pre-exisisting LDAP node: " + destination);
187             } else {
188                 Attributes attrs = new BasicAttributes(true);
189                 Attribute objclass = new BasicAttribute("objectclass");
190                 objclass.add("top");
191                 objclass.add("rfc822MailGroup");
192                 attrs.put(objclass);
193                 Attribute cname = new BasicAttribute("cn");
194                 cname.add(childName);
195                 attrs.put(cname);
196                 Attribute owner = new BasicAttribute("owner");
197                 owner.add("JAMES-unassigned");
198                 attrs.put(owner);
199 
200                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
201                 ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
202                 ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
203 
204                 ctx.createSubcontext("cn=" + childName, attrs);
205                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
206 
207                 StringBuffer destinationBuffer =
208                     new StringBuffer(128)
209                             .append("cn=")
210                             .append(childName)
211                             .append(", ")
212                             .append(baseNodeDN);
213                 destination = destinationBuffer.toString();
214                 getLogger().info("Created new LDAP node: " + destination);
215             }
216         } catch (NamingException e) {
217             getLogger().error("Problem with child nodes " + e.getMessage(), e);
218         }
219 
220         return destination;
221     }
222 
223     /***
224      * List users in repository.
225      *
226      * @return Iterator over a collection of Strings, each being one user in the repository.
227      */
228     public Iterator list() {
229 
230         List result = new ArrayList();
231         // String filter = mailAddressAttr + "=*";
232         String[] attrIDs = {membersAttr};
233 
234         try {
235             Attribute members
236                 = ctx.getAttributes("", attrIDs).get(membersAttr);
237             if (members != null) {
238                 NamingEnumeration enumeration = members.getAll();
239                 while (enumeration.hasMore()) {
240                     result.add(enumeration.next());
241                 }
242             }
243         } catch (NamingException e) {
244             getLogger().error("Problem listing mailboxes. " + e );
245 
246         }
247         return result.iterator();
248     }
249 
250     // Methods from interface UsersRepository --------------------------
251 
252     /***
253      * Update the repository with the specified user object.  Unsupported for
254      * this user repository type.
255      *
256      * @return false
257      */
258     public boolean addUser(User user) {
259         return false;
260     }
261 
262     public  User getUserByName(String name) {
263         return new DefaultUser("dummy", "dummy");
264     }
265 
266     public User getUserByNameCaseInsensitive(String name) {
267         return getUserByName(name);
268     }
269 
270     public boolean containsCaseInsensitive(String name) {
271         return contains(name);
272     }
273 
274     // TODO: This is in violation of the contract for the interface.
275     //       Should only return null if the user doesn't exist.  Otherwise
276     //       this should return a consistent string representation of the name
277     public String getRealName(String name) {
278         return null;
279     }
280 
281     public boolean updateUser(User user) {
282         return false;
283     }
284 
285     /***
286      * Adds userName to the MemberAttribute (specified in conf.xml) of this
287      * node.
288      * If ManageGroupAttribute (conf.xml) is TRUE then calls addGroupToUser.
289      */
290     public synchronized void addUser(String userName, Object attributes) {
291 
292         String[] attrIDs = {membersAttr};
293 
294         // First, add username to mailGroup at baseNode
295 
296         try {
297             Attribute members = ctx.getAttributes("", attrIDs).get(membersAttr);
298 
299 
300             if (members != null && members.contains(userName)) {//user already here
301                 StringBuffer infoBuffer =
302                     new StringBuffer(64)
303                             .append("Found ")
304                             .append(userName)
305                             .append(" already in mailGroup. ");
306                 getLogger().info(infoBuffer.toString());
307                 //System.out.println(infoBuffer.toString());
308 
309             } else {
310                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
311                 ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
312                 ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
313 
314                 ModificationItem[] mods = new ModificationItem[1];
315                 mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute(membersAttr, userName));
316 
317                 ctx.modifyAttributes("", mods);
318 
319                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
320                 StringBuffer infoBuffer =
321                     new StringBuffer(128)
322                             .append(userName)
323                             .append(" added to mailGroup ")
324                             .append(baseNodeDN);
325                 getLogger().info(infoBuffer.toString());
326                 //System.out.println(infoBuffer.toString());
327             }
328         } catch (NamingException e) {
329             StringBuffer exceptionBuffer =
330                 new StringBuffer(256)
331                         .append("Problem adding user ")
332                         .append(userName)
333                         .append(" to: ")
334                         .append(baseNodeDN)
335                         .append(e);
336             getLogger().error(exceptionBuffer.toString());
337         }
338 
339         // Add attributes to user objects, if necessary
340 
341         if (manageGroupAttr) {
342             addGroupToUser(userName);
343         }
344 
345 //        if (managePasswordAttr) {
346 //            String userPassword = (String) attributes; // Not yet implemented
347 //        }
348     }
349     
350     /***
351      * @see org.apache.james.services.UsersRepository#addUser(java.lang.String, java.lang.String)
352      */
353     public boolean addUser(String username, String password) {
354         if (!contains(username)) {
355             addUser(username, password);
356             return contains(username);
357         } else {
358             return false;
359         }
360     }
361 
362     private void addGroupToUser(String userName) {
363         String[] attrIDs = {membersAttr};
364 
365         Hashtable env = new Hashtable();
366         env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
367         env.put(javax.naming.Context.PROVIDER_URL, rootURL);
368 
369         DirContext rootCtx = null;
370         try {
371             rootCtx = new InitialDirContext(env);
372 
373             String[] returnAttrs = {groupAttr};
374             SearchControls ctls = new SearchControls();
375             ctls.setReturningAttributes(attrIDs);
376             ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
377             StringBuffer filterBuffer =
378                 new StringBuffer(128)
379                         .append(mailAddressAttr)
380                         .append("=")
381                         .append(userName)
382                         .append("@")
383                         .append(usersDomain);
384             String filter = filterBuffer.toString();
385 
386             NamingEnumeration enumeration  = rootCtx.search("", filter, ctls);
387 
388             if (enumeration.hasMore()) { // ie User is in Directory
389                 SearchResult newSr = (SearchResult)enumeration.next();
390                 String userDN = newSr.getName();
391                 Attribute servers = rootCtx.getAttributes(userDN, returnAttrs).get(groupAttr);
392 
393 
394                 if (servers != null && servers.contains(baseNodeDN)) {//server already registered for user
395                     getLogger().info(baseNodeDN + " already in user's Groups. " );
396                     //System.out.println(baseNodeDN + " already in user's Groups. ");
397 
398                 } else {
399 
400                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
401                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
402                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
403 
404                     rootCtx.modifyAttributes(userDN, DirContext.ADD_ATTRIBUTE, new BasicAttributes(groupAttr, baseNodeDN, true));
405 
406                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
407                     getLogger().info(baseNodeDN + " added to user's groups ");
408                     //System.out.println(baseNodeDN + " added to users' groups ");
409 
410                 }
411 
412             } else {
413                 StringBuffer infoBuffer =
414                     new StringBuffer(64)
415                             .append("User ")
416                             .append(userName)
417                             .append(" not in directory.");
418                 getLogger().info(infoBuffer.toString());
419                 // System.out.println(infoBuffer.toString());
420 
421             }
422         } catch (NamingException e) {
423             getLogger().error("Problem adding group to user " + userName);
424             //System.out.println("Problem adding group to user " + userName);
425             //System.out.println(e.getMessage());
426             //e.printStackTrace();
427         } finally {
428             closeDirContext(rootCtx);
429         }
430     }
431 
432     public synchronized void removeUser(String userName) {
433         String[] attrIDs = {membersAttr};
434 
435         try {
436             Attribute members = ctx.getAttributes("", attrIDs).get(membersAttr);
437             if (members == null) {
438                 System.out.println("UsersLDAPRepository - Null list attribute.");
439 
440             } else  if (!members.contains(userName)) {//user not here
441                 getLogger().info(userName + " missing from mailGroup. ");
442                 //System.out.println(userName + " missing from mailGroup. ");
443 
444             } else {
445                 // First, remove username from mailGroup at baseNode
446 
447                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
448                 ctx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
449                 ctx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
450 
451                 ModificationItem[] mods = new ModificationItem[1];
452                 mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(membersAttr, userName));
453 
454                 ctx.modifyAttributes("", mods);
455 
456 
457                 ctx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
458                 getLogger().info(userName + " removed from mailGroup. ");
459                 //System.out.println(userName + " removed from mailGroup. ");
460             }
461         } catch (NamingException e) {
462             StringBuffer exceptionBuffer =
463                 new StringBuffer(256)
464                         .append("Problem removing user ")
465                         .append(userName)
466                         .append(": ")
467                         .append(e);
468             getLogger().error(exceptionBuffer.toString());
469             //System.out.println("Problem removing user " + userName);
470             //System.out.println(e.getMessage());
471             //e.printStackTrace();
472         }
473         if (manageGroupAttr) {
474             removeGroupFromUser(userName);
475         }
476 
477         if (managePasswordAttr) {
478             // not yet implemented
479         }
480 
481     }
482 
483     public void removeGroupFromUser(String userName) {
484 
485         Hashtable env = new Hashtable();
486         env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
487         env.put(javax.naming.Context.PROVIDER_URL, rootURL);
488 
489 
490         DirContext rootCtx = null;
491         try {
492             rootCtx = new InitialDirContext(env);
493 
494             // Find directory entry
495             String[] returnAttrs = {groupAttr};
496             SearchControls ctls = new SearchControls();
497             ctls.setReturningAttributes(returnAttrs);
498             ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
499             StringBuffer filterBuffer =
500                 new StringBuffer(128)
501                         .append(mailAddressAttr)
502                         .append("=")
503                         .append(userName)
504                         .append("@")
505                         .append(usersDomain);
506             String filter = filterBuffer.toString();
507 
508             NamingEnumeration enumeration  = rootCtx.search("", filter, ctls);
509 
510             if (enumeration.hasMore()) { // ie User is in Directory
511                 SearchResult newSr = (SearchResult)enumeration.next();
512                 String userDN = newSr.getName();
513 
514                 System.out.println("Found user entry: " + userDN);
515 
516                 Attribute servers = rootCtx.getAttributes(userDN, returnAttrs).get(groupAttr);
517                 if (servers == null) { //should not happen
518                     getLogger().info("GroupAttribute missing from user: " + userName);
519                     // System.out.println("GroupAttribute missing from user: " + userName );
520 
521                 } else if (!servers.contains(baseNodeDN)) {//server not registered for user
522                     getLogger().info(baseNodeDN + " missing from users' Groups. " );
523                     //System.out.println(baseNodeDN + " missing from users' Groups. ");
524 
525                 } else {
526 
527                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, authType);
528                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_PRINCIPAL, principal);
529                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_CREDENTIALS, password);
530 
531                     ModificationItem[] mods = new ModificationItem[1];
532                     mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute(groupAttr, baseNodeDN));
533 
534                     rootCtx.modifyAttributes(userDN, mods);
535 
536                     //rootCtx.modifyAttributes(userDN, DirContext.REPLACE_ATTRIBUTE, changes);
537 
538                     rootCtx.addToEnvironment(javax.naming.Context.SECURITY_AUTHENTICATION, "none");
539                     getLogger().info(baseNodeDN + " removed from users' groups " );
540                     //System.out.println(baseNodeDN + " removed from users' groups ");
541 
542                 }
543 
544             } else {
545                 StringBuffer infoBuffer =
546                     new StringBuffer(64)
547                             .append("User ")
548                             .append(userName)
549                             .append(" not in directory.");
550                 getLogger().info(infoBuffer.toString());
551                 //System.out.println(infoBuffer.toString());
552 
553             }
554         } catch (NamingException e) {
555             StringBuffer exceptionBuffer =
556                 new StringBuffer(256)
557                         .append("Problem removing user ")
558                         .append(userName)
559                         .append(e);
560             getLogger().error(exceptionBuffer.toString());
561             //System.out.println("Problem removing user " + userName);
562             //System.out.println(e.getMessage());
563             //e.printStackTrace();
564         } finally {
565             closeDirContext(rootCtx);
566             rootCtx = null;
567         }
568     }
569 
570 
571     public boolean contains(String name) {
572         boolean found = false;
573         String[] attrIDs = {membersAttr};
574 
575         try {
576             Attribute members = ctx.getAttributes("", attrIDs).get(membersAttr);
577             if (members != null && members.contains(name)) {
578                 found = true;
579                 StringBuffer infoBuffer =
580                     new StringBuffer(64)
581                             .append("Found ")
582                             .append(name)
583                             .append(" in mailGroup. ");
584                 getLogger().info(infoBuffer.toString());
585                 //System.out.println(infoBuffer.toString());
586             }
587         } catch (NamingException e) {
588             StringBuffer exceptionBuffer =
589                 new StringBuffer(256)
590                         .append("Problem finding user ")
591                         .append(name)
592                         .append(" : ")
593                         .append(e);
594             getLogger().error(exceptionBuffer.toString());
595             //System.out.println(exceptionBuffer.toString());
596         }
597         return found;
598     }
599 
600 
601     public boolean test(String name, String testPassword) {
602         boolean result = false;
603         boolean foundFlag = false;
604         String userDN = null;
605 
606         try {
607             String[] returnAttrs = {identAttr, passwordAttr};
608             SearchControls ctls = new SearchControls();
609             ctls.setReturningAttributes(returnAttrs);
610             ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
611             StringBuffer filterBuffer = 
612                 new StringBuffer(128)
613                         .append(mailAddressAttr)
614                         .append("=")
615                         .append(name)
616                         .append("@")
617                         .append(usersDomain);
618             String filter = filterBuffer.toString();
619 
620             Hashtable env = new Hashtable();
621             env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
622             env.put(javax.naming.Context.PROVIDER_URL, rootURL);
623             DirContext rootCtx = null;
624 
625             try {
626                 rootCtx = new InitialDirContext(env);
627     
628                 NamingEnumeration enumeration  = rootCtx.search("", filter, ctls);
629                 if (enumeration.hasMore()) { // ie User is in Directory
630                     SearchResult sr = (SearchResult)enumeration.next();
631                     String userRDN = sr.getName();
632                     StringBuffer userDNBuffer =
633                         new StringBuffer(128)
634                                 .append(userRDN)
635                                 .append(", ")
636                                 .append(rootNodeDN);
637                     userDN = userDNBuffer.toString();
638                     foundFlag = true;
639                     //System.out.println("UserDN is : " + userDN);
640                 }
641             } finally {
642                 closeDirContext(rootCtx);
643             }
644         } catch (Exception e) {
645             StringBuffer exceptionBuffer =
646                 new StringBuffer(256)
647                         .append("Problem finding user ")
648                         .append(name)
649                         .append(" for password test.")
650                         .append(e); 
651             getLogger().error(exceptionBuffer.toString());
652             //e.getMessage();
653             //e.printStackTrace();
654         }
655 
656         if (foundFlag) { // ie User is in Directory
657             Hashtable env2 = new Hashtable();
658             env2.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
659             env2.put(javax.naming.Context.PROVIDER_URL, rootURL);
660             env2.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
661             env2.put(javax.naming.Context.SECURITY_PRINCIPAL, userDN);
662             env2.put(javax.naming.Context.SECURITY_CREDENTIALS, testPassword);
663             //System.out.println("Creating initial context from " + baseURL);
664 
665             DirContext testCtx = null;
666             try {
667                 testCtx = new InitialDirContext(env2);
668                 result = true;
669 
670             } catch (AuthenticationException ae) {
671                 result = false;
672                 StringBuffer exceptionBuffer =
673                     new StringBuffer(256)
674                             .append("Attempt to authenticate with incorrect password for ")
675                             .append(name)
676                             .append(" : ")
677                             .append(ae); 
678                 getLogger().error(exceptionBuffer.toString());
679                 //System.out.println(exceptionBuffer.toString());
680                 //System.out.println(ae.getMessage());
681                 //ae.printStackTrace();
682             } catch (Exception e) {
683                 StringBuffer exceptionBuffer =
684                     new StringBuffer(256)
685                             .append("Problem checking password for ")
686                             .append(name)
687                             .append(" : ")
688                             .append(e); 
689                 getLogger().error(exceptionBuffer.toString());
690                 //System.out.println(exceptionBuffer.toString());
691                 //System.out.println(e.getMessage());
692                 //e.printStackTrace();
693             } finally {
694                 closeDirContext(testCtx);
695             }
696         }
697         return result;
698 
699     }
700 
701     public int countUsers() {
702 
703         String[] attrIDs = {membersAttr};
704         int result = -1;
705 
706         try {
707             Attribute members = ctx.getAttributes("", attrIDs).get(membersAttr);
708             if (members != null) {
709                 result = members.size();
710             } else {
711                 result = 0;
712             }
713         } catch (NamingException e) {
714             getLogger().error("Problem counting users: "  + e);
715             //System.out.println("Problem counting users. ");
716         }
717         return result;
718     }
719 
720     public String getDomains() {
721         return usersDomain;
722     }
723 
724     /***
725      * Disposes of all open directory contexts
726      *
727      * @throws Exception if an error is encountered during shutdown
728      */
729     public void dispose() throws Exception {
730         closeDirContext(ctx);
731         ctx = null;
732     }
733 
734     private void closeDirContext(DirContext ctx) {
735         try {
736             if (ctx != null) {
737                 ctx.close();
738             }
739         } catch (NamingException ne) {
740             getLogger().warn("UsersLDAPRepository: Unexpected exception encountered while closing directory context: " + ne);
741         }
742     }
743 }
744 
745