001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2007-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.core; 028 import org.opends.messages.Message; 029 import org.opends.messages.MessageBuilder; 030 031 032 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_AUTH_TYPE; 033 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_BIND_DN; 034 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_ERROR_MESSAGE; 035 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_MATCHED_DN; 036 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_PROCESSING_TIME; 037 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_REFERRAL_URLS; 038 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_RESULT_CODE; 039 import static org.opends.server.core.CoreConstants.LOG_ELEMENT_SASL_MECHANISM; 040 import static org.opends.server.loggers.AccessLogger.logBindRequest; 041 import static org.opends.server.loggers.AccessLogger.logBindResponse; 042 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; 043 import static org.opends.messages.CoreMessages.*; 044 045 import java.util.ArrayList; 046 import java.util.Iterator; 047 import java.util.List; 048 049 import org.opends.server.api.ClientConnection; 050 import org.opends.server.api.plugin.PluginResult; 051 import org.opends.server.loggers.debug.DebugLogger; 052 import org.opends.server.loggers.debug.DebugTracer; 053 import org.opends.server.protocols.asn1.ASN1OctetString; 054 import org.opends.server.types.*; 055 import org.opends.server.types.operation.PreParseBindOperation; 056 import org.opends.server.workflowelement.localbackend.*; 057 058 059 060 061 /** 062 * This class defines an operation that may be used to authenticate a user to 063 * the Directory Server. Note that for security restrictions, response messages 064 * that may be returned to the client must be carefully cleaned to ensure that 065 * they do not provide a malicious client with information that may be useful in 066 * an attack. This does impact the debugability of the server, but that can 067 * be addressed by calling the <CODE>setAuthFailureReason</CODE> method, which 068 * can provide a reason for a failure in a form that will not be returned to the 069 * client but may be written to a log file. 070 */ 071 public class BindOperationBasis 072 extends AbstractOperation 073 implements BindOperation, PreParseBindOperation 074 { 075 /** 076 * The tracer object for the debug logger. 077 */ 078 private static final DebugTracer TRACER = DebugLogger.getTracer(); 079 080 // The credentials used for SASL authentication. 081 private ASN1OctetString saslCredentials; 082 083 // The server SASL credentials provided to the client in the response. 084 private ASN1OctetString serverSASLCredentials; 085 086 // The authentication info for this bind operation. 087 private AuthenticationInfo authInfo = null; 088 089 // The authentication type used for this bind operation. 090 private AuthenticationType authType; 091 092 // The raw, unprocessed bind DN as contained in the client request. 093 private ByteString rawBindDN; 094 095 // The password used for simple authentication. 096 private ByteString simplePassword; 097 098 // The bind DN used for this bind operation. 099 private DN bindDN; 100 101 // The DN of the user entry that is attempting to authenticate. 102 private DN userEntryDN; 103 104 // The DN of the user as whom a SASL authentication was attempted (regardless 105 // of whether the authentication was successful) for the purpose of updating 106 // password policy state information. 107 private Entry saslAuthUserEntry; 108 109 // The set of response controls for this bind operation. 110 private List<Control> responseControls; 111 112 // A message explaining the reason for the authentication failure. 113 private Message authFailureReason; 114 115 // The SASL mechanism used for SASL authentication. 116 private String saslMechanism; 117 118 // A string representation of the protocol version for this bind operation. 119 private String protocolVersion; 120 121 /** 122 * Creates a new simple bind operation with the provided information. 123 * 124 * @param clientConnection The client connection with which this operation 125 * is associated. 126 * @param operationID The operation ID for this operation. 127 * @param messageID The message ID of the request with which this 128 * operation is associated. 129 * @param requestControls The set of controls included in the request. 130 * @param protocolVersion The string representation of the protocol version 131 * associated with this bind request. 132 * @param rawBindDN The raw, unprocessed bind DN as provided in the 133 * request from the client. 134 * @param simplePassword The password to use for the simple 135 * authentication. 136 */ 137 public BindOperationBasis(ClientConnection clientConnection, long operationID, 138 int messageID, List<Control> requestControls, 139 String protocolVersion, ByteString rawBindDN, 140 ByteString simplePassword) 141 { 142 super(clientConnection, operationID, messageID, requestControls); 143 144 145 this.protocolVersion = protocolVersion; 146 this.authType = AuthenticationType.SIMPLE; 147 this.saslMechanism = null; 148 this.saslCredentials = null; 149 150 if (rawBindDN == null) 151 { 152 this.rawBindDN = new ASN1OctetString(); 153 } 154 else 155 { 156 this.rawBindDN = rawBindDN; 157 } 158 159 if (simplePassword == null) 160 { 161 this.simplePassword = new ASN1OctetString(); 162 } 163 else 164 { 165 this.simplePassword = simplePassword; 166 } 167 168 bindDN = null; 169 userEntryDN = null; 170 responseControls = new ArrayList<Control>(0); 171 authFailureReason = null; 172 saslAuthUserEntry = null; 173 174 cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL, 175 ERR_CANNOT_CANCEL_BIND.get()); 176 } 177 178 179 180 /** 181 * Creates a new SASL bind operation with the provided information. 182 * 183 * @param clientConnection The client connection with which this operation 184 * is associated. 185 * @param operationID The operation ID for this operation. 186 * @param messageID The message ID of the request with which this 187 * operation is associated. 188 * @param requestControls The set of controls included in the request. 189 * @param protocolVersion The string representation of the protocol version 190 * associated with this bind request. 191 * @param rawBindDN The raw, unprocessed bind DN as provided in the 192 * request from the client. 193 * @param saslMechanism The SASL mechanism included in the request. 194 * @param saslCredentials The optional SASL credentials included in the 195 * request. 196 */ 197 public BindOperationBasis(ClientConnection clientConnection, long operationID, 198 int messageID, List<Control> requestControls, 199 String protocolVersion, ByteString rawBindDN, 200 String saslMechanism, ASN1OctetString saslCredentials) 201 { 202 super(clientConnection, operationID, messageID, requestControls); 203 204 205 this.protocolVersion = protocolVersion; 206 this.authType = AuthenticationType.SASL; 207 this.saslMechanism = saslMechanism; 208 this.saslCredentials = saslCredentials; 209 this.simplePassword = null; 210 211 if (rawBindDN == null) 212 { 213 this.rawBindDN = new ASN1OctetString(); 214 } 215 else 216 { 217 this.rawBindDN = rawBindDN; 218 } 219 220 bindDN = null; 221 userEntryDN = null; 222 responseControls = new ArrayList<Control>(0); 223 authFailureReason = null; 224 saslAuthUserEntry = null; 225 226 cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL, 227 ERR_CANNOT_CANCEL_BIND.get()); 228 } 229 230 231 232 /** 233 * Creates a new simple bind operation with the provided information. 234 * 235 * @param clientConnection The client connection with which this operation 236 * is associated. 237 * @param operationID The operation ID for this operation. 238 * @param messageID The message ID of the request with which this 239 * operation is associated. 240 * @param requestControls The set of controls included in the request. 241 * @param protocolVersion The string representation of the protocol version 242 * associated with this bind request. 243 * @param bindDN The bind DN for this bind operation. 244 * @param simplePassword The password to use for the simple 245 * authentication. 246 */ 247 public BindOperationBasis(ClientConnection clientConnection, long operationID, 248 int messageID, List<Control> requestControls, 249 String protocolVersion, DN bindDN, 250 ByteString simplePassword) 251 { 252 super(clientConnection, operationID, messageID, requestControls); 253 254 255 this.protocolVersion = protocolVersion; 256 this.authType = AuthenticationType.SIMPLE; 257 this.bindDN = bindDN; 258 this.saslMechanism = null; 259 this.saslCredentials = null; 260 261 if (bindDN == null) 262 { 263 rawBindDN = new ASN1OctetString(); 264 } 265 else 266 { 267 rawBindDN = new ASN1OctetString(bindDN.toString()); 268 } 269 270 if (simplePassword == null) 271 { 272 this.simplePassword = new ASN1OctetString(); 273 } 274 else 275 { 276 this.simplePassword = simplePassword; 277 } 278 279 responseControls = new ArrayList<Control>(0); 280 authFailureReason = null; 281 saslAuthUserEntry = null; 282 userEntryDN = null; 283 284 cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL, 285 ERR_CANNOT_CANCEL_BIND.get()); 286 } 287 288 289 290 /** 291 * Creates a new SASL bind operation with the provided information. 292 * 293 * @param clientConnection The client connection with which this operation 294 * is associated. 295 * @param operationID The operation ID for this operation. 296 * @param messageID The message ID of the request with which this 297 * operation is associated. 298 * @param requestControls The set of controls included in the request. 299 * @param protocolVersion The string representation of the protocol version 300 * associated with this bind request. 301 * @param bindDN The bind DN for this bind operation. 302 * @param saslMechanism The SASL mechanism included in the request. 303 * @param saslCredentials The optional SASL credentials included in the 304 * request. 305 */ 306 public BindOperationBasis(ClientConnection clientConnection, long operationID, 307 int messageID, List<Control> requestControls, 308 String protocolVersion, DN bindDN, 309 String saslMechanism, ASN1OctetString saslCredentials) 310 { 311 super(clientConnection, operationID, messageID, requestControls); 312 313 314 this.protocolVersion = protocolVersion; 315 this.authType = AuthenticationType.SASL; 316 this.bindDN = bindDN; 317 this.saslMechanism = saslMechanism; 318 this.saslCredentials = saslCredentials; 319 this.simplePassword = null; 320 321 if (bindDN == null) 322 { 323 rawBindDN = new ASN1OctetString(); 324 } 325 else 326 { 327 rawBindDN = new ASN1OctetString(bindDN.toString()); 328 } 329 330 responseControls = new ArrayList<Control>(0); 331 authFailureReason = null; 332 saslAuthUserEntry = null; 333 userEntryDN = null; 334 335 cancelResult = new CancelResult(ResultCode.CANNOT_CANCEL, 336 ERR_CANNOT_CANCEL_BIND.get()); 337 } 338 339 340 /** 341 * {@inheritDoc} 342 */ 343 public final AuthenticationType getAuthenticationType() 344 { 345 return authType; 346 } 347 348 349 /** 350 * {@inheritDoc} 351 */ 352 public final ByteString getRawBindDN() 353 { 354 return rawBindDN; 355 } 356 357 /** 358 * {@inheritDoc} 359 */ 360 public final void setRawBindDN(ByteString rawBindDN) 361 { 362 if (rawBindDN == null) 363 { 364 this.rawBindDN = new ASN1OctetString(); 365 } 366 else 367 { 368 this.rawBindDN = rawBindDN; 369 } 370 371 bindDN = null; 372 } 373 374 375 /** 376 * {@inheritDoc} 377 */ 378 public final DN getBindDN() 379 { 380 try 381 { 382 if (bindDN == null) 383 { 384 bindDN = DN.decode(rawBindDN); 385 } 386 } 387 catch (DirectoryException de) 388 { 389 if (debugEnabled()) 390 { 391 TRACER.debugCaught(DebugLogLevel.ERROR, de); 392 } 393 394 setResultCode(ResultCode.INVALID_CREDENTIALS); 395 setAuthFailureReason(de.getMessageObject()); 396 } 397 return bindDN; 398 } 399 400 /** 401 * {@inheritDoc} 402 */ 403 public final ByteString getSimplePassword() 404 { 405 return simplePassword; 406 } 407 408 /** 409 * {@inheritDoc} 410 */ 411 public final void setSimplePassword(ByteString simplePassword) 412 { 413 if (simplePassword == null) 414 { 415 this.simplePassword = new ASN1OctetString(); 416 } 417 else 418 { 419 this.simplePassword = simplePassword; 420 } 421 422 authType = AuthenticationType.SIMPLE; 423 saslMechanism = null; 424 saslCredentials = null; 425 } 426 427 /** 428 * {@inheritDoc} 429 */ 430 public final String getSASLMechanism() 431 { 432 return saslMechanism; 433 } 434 435 /** 436 * {@inheritDoc} 437 */ 438 public final ASN1OctetString getSASLCredentials() 439 { 440 return saslCredentials; 441 } 442 443 /** 444 * {@inheritDoc} 445 */ 446 public final void setSASLCredentials(String saslMechanism, 447 ASN1OctetString saslCredentials) 448 { 449 this.saslMechanism = saslMechanism; 450 this.saslCredentials = saslCredentials; 451 452 authType = AuthenticationType.SASL; 453 simplePassword = null; 454 } 455 456 /** 457 * {@inheritDoc} 458 */ 459 public final ASN1OctetString getServerSASLCredentials() 460 { 461 return serverSASLCredentials; 462 } 463 464 /** 465 * {@inheritDoc} 466 */ 467 public final void setServerSASLCredentials(ASN1OctetString 468 serverSASLCredentials) 469 { 470 this.serverSASLCredentials = serverSASLCredentials; 471 } 472 473 /** 474 * {@inheritDoc} 475 */ 476 public final Entry getSASLAuthUserEntry() 477 { 478 return saslAuthUserEntry; 479 } 480 481 /** 482 * {@inheritDoc} 483 */ 484 public final void setSASLAuthUserEntry(Entry saslAuthUserEntry) 485 { 486 this.saslAuthUserEntry = saslAuthUserEntry; 487 } 488 489 /** 490 * {@inheritDoc} 491 */ 492 public final Message getAuthFailureReason() 493 { 494 return authFailureReason; 495 } 496 497 /** 498 * {@inheritDoc} 499 */ 500 public final void setAuthFailureReason(Message message) 501 { 502 if (DirectoryServer.returnBindErrorMessages()) 503 { 504 appendErrorMessage(message); 505 } 506 else 507 { 508 authFailureReason = message; 509 } 510 } 511 512 /** 513 * {@inheritDoc} 514 */ 515 public final DN getUserEntryDN() 516 { 517 return userEntryDN; 518 } 519 520 /** 521 * {@inheritDoc} 522 */ 523 public final AuthenticationInfo getAuthenticationInfo() 524 { 525 return authInfo; 526 } 527 528 /** 529 * {@inheritDoc} 530 */ 531 public final void setAuthenticationInfo(AuthenticationInfo authInfo) 532 { 533 this.authInfo = authInfo; 534 } 535 536 /** 537 * {@inheritDoc} 538 */ 539 @Override() 540 public final OperationType getOperationType() 541 { 542 // Note that no debugging will be done in this method because it is a likely 543 // candidate for being called by the logging subsystem. 544 545 return OperationType.BIND; 546 } 547 548 /** 549 * {@inheritDoc} 550 */ 551 @Override() 552 public final String[][] getRequestLogElements() 553 { 554 // Note that no debugging will be done in this method because it is a likely 555 // candidate for being called by the logging subsystem. 556 557 if (authType == AuthenticationType.SASL) 558 { 559 return new String[][] 560 { 561 new String[] { LOG_ELEMENT_BIND_DN, String.valueOf(rawBindDN) }, 562 new String[] { LOG_ELEMENT_AUTH_TYPE, authType.toString() }, 563 new String[] { LOG_ELEMENT_SASL_MECHANISM, saslMechanism } 564 }; 565 } 566 else 567 { 568 return new String[][] 569 { 570 new String[] { LOG_ELEMENT_BIND_DN, String.valueOf(rawBindDN) }, 571 new String[] { LOG_ELEMENT_AUTH_TYPE, authType.toString() } 572 }; 573 } 574 } 575 576 /** 577 * {@inheritDoc} 578 */ 579 @Override() 580 public final String[][] getResponseLogElements() 581 { 582 // Note that no debugging will be done in this method because it is a likely 583 // candidate for being called by the logging subsystem. 584 585 String resultCode = String.valueOf(getResultCode().getIntValue()); 586 587 String errorMessage; 588 MessageBuilder errorMessageBuffer = getErrorMessage(); 589 if (errorMessageBuffer == null) 590 { 591 errorMessage = null; 592 } 593 else 594 { 595 errorMessage = errorMessageBuffer.toString(); 596 } 597 598 String matchedDNStr; 599 DN matchedDN = getMatchedDN(); 600 if (matchedDN == null) 601 { 602 matchedDNStr = null; 603 } 604 else 605 { 606 matchedDNStr = matchedDN.toString(); 607 } 608 609 String referrals; 610 List<String> referralURLs = getReferralURLs(); 611 if ((referralURLs == null) || referralURLs.isEmpty()) 612 { 613 referrals = null; 614 } 615 else 616 { 617 StringBuilder buffer = new StringBuilder(); 618 Iterator<String> iterator = referralURLs.iterator(); 619 buffer.append(iterator.next()); 620 621 while (iterator.hasNext()) 622 { 623 buffer.append(", "); 624 buffer.append(iterator.next()); 625 } 626 627 referrals = buffer.toString(); 628 } 629 630 String processingTime = 631 String.valueOf(getProcessingTime()); 632 633 return new String[][] 634 { 635 new String[] { LOG_ELEMENT_RESULT_CODE, resultCode }, 636 new String[] { LOG_ELEMENT_ERROR_MESSAGE, errorMessage }, 637 new String[] { LOG_ELEMENT_MATCHED_DN, matchedDNStr }, 638 new String[] { LOG_ELEMENT_REFERRAL_URLS, referrals }, 639 new String[] { LOG_ELEMENT_PROCESSING_TIME, processingTime } 640 }; 641 } 642 643 /** 644 * {@inheritDoc} 645 */ 646 @Override() 647 public final List<Control> getResponseControls() 648 { 649 return responseControls; 650 } 651 652 /** 653 * {@inheritDoc} 654 */ 655 @Override() 656 public final void addResponseControl(Control control) 657 { 658 responseControls.add(control); 659 } 660 661 /** 662 * {@inheritDoc} 663 */ 664 @Override() 665 public final void removeResponseControl(Control control) 666 { 667 responseControls.remove(control); 668 } 669 670 671 /** 672 * {@inheritDoc} 673 */ 674 @Override() 675 public final void toString(StringBuilder buffer) 676 { 677 buffer.append("BindOperation(connID="); 678 buffer.append(clientConnection.getConnectionID()); 679 buffer.append(", opID="); 680 buffer.append(operationID); 681 buffer.append(", protocol=\""); 682 buffer.append(clientConnection.getProtocol()); 683 buffer.append(" "); 684 buffer.append(protocolVersion); 685 buffer.append(", dn="); 686 buffer.append(rawBindDN); 687 buffer.append(", authType="); 688 buffer.append(authType); 689 buffer.append(")"); 690 } 691 692 /** 693 * {@inheritDoc} 694 */ 695 public void setUserEntryDN(DN userEntryDN) 696 { 697 this.userEntryDN = userEntryDN; 698 } 699 700 /** 701 * {@inheritDoc} 702 */ 703 public String getProtocolVersion() 704 { 705 return protocolVersion; 706 } 707 708 /** 709 * {@inheritDoc} 710 */ 711 public void setProtocolVersion(String protocolVersion) 712 { 713 this.protocolVersion = protocolVersion; 714 } 715 716 /** 717 * {@inheritDoc} 718 */ 719 public final void run() 720 { 721 setResultCode(ResultCode.UNDEFINED); 722 723 // Start the processing timer and initially set the result to indicate that 724 // the result is unknown. 725 setProcessingStartTime(); 726 727 // Log the bind request message. 728 logBindRequest(this); 729 730 ClientConnection clientConnection = getClientConnection(); 731 732 // Set a flag to indicate that a bind operation is in progress. This should 733 // ensure that no new operations will be accepted for this client until the 734 // bind is complete. 735 clientConnection.setBindInProgress(true); 736 737 // Wipe out any existing authentication for the client connection and create 738 // a placeholder that will be used if the bind is successful. 739 clientConnection.setUnauthenticated(); 740 741 // Abandon any operations that may be in progress for the client. 742 Message cancelReason = INFO_CANCELED_BY_BIND_REQUEST.get(); 743 CancelRequest cancelRequest = new CancelRequest(true, cancelReason); 744 clientConnection.cancelAllOperationsExcept(cancelRequest, getMessageID()); 745 746 747 // Get the plugin config manager that will be used for invoking plugins. 748 PluginConfigManager pluginConfigManager = 749 DirectoryServer.getPluginConfigManager(); 750 751 752 // This flag is set to true as soon as a workflow has been executed. 753 boolean workflowExecuted = false; 754 755 756 try 757 { 758 // Invoke the pre-parse bind plugins. 759 PluginResult.PreParse preParseResult = 760 pluginConfigManager.invokePreParseBindPlugins(this); 761 if (!preParseResult.continueProcessing()) 762 { 763 setResultCode(preParseResult.getResultCode()); 764 appendErrorMessage(preParseResult.getErrorMessage()); 765 setMatchedDN(preParseResult.getMatchedDN()); 766 setReferralURLs(preParseResult.getReferralURLs()); 767 return; 768 } 769 770 771 // Process the bind DN to convert it from the raw form as provided by the 772 // client into the form required for the rest of the bind processing. 773 DN bindDN = getBindDN(); 774 if (bindDN == null){ 775 return; 776 } 777 778 // If this is a simple bind 779 // Then check wether the bind DN is actually one of the alternate root DNs 780 // defined in the server. If so, then replace it with the actual DN 781 // for that user. 782 switch (getAuthenticationType()) 783 { 784 case SIMPLE: 785 DN actualRootDN = DirectoryServer.getActualRootBindDN(bindDN); 786 if (actualRootDN != null) 787 { 788 bindDN = actualRootDN; 789 } 790 } 791 792 793 // Retrieve the network group attached to the client connection 794 // and get a workflow to process the operation. 795 NetworkGroup ng = getClientConnection().getNetworkGroup(); 796 Workflow workflow = ng.getWorkflowCandidate(bindDN); 797 if (workflow == null) 798 { 799 // We have found no workflow for the requested base DN, just return 800 // a no such entry result code and stop the processing. 801 updateOperationErrMsgAndResCode(); 802 return; 803 } 804 workflow.execute(this); 805 workflowExecuted = true; 806 807 } 808 catch(CanceledOperationException coe) 809 { 810 // This shouldn't happen for bind operations. Just cancel anyways 811 if (debugEnabled()) 812 { 813 TRACER.debugCaught(DebugLogLevel.ERROR, coe); 814 } 815 816 setResultCode(ResultCode.CANCELED); 817 818 appendErrorMessage(cancelRequest.getCancelReason()); 819 } 820 finally 821 { 822 // If the bind processing is finished, then unset the "bind in progress" 823 // flag to allow other operations to be processed on the connection. 824 if (getResultCode() != ResultCode.SASL_BIND_IN_PROGRESS) 825 { 826 clientConnection.setBindInProgress(false); 827 } 828 829 // Stop the processing timer. 830 setProcessingStopTime(); 831 832 // Send the bind response to the client. 833 clientConnection.sendResponse(this); 834 835 // Log the bind response. 836 logBindResponse(this); 837 838 // Invoke the post-response bind plugins. 839 invokePostResponsePlugins(workflowExecuted); 840 } 841 } 842 843 844 /** 845 * Invokes the post response plugins. If a workflow has been executed 846 * then invoke the post response plugins provided by the workflow 847 * elements of the worklfow, otherwise invoke the post reponse plugins 848 * that have been registered with the current operation. 849 * 850 * @param workflowExecuted <code>true</code> if a workflow has been 851 * executed 852 */ 853 private void invokePostResponsePlugins(boolean workflowExecuted) 854 { 855 // Get the plugin config manager that will be used for invoking plugins. 856 PluginConfigManager pluginConfigManager = 857 DirectoryServer.getPluginConfigManager(); 858 859 // Invoke the post response plugins 860 if (workflowExecuted) 861 { 862 // The post responses are provided by the workflow elements of the 863 // workflow. 864 List localOperations = 865 (List)getAttachment(Operation.LOCALBACKENDOPERATIONS); 866 if (localOperations != null) 867 { 868 for (Object localOp : localOperations) 869 { 870 LocalBackendBindOperation localOperation = 871 (LocalBackendBindOperation)localOp; 872 // Invoke the post-response bind plugins. 873 pluginConfigManager.invokePostResponseBindPlugins(localOperation); 874 } 875 } 876 else 877 { 878 // The current operation does not implement any bind post response 879 // interface so we cannot invoke any post-response plugin. 880 } 881 } 882 } 883 884 885 /** 886 * Updates the error message and the result code of the operation. 887 * 888 * This method is called because no workflows were found to process 889 * the operation. 890 */ 891 private void updateOperationErrMsgAndResCode() 892 { 893 Message message = ERR_BIND_OPERATION_UNKNOWN_USER.get( 894 String.valueOf(getBindDN())); 895 setResultCode(ResultCode.INVALID_CREDENTIALS); 896 setAuthFailureReason(message); 897 } 898 899 } 900