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