1 package org.apache.turbine.services.security.ldap;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.List;
23 import java.util.Hashtable;
24 import java.util.Vector;
25
26 import javax.naming.AuthenticationException;
27 import javax.naming.Context;
28 import javax.naming.NamingEnumeration;
29 import javax.naming.NamingException;
30 import javax.naming.directory.Attributes;
31 import javax.naming.directory.DirContext;
32 import javax.naming.directory.SearchControls;
33 import javax.naming.directory.SearchResult;
34
35 import org.apache.commons.configuration.Configuration;
36
37 import org.apache.turbine.om.security.User;
38 import org.apache.turbine.services.security.TurbineSecurity;
39 import org.apache.turbine.services.security.UserManager;
40 import org.apache.turbine.util.security.DataBackendException;
41 import org.apache.turbine.util.security.EntityExistsException;
42 import org.apache.turbine.util.security.PasswordMismatchException;
43 import org.apache.turbine.util.security.UnknownEntityException;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class LDAPUserManager implements UserManager
67 {
68
69
70
71
72
73 public void init(Configuration conf)
74 {
75
76 }
77
78
79
80
81
82
83
84
85
86
87 public boolean accountExists(User user) throws DataBackendException
88 {
89 return accountExists(user.getName());
90 }
91
92
93
94
95
96
97
98
99
100
101 public boolean accountExists(String username)
102 throws DataBackendException
103 {
104 try
105 {
106 User ldapUser = retrieve(username);
107 }
108 catch (UnknownEntityException ex)
109 {
110 return false;
111 }
112
113 return true;
114 }
115
116
117
118
119
120
121
122
123
124
125
126 public User retrieve(String username)
127 throws UnknownEntityException, DataBackendException
128 {
129 try
130 {
131 DirContext ctx = bindAsAdmin();
132
133
134
135
136 String userBaseSearch = LDAPSecurityConstants.getBaseSearch();
137 String filter = LDAPSecurityConstants.getNameAttribute();
138
139 filter = "(" + filter + "=" + username + ")";
140
141
142
143
144 SearchControls ctls = new SearchControls();
145
146 NamingEnumeration answer =
147 ctx.search(userBaseSearch, filter, ctls);
148
149 if (answer.hasMore())
150 {
151 SearchResult sr = (SearchResult) answer.next();
152 Attributes attribs = sr.getAttributes();
153 LDAPUser ldapUser = createLDAPUser();
154
155 ldapUser.setLDAPAttributes(attribs);
156 ldapUser.setTemp("turbine.user", ldapUser);
157
158 return ldapUser;
159 }
160 else
161 {
162 throw new UnknownEntityException("The given user: "
163 + username + "\n does not exist.");
164 }
165 }
166 catch (NamingException ex)
167 {
168 throw new DataBackendException(
169 "The LDAP server specified is unavailable", ex);
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 public User[] retrieve(Object criteria)
191 throws DataBackendException
192 {
193 return (User []) retrieveList(criteria).toArray(new User[0]);
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 public List retrieveList(Object criteria)
211 throws DataBackendException
212 {
213 List users = new Vector(0);
214
215 try
216 {
217 DirContext ctx = bindAsAdmin();
218
219 String userBaseSearch = LDAPSecurityConstants.getBaseSearch();
220 String filter = LDAPSecurityConstants.getNameAttribute();
221
222 filter = "(" + filter + "=*)";
223
224
225
226
227 SearchControls ctls = new SearchControls();
228
229 NamingEnumeration answer =
230 ctx.search(userBaseSearch, filter, ctls);
231
232 while (answer.hasMore())
233 {
234 SearchResult sr = (SearchResult) answer.next();
235 Attributes attribs = sr.getAttributes();
236 LDAPUser ldapUser = createLDAPUser();
237
238 ldapUser.setLDAPAttributes(attribs);
239 ldapUser.setTemp("turbine.user", ldapUser);
240 users.add(ldapUser);
241 }
242 }
243 catch (NamingException ex)
244 {
245 throw new DataBackendException(
246 "The LDAP server specified is unavailable", ex);
247 }
248 return users;
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public User retrieve(String username, String password)
267 throws PasswordMismatchException,
268 UnknownEntityException, DataBackendException
269 {
270 User user = retrieve(username);
271
272 authenticate(user, password);
273 return user;
274 }
275
276
277
278
279
280
281
282
283
284
285
286 public void store(User user)
287 throws UnknownEntityException, DataBackendException
288 {
289 if (!accountExists(user))
290 {
291 throw new UnknownEntityException("The account '"
292 + user.getName() + "' does not exist");
293 }
294
295 try
296 {
297 LDAPUser ldapUser = (LDAPUser) user;
298 Attributes attrs = ldapUser.getLDAPAttributes();
299 String name = ldapUser.getDN();
300
301 DirContext ctx = bindAsAdmin();
302
303 ctx.modifyAttributes(name, DirContext.REPLACE_ATTRIBUTE, attrs);
304 }
305 catch (NamingException ex)
306 {
307 throw new DataBackendException("NamingException caught", ex);
308 }
309 }
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 public void saveOnSessionUnbind(User user)
325 throws UnknownEntityException, DataBackendException
326 {
327 if (!accountExists(user))
328 {
329 throw new UnknownEntityException("The account '" +
330 user.getName() + "' does not exist");
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 public void authenticate(User user, String password)
348 throws PasswordMismatchException,
349 UnknownEntityException,
350 DataBackendException
351 {
352 LDAPUser ldapUser = (LDAPUser) user;
353
354 try
355 {
356 bind(ldapUser.getDN(), password);
357 }
358 catch (AuthenticationException ex)
359 {
360 throw new PasswordMismatchException(
361 "The given password for: "
362 + ldapUser.getDN() + " is invalid\n");
363 }
364 catch (NamingException ex)
365 {
366 throw new DataBackendException(
367 "NamingException caught:", ex);
368 }
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 public void changePassword(User user, String oldPass, String newPass)
385 throws PasswordMismatchException,
386 UnknownEntityException, DataBackendException
387 {
388 throw new DataBackendException(
389 "The method changePassword has no implementation.");
390 }
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407 public void forcePassword(User user, String password)
408 throws UnknownEntityException, DataBackendException
409 {
410 throw new DataBackendException(
411 "The method forcePassword has no implementation.");
412 }
413
414
415
416
417
418
419
420
421
422 public void createAccount(User user, String initialPassword)
423 throws EntityExistsException, DataBackendException
424 {
425 if (accountExists(user))
426 {
427 throw new EntityExistsException("The account '"
428 + user.getName() + "' already exist");
429 }
430
431 try
432 {
433 LDAPUser ldapUser = (LDAPUser) user;
434 Attributes attrs = ldapUser.getLDAPAttributes();
435 String name = ldapUser.getDN();
436
437 DirContext ctx = bindAsAdmin();
438
439 ctx.bind(name, null, attrs);
440 }
441 catch (NamingException ex)
442 {
443 throw new DataBackendException("NamingException caught", ex);
444 }
445 }
446
447
448
449
450
451
452
453
454 public void removeAccount(User user)
455 throws UnknownEntityException, DataBackendException
456 {
457 if (!accountExists(user))
458 {
459 throw new UnknownEntityException("The account '"
460 + user.getName() + "' does not exist");
461 }
462
463 try
464 {
465 LDAPUser ldapUser = (LDAPUser) user;
466 String name = ldapUser.getDN();
467
468 DirContext ctx = bindAsAdmin();
469
470 ctx.unbind(name);
471 }
472 catch (NamingException ex)
473 {
474 throw new DataBackendException("NamingException caught", ex);
475 }
476 }
477
478
479
480
481
482
483
484 public static DirContext bindAsAdmin()
485 throws NamingException
486 {
487 String adminUser = LDAPSecurityConstants.getAdminUsername();
488 String adminPassword = LDAPSecurityConstants.getAdminPassword();
489
490 return bind(adminUser, adminPassword);
491 }
492
493
494
495
496
497
498
499
500
501 public static DirContext bind(String username, String password)
502 throws NamingException
503 {
504 String host = LDAPSecurityConstants.getLDAPHost();
505 String port = LDAPSecurityConstants.getLDAPPort();
506 String providerURL = "ldap://" + host + ":" + port;
507 String ldapProvider = LDAPSecurityConstants.getLDAPProvider();
508 String authentication = LDAPSecurityConstants.getLDAPAuthentication();
509
510
511
512
513
514 Hashtable env = new Hashtable();
515
516 env.put(Context.INITIAL_CONTEXT_FACTORY, ldapProvider);
517 env.put(Context.PROVIDER_URL, providerURL);
518 env.put(Context.SECURITY_AUTHENTICATION, authentication);
519 env.put(Context.SECURITY_PRINCIPAL, username);
520 env.put(Context.SECURITY_CREDENTIALS, password);
521
522 DirContext ctx = new javax.naming.directory.InitialDirContext(env);
523
524 return ctx;
525 }
526
527
528
529
530
531
532
533 private LDAPUser createLDAPUser()
534 throws DataBackendException
535 {
536 try
537 {
538 return (LDAPUser) TurbineSecurity.getUserInstance();
539 }
540 catch (ClassCastException ex)
541 {
542 throw new DataBackendException("ClassCastException:", ex);
543 }
544 catch (UnknownEntityException ex)
545 {
546 throw new DataBackendException("UnknownEntityException:", ex);
547 }
548 }
549
550 }