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