001 /*
002 * Copyright 2009-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2015 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk.unboundidds.logs;
022
023
024
025 import java.util.Collections;
026 import java.util.LinkedList;
027 import java.util.List;
028 import java.util.StringTokenizer;
029
030 import com.unboundid.ldap.sdk.ResultCode;
031 import com.unboundid.util.NotMutable;
032 import com.unboundid.util.ThreadSafety;
033 import com.unboundid.util.ThreadSafetyLevel;
034
035
036
037 /**
038 * <BLOCKQUOTE>
039 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
040 * LDAP SDK for Java. It is not available for use in applications that
041 * include only the Standard Edition of the LDAP SDK, and is not supported for
042 * use in conjunction with non-UnboundID products.
043 * </BLOCKQUOTE>
044 * This class provides a data structure that holds information about a log
045 * message that may appear in the Directory Server access log about the result
046 * of a bind operation processed by the Directory Server.
047 */
048 @NotMutable()
049 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
050 public final class BindResultAccessLogMessage
051 extends BindRequestAccessLogMessage
052 implements OperationResultAccessLogMessage
053 {
054 /**
055 * The serial version UID for this serializable class.
056 */
057 private static final long serialVersionUID = -5612410738721878134L;
058
059
060
061 // Indicates whether a retired password was used to perform the bind.
062 private final Boolean retiredPasswordUsed;
063
064 // Indicates whether the any uncached data was accessed in the course of
065 // processing this operation.
066 private final Boolean uncachedDataAccessed;
067
068 // The processing time for the operation.
069 private final Double processingTime;
070
071 // The queue time for the operation.
072 private final Double queueTime;
073
074 // The list of privileges required for processing the operation that the
075 // requester did not have.
076 private final List<String> missingPrivileges;
077
078 // The list of privileges used during the course of processing the operation
079 // before an alternate authorization identity was assigned.
080 private final List<String> preAuthZUsedPrivileges;
081
082 // The list of referral URLs for the operation.
083 private final List<String> referralURLs;
084
085 // The list of response control OIDs for the operation.
086 private final List<String> responseControlOIDs;
087
088 // The list of servers accessed while processing the operation.
089 private final List<String> serversAccessed;
090
091 // The list of privileges used during the course of processing the operation.
092 private final List<String> usedPrivileges;
093
094 // The numeric identifier for the authentication failure reason.
095 private final Long authFailureID;
096
097 // The number of intermediate response messages returned to the client.
098 private final Long intermediateResponsesReturned;
099
100 // The result code for the operation.
101 private final ResultCode resultCode;
102
103 // Additional information about the operation result.
104 private final String additionalInformation;
105
106 // The DN of the authenticated user.
107 private final String authDN;
108
109 // A message with information about the reason for the authentication failure.
110 private final String authFailureReason;
111
112 // The DN of the alternate authorization identity.
113 private final String authzDN;
114
115 // The name of the client connection policy selected for the client.
116 private final String clientConnectionPolicy;
117
118 // The diagnostic message for the operation.
119 private final String diagnosticMessage;
120
121 // The intermediate client result for the operation.
122 private final String intermediateClientResult;
123
124 // The matched DN for the operation.
125 private final String matchedDN;
126
127 // The port of the backend server to which the request has been forwarded.
128 private final Integer targetPort;
129
130 // The address of the backend server to which the request has been forwarded.
131 private final String targetHost;
132
133 // The protocol used to forward the request to the backend server.
134 private final String targetProtocol;
135
136
137
138 /**
139 * Creates a new bind result access log message from the provided message
140 * string.
141 *
142 * @param s The string to be parsed as a bind result access log message.
143 *
144 * @throws LogException If the provided string cannot be parsed as a valid
145 * log message.
146 */
147 public BindResultAccessLogMessage(final String s)
148 throws LogException
149 {
150 this(new LogMessage(s));
151 }
152
153
154
155 /**
156 * Creates a new bind result access log message from the provided log message.
157 *
158 * @param m The log message to be parsed as a bind result access log
159 * message.
160 */
161 public BindResultAccessLogMessage(final LogMessage m)
162 {
163 super(m);
164
165 diagnosticMessage = getNamedValue("message");
166 additionalInformation = getNamedValue("additionalInfo");
167 matchedDN = getNamedValue("matchedDN");
168 processingTime = getNamedValueAsDouble("etime");
169 queueTime = getNamedValueAsDouble("qtime");
170 intermediateClientResult = getNamedValue("from");
171 authDN = getNamedValue("authDN");
172 authzDN = getNamedValue("authzDN");
173 authFailureID = getNamedValueAsLong("authFailureID");
174 authFailureReason = getNamedValue("authFailureReason");
175 targetHost = getNamedValue("targetHost");
176 targetPort = getNamedValueAsInteger("targetPort");
177 targetProtocol = getNamedValue("targetProtocol");
178 clientConnectionPolicy = getNamedValue("clientConnectionPolicy");
179
180 intermediateResponsesReturned =
181 getNamedValueAsLong("intermediateResponsesReturned");
182
183 final Integer rcInteger = getNamedValueAsInteger("resultCode");
184 if (rcInteger == null)
185 {
186 resultCode = null;
187 }
188 else
189 {
190 resultCode = ResultCode.valueOf(rcInteger);
191 }
192
193 final String refStr = getNamedValue("referralURLs");
194 if ((refStr == null) || (refStr.length() == 0))
195 {
196 referralURLs = Collections.emptyList();
197 }
198 else
199 {
200 final LinkedList<String> refs = new LinkedList<String>();
201 int startPos = 0;
202 while (true)
203 {
204 final int commaPos = refStr.indexOf(",ldap", startPos);
205 if (commaPos < 0)
206 {
207 refs.add(refStr.substring(startPos));
208 break;
209 }
210 else
211 {
212 refs.add(refStr.substring(startPos, commaPos));
213 startPos = commaPos+1;
214 }
215 }
216 referralURLs = Collections.unmodifiableList(refs);
217 }
218
219 final String controlStr = getNamedValue("responseControls");
220 if (controlStr == null)
221 {
222 responseControlOIDs = Collections.emptyList();
223 }
224 else
225 {
226 final LinkedList<String> controlList = new LinkedList<String>();
227 final StringTokenizer t = new StringTokenizer(controlStr, ",");
228 while (t.hasMoreTokens())
229 {
230 controlList.add(t.nextToken());
231 }
232 responseControlOIDs = Collections.unmodifiableList(controlList);
233 }
234
235 final String serversAccessedStr = getNamedValue("serversAccessed");
236 if ((serversAccessedStr == null) || (serversAccessedStr.length() == 0))
237 {
238 serversAccessed = Collections.emptyList();
239 }
240 else
241 {
242 final LinkedList<String> servers = new LinkedList<String>();
243 final StringTokenizer tokenizer =
244 new StringTokenizer(serversAccessedStr, ",");
245 while (tokenizer.hasMoreTokens())
246 {
247 servers.add(tokenizer.nextToken());
248 }
249 serversAccessed = Collections.unmodifiableList(servers);
250 }
251
252 uncachedDataAccessed = getNamedValueAsBoolean("uncachedDataAccessed");
253 retiredPasswordUsed = getNamedValueAsBoolean("retiredPasswordUsed");
254
255 final String usedPrivilegesStr = getNamedValue("usedPrivileges");
256 if ((usedPrivilegesStr == null) || (usedPrivilegesStr.length() == 0))
257 {
258 usedPrivileges = Collections.emptyList();
259 }
260 else
261 {
262 final LinkedList<String> privileges = new LinkedList<String>();
263 final StringTokenizer tokenizer =
264 new StringTokenizer(usedPrivilegesStr, ",");
265 while (tokenizer.hasMoreTokens())
266 {
267 privileges.add(tokenizer.nextToken());
268 }
269 usedPrivileges = Collections.unmodifiableList(privileges);
270 }
271
272 final String preAuthZUsedPrivilegesStr =
273 getNamedValue("preAuthZUsedPrivileges");
274 if ((preAuthZUsedPrivilegesStr == null) ||
275 (preAuthZUsedPrivilegesStr.length() == 0))
276 {
277 preAuthZUsedPrivileges = Collections.emptyList();
278 }
279 else
280 {
281 final LinkedList<String> privileges = new LinkedList<String>();
282 final StringTokenizer tokenizer =
283 new StringTokenizer(preAuthZUsedPrivilegesStr, ",");
284 while (tokenizer.hasMoreTokens())
285 {
286 privileges.add(tokenizer.nextToken());
287 }
288 preAuthZUsedPrivileges = Collections.unmodifiableList(privileges);
289 }
290
291 final String missingPrivilegesStr = getNamedValue("missingPrivileges");
292 if ((missingPrivilegesStr == null) || (missingPrivilegesStr.length() == 0))
293 {
294 missingPrivileges = Collections.emptyList();
295 }
296 else
297 {
298 final LinkedList<String> privileges = new LinkedList<String>();
299 final StringTokenizer tokenizer =
300 new StringTokenizer(missingPrivilegesStr, ",");
301 while (tokenizer.hasMoreTokens())
302 {
303 privileges.add(tokenizer.nextToken());
304 }
305 missingPrivileges = Collections.unmodifiableList(privileges);
306 }
307 }
308
309
310
311 /**
312 * Retrieves the result code for the operation.
313 *
314 * @return The result code for the operation, or {@code null} if it is not
315 * included in the log message.
316 */
317 public ResultCode getResultCode()
318 {
319 return resultCode;
320 }
321
322
323
324 /**
325 * Retrieves the diagnostic message for the operation.
326 *
327 * @return The diagnostic message for the operation, or {@code null} if it is
328 * not included in the log message.
329 */
330 public String getDiagnosticMessage()
331 {
332 return diagnosticMessage;
333 }
334
335
336
337 /**
338 * Retrieves a message with additional information about the result of the
339 * operation.
340 *
341 * @return A message with additional information about the result of the
342 * operation, or {@code null} if it is not included in the log
343 * message.
344 */
345 public String getAdditionalInformation()
346 {
347 return additionalInformation;
348 }
349
350
351
352 /**
353 * Retrieves the matched DN for the operation.
354 *
355 * @return The matched DN for the operation, or {@code null} if it is not
356 * included in the log message.
357 */
358 public String getMatchedDN()
359 {
360 return matchedDN;
361 }
362
363
364
365 /**
366 * Retrieves the list of referral URLs for the operation.
367 *
368 * @return The list of referral URLs for the operation, or an empty list if
369 * it is not included in the log message.
370 */
371 public List<String> getReferralURLs()
372 {
373 return referralURLs;
374 }
375
376
377
378 /**
379 * Retrieves the number of intermediate response messages returned in the
380 * course of processing the operation.
381 *
382 * @return The number of intermediate response messages returned to the
383 * client in the course of processing the operation, or {@code null}
384 * if it is not included in the log message.
385 */
386 public Long getIntermediateResponsesReturned()
387 {
388 return intermediateResponsesReturned;
389 }
390
391
392
393 /**
394 * Retrieves the length of time in milliseconds required to process the
395 * operation.
396 *
397 * @return The length of time in milliseconds required to process the
398 * operation, or {@code null} if it is not included in the log
399 * message.
400 */
401 public Double getProcessingTimeMillis()
402 {
403 return processingTime;
404 }
405
406
407
408 /**
409 * Retrieves the length of time in milliseconds the operation was required to
410 * wait on the work queue.
411 *
412 * @return The length of time in milliseconds the operation was required to
413 * wait on the work queue, or {@code null} if it is not included in
414 * the log message.
415 */
416 public Double getQueueTimeMillis()
417 {
418 return queueTime;
419 }
420
421
422
423 /**
424 * Retrieves the OIDs of any response controls contained in the log message.
425 *
426 * @return The OIDs of any response controls contained in the log message, or
427 * an empty list if it is not included in the log message.
428 */
429 public List<String> getResponseControlOIDs()
430 {
431 return responseControlOIDs;
432 }
433
434
435
436 /**
437 * Retrieves a list of the additional servers that were accessed in the course
438 * of processing the operation. For example, if the access log message is
439 * from a Directory Proxy Server instance, then this may contain a list of the
440 * backend servers used to process the operation.
441 *
442 * @return A list of the additional servers that were accessed in the course
443 * of processing the operation, or an empty list if it is not
444 * included in the log message.
445 */
446 public List<String> getServersAccessed()
447 {
448 return serversAccessed;
449 }
450
451
452
453 /**
454 * Indicates whether the server accessed any uncached data in the course of
455 * processing the operation.
456 *
457 * @return {@code true} if the server was known to access uncached data in
458 * the course of processing the operation, {@code false} if the
459 * server was known not to access uncached data, or {@code null} if
460 * it is not included in the log message (and the server likely did
461 * not access uncached data).
462 */
463 public Boolean getUncachedDataAccessed()
464 {
465 return uncachedDataAccessed;
466 }
467
468
469
470 /**
471 * Retrieves the content of the intermediate client result for the
472 * operation.
473 *
474 * @return The content of the intermediate client result for the operation,
475 * or {@code null} if it is not included in the log message.
476 */
477 public String getIntermediateClientResult()
478 {
479 return intermediateClientResult;
480 }
481
482
483
484 /**
485 * Retrieves the DN of the user authenticated by the bind operation.
486 *
487 * @return The DN of the user authenticated by the bind operation, or
488 * {@code null} if it is not included in the log message.
489 */
490 public String getAuthenticationDN()
491 {
492 return authDN;
493 }
494
495
496
497 /**
498 * Retrieves the DN of the alternate authorization identity for the bind
499 * operation.
500 *
501 * @return The DN of the alternate authorization identity for the bind
502 * operation, or {@code null} if it is not included in the log
503 * message.
504 */
505 public String getAuthorizationDN()
506 {
507 return authzDN;
508 }
509
510
511
512 /**
513 * Retrieves the numeric identifier for the authentication failure reason.
514 *
515 * @return The numeric identifier for the authentication failure reason, or
516 * {@code null} if it is not included in the log message.
517 */
518 public Long getAuthenticationFailureID()
519 {
520 return authFailureID;
521 }
522
523
524
525 /**
526 * Retrieves a message with information about the reason that the
527 * authentication attempt failed.
528 *
529 * @return A message with information about the reason that the
530 * authentication attempt failed, or {@code null} if it is not
531 * included in the log message.
532 */
533 public String getAuthenticationFailureReason()
534 {
535 return authFailureReason;
536 }
537
538
539
540 /**
541 * Indicates whether a retired password was used in the course of processing
542 * the bind.
543 *
544 * @return {@code true} if a retired password was used in the course of
545 * processing the bind, {@code false} if a retired password was not
546 * used in the course of processing the bind, or {@code null} if
547 * this was not included in the log message (and a retired password
548 * was likely not used in the course of processing the operation).
549 */
550 public Boolean getRetiredPasswordUsed()
551 {
552 return retiredPasswordUsed;
553 }
554
555
556
557 /**
558 * Retrieves the address of the backend server to which the request has been
559 * forwarded.
560 *
561 * @return The address of the backend server to which the request has been
562 * forwarded, or {@code null} if it is not included in the log
563 * message.
564 */
565 public String getTargetHost()
566 {
567 return targetHost;
568 }
569
570
571
572 /**
573 * Retrieves the port of the backend server to which the request has been
574 * forwarded.
575 *
576 * @return The port of the backend server to which the request has been
577 * forwarded, or {@code null} if it is not included in the log
578 * message.
579 */
580 public Integer getTargetPort()
581 {
582 return targetPort;
583 }
584
585
586
587 /**
588 * Retrieves the protocol used to forward the request to the backend server.
589 *
590 * @return The protocol used to forward the request to the backend server, or
591 * {@code null} if it is not included in the log message.
592 */
593 public String getTargetProtocol()
594 {
595 return targetProtocol;
596 }
597
598
599
600 /**
601 * Retrieves the name of the client connection policy that was selected for
602 * the client connection.
603 *
604 * @return The name of the client connection policy that was selected for the
605 * client connection, or {@code null} if it is not included in the
606 * log message.
607 */
608 public String getClientConnectionPolicy()
609 {
610 return clientConnectionPolicy;
611 }
612
613
614
615 /**
616 * Retrieves the names of any privileges used during the course of processing
617 * the operation.
618 *
619 * @return The names of any privileges used during the course of processing
620 * the operation, or an empty list if no privileges were used or this
621 * is not included in the log message.
622 */
623 public List<String> getUsedPrivileges()
624 {
625 return usedPrivileges;
626 }
627
628
629
630 /**
631 * Retrieves the names of any privileges used during the course of processing
632 * the operation before an alternate authorization identity was assigned.
633 *
634 * @return The names of any privileges used during the course of processing
635 * the operation before an alternate authorization identity was
636 * assigned, or an empty list if no privileges were used or this is
637 * not included in the log message.
638 */
639 public List<String> getPreAuthorizationUsedPrivileges()
640 {
641 return preAuthZUsedPrivileges;
642 }
643
644
645
646 /**
647 * Retrieves the names of any privileges that would have been required for
648 * processing the operation but that the requester did not have.
649 *
650 * @return The names of any privileges that would have been required for
651 * processing the operation but that the requester did not have, or
652 * an empty list if there were no missing privileges or this is not
653 * included in the log message.
654 */
655 public List<String> getMissingPrivileges()
656 {
657 return missingPrivileges;
658 }
659
660
661
662 /**
663 * {@inheritDoc}
664 */
665 @Override()
666 public AccessLogMessageType getMessageType()
667 {
668 return AccessLogMessageType.RESULT;
669 }
670 }