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 }