001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2009 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.protocols.internal;
018
019import java.net.InetAddress;
020import java.util.ArrayList;
021import java.util.Collection;
022import java.util.Collections;
023import java.util.LinkedHashMap;
024import java.util.List;
025import java.util.Map;
026import java.util.concurrent.atomic.AtomicInteger;
027import java.util.concurrent.atomic.AtomicLong;
028
029import org.forgerock.i18n.LocalizableMessage;
030import org.forgerock.i18n.LocalizedIllegalArgumentException;
031import org.forgerock.i18n.slf4j.LocalizedLogger;
032import org.forgerock.opendj.ldap.AttributeDescription;
033import org.forgerock.opendj.ldap.ByteString;
034import org.forgerock.opendj.ldap.DN;
035import org.forgerock.opendj.ldap.RDN;
036import org.forgerock.opendj.ldap.ResultCode;
037import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
038import org.forgerock.opendj.ldap.requests.ModifyRequest;
039import org.forgerock.opendj.ldap.schema.AttributeType;
040import org.opends.server.api.ClientConnection;
041import org.opends.server.api.ConnectionHandler;
042import org.opends.server.core.AddOperation;
043import org.opends.server.core.AddOperationBasis;
044import org.opends.server.core.BindOperation;
045import org.opends.server.core.BindOperationBasis;
046import org.opends.server.core.CompareOperation;
047import org.opends.server.core.CompareOperationBasis;
048import org.opends.server.core.DeleteOperation;
049import org.opends.server.core.DeleteOperationBasis;
050import org.opends.server.core.DirectoryServer;
051import org.opends.server.core.ExtendedOperation;
052import org.opends.server.core.ExtendedOperationBasis;
053import org.opends.server.core.ModifyDNOperation;
054import org.opends.server.core.ModifyDNOperationBasis;
055import org.opends.server.core.ModifyOperation;
056import org.opends.server.core.ModifyOperationBasis;
057import org.opends.server.core.SearchOperation;
058import org.opends.server.types.Attribute;
059import org.opends.server.types.AttributeBuilder;
060import org.opends.server.types.Attributes;
061import org.opends.server.types.AuthenticationInfo;
062import org.opends.server.types.CancelRequest;
063import org.opends.server.types.CancelResult;
064import org.opends.server.types.Control;
065import org.opends.server.types.DirectoryException;
066import org.opends.server.types.DisconnectReason;
067import org.opends.server.types.Entry;
068import org.opends.server.types.IntermediateResponse;
069import org.opends.server.types.Modification;
070import org.opends.server.types.ObjectClass;
071import org.opends.server.types.Operation;
072import org.opends.server.types.Privilege;
073import org.opends.server.types.RawAttribute;
074import org.opends.server.types.RawModification;
075import org.opends.server.types.SearchResultEntry;
076import org.opends.server.types.SearchResultReference;
077import org.opends.server.util.AddChangeRecordEntry;
078import org.opends.server.util.DeleteChangeRecordEntry;
079import org.opends.server.util.ModifyChangeRecordEntry;
080import org.opends.server.util.ModifyDNChangeRecordEntry;
081
082import static org.forgerock.opendj.adapter.server3x.Converters.*;
083import static org.opends.messages.ProtocolMessages.*;
084import static org.opends.server.config.ConfigConstants.*;
085import static org.opends.server.util.CollectionUtils.*;
086import static org.opends.server.util.ServerConstants.*;
087import static org.opends.server.util.StaticUtils.*;
088
089/**
090 * This class defines a pseudo-connection object that can be used for
091 * performing internal operations.
092 */
093@org.opends.server.types.PublicAPI(
094     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
095     mayInstantiate=true,
096     mayExtend=false,
097     mayInvoke=true)
098public final class InternalClientConnection
099       extends ClientConnection
100{
101  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
102
103  /**
104   * The protocol version string that will be used for internal bind
105   * operations.  Since this is modeled after LDAPv3 binds, it will
106   * use a version number string of "3".
107   */
108  public static final String PROTOCOL_VERSION = "3";
109
110
111
112  /** The message ID counter to use for internal connections. */
113  private static AtomicInteger nextMessageID;
114
115  /** The connection ID counter to use for internal connections. */
116  private static AtomicLong nextConnectionID;
117
118  /** The operation ID counter to use for operations on this connection. */
119  private static AtomicLong nextOperationID;
120
121  /** The static connection for root-based connections. */
122  private static InternalClientConnection rootConnection;
123
124  /** The connection ID for this client connection. */
125  private final long connectionID;
126
127
128
129  static
130  {
131    nextMessageID    = new AtomicInteger(1);
132    nextConnectionID = new AtomicLong(-1);
133    nextOperationID  = new AtomicLong(0);
134  }
135
136
137
138  /**
139   * Creates a new internal client connection that will be
140   * authenticated as a root user for which access control will not be
141   * enforced.
142   */
143  private InternalClientConnection()
144  {
145    super();
146
147    // This connection will be authenticated as a root user so that no
148    // access control will be enforced.
149    String commonName    = "Internal Client";
150    String shortDNString = "cn=" + commonName;
151    String fullDNString  = shortDNString + ",cn=Root DNs,cn=config";
152    try
153    {
154      LinkedHashMap<ObjectClass,String> objectClasses = new LinkedHashMap<>();
155      put(objectClasses, DirectoryServer.getTopObjectClass());
156      put(objectClasses, DirectoryServer.getObjectClass(OC_PERSON, true));
157      put(objectClasses, DirectoryServer.getObjectClass(OC_ROOT_DN, true));
158
159      LinkedHashMap<AttributeType,List<Attribute>> userAttrs = new LinkedHashMap<>();
160      put(userAttrs, ATTR_COMMON_NAME, commonName);
161      put(userAttrs, ATTR_SN, commonName);
162      put(userAttrs, ATTR_ROOTDN_ALTERNATE_BIND_DN, shortDNString);
163
164      AttributeType privType = DirectoryServer.getAttributeType(OP_ATTR_PRIVILEGE_NAME);
165      AttributeBuilder builder = new AttributeBuilder(privType);
166      for (Privilege p : Privilege.getDefaultRootPrivileges())
167      {
168        builder.add(p.getName());
169      }
170
171      LinkedHashMap<AttributeType, List<Attribute>> operationalAttrs = new LinkedHashMap<>();
172      operationalAttrs.put(privType, builder.toAttributeList());
173
174
175      DN internalUserDN = DN.valueOf(fullDNString);
176      Entry internalUserEntry = new Entry(
177          internalUserDN, objectClasses, userAttrs, operationalAttrs);
178
179      this.authenticationInfo = new AuthenticationInfo(internalUserEntry, true);
180      super.setAuthenticationInfo(authenticationInfo);
181      super.setSizeLimit(0);
182      super.setTimeLimit(0);
183      super.setIdleTimeLimit(0);
184      super.setLookthroughLimit(0);
185    }
186    catch (LocalizedIllegalArgumentException e)
187    {
188      logger.traceException(e);
189      logger.error(ERR_INTERNAL_CANNOT_DECODE_DN, fullDNString, getExceptionMessage(e));
190    }
191
192    connectionID  = nextConnectionID.getAndDecrement();
193  }
194
195  private void put(Map<ObjectClass, String> objectClasses, ObjectClass oc)
196  {
197    objectClasses.put(oc, oc.getPrimaryName());
198  }
199
200  private void put(Map<AttributeType, List<Attribute>> Attrs, String attrName, String value)
201  {
202    List<Attribute> attrs = newLinkedList(Attributes.create(attrName, value));
203    Attrs.put(DirectoryServer.getAttributeType(attrName), attrs);
204  }
205
206  /**
207   * Creates a new internal client connection that will be
208   * authenticated as the specified user.
209   *
210   * @param  authInfo  The authentication information to use for the
211   *                   connection.
212   */
213  public InternalClientConnection(AuthenticationInfo authInfo)
214  {
215    super();
216
217    // Don't call super.setAuthenticationInfo() since this will register this
218    // connection in the authenticated users table, which is unnecessary and
219    // will also cause the connection to be leaked since internal connections
220    // are never closed/disconnected.
221    if (authInfo == null)
222    {
223      this.authenticationInfo = new AuthenticationInfo();
224      updatePrivileges(null, false);
225    }
226    else
227    {
228      this.authenticationInfo = authInfo;
229      updatePrivileges(authInfo.getAuthorizationEntry(), authInfo.isRoot());
230    }
231
232    super.setSizeLimit(0);
233    super.setTimeLimit(0);
234    super.setIdleTimeLimit(0);
235    super.setLookthroughLimit(0);
236
237    connectionID  = nextConnectionID.getAndDecrement();
238  }
239
240
241
242  /**
243   * Creates a new internal client connection that will be
244   * authenticated as the specified user.
245   *
246   * @param  userDN  The DN of the entry to use as the
247   *                 authentication and authorization identity.
248   *
249   * @throws  DirectoryException  If a problem occurs while trying to
250   *                              get the entry for the provided user
251   *                              DN.
252   */
253  public InternalClientConnection(DN userDN)
254         throws DirectoryException
255  {
256    this(getAuthInfoForDN(userDN));
257  }
258
259  /**
260   * Creates an authentication information object for the user with
261   * the specified DN.
262   *
263   * @param  userDN  The DN of the user for whom to create an
264   *                 authentication information object.
265   *
266   * @return  The appropriate authentication information object.
267   *
268   * @throws  DirectoryException  If a problem occurs while trying to
269   *                              create the authentication
270   *                              information object, or there is no
271   *                              such user in the directory.
272   */
273  private static AuthenticationInfo getAuthInfoForDN(DN userDN)
274          throws DirectoryException
275  {
276    if (userDN == null || userDN.isRootDN())
277    {
278      return new AuthenticationInfo();
279    }
280
281    DN rootUserDN = DirectoryServer.getActualRootBindDN(userDN);
282    if (rootUserDN != null)
283    {
284      userDN = rootUserDN;
285    }
286
287    Entry userEntry = DirectoryServer.getEntry(userDN);
288    if (userEntry == null)
289    {
290      LocalizableMessage m =
291           ERR_INTERNALCONN_NO_SUCH_USER.get(userDN);
292      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, m);
293    }
294
295    boolean isRoot = DirectoryServer.isRootDN(userDN);
296    return new AuthenticationInfo(userEntry, isRoot);
297  }
298
299
300
301  /**
302   * Retrieves a shared internal client connection that is
303   * authenticated as a root user.
304   *
305   * @return  A shared internal client connection that is
306   *          authenticated as a root user.
307   */
308  public static InternalClientConnection getRootConnection()
309  {
310    if (rootConnection == null)
311    {
312      rootConnection = new InternalClientConnection();
313    }
314
315    return rootConnection;
316  }
317
318
319
320  /**
321   * Retrieves the operation ID that should be used for the next
322   * internal operation.
323   *
324   * @return  The operation ID that should be used for the next
325   *          internal operation.
326   */
327  public static long nextOperationID()
328  {
329    long opID = nextOperationID.getAndIncrement();
330    if (opID < 0)
331    {
332      synchronized (nextOperationID)
333      {
334        if (nextOperationID.get() < 0)
335        {
336          nextOperationID.set(1);
337          return 0;
338        }
339        else
340        {
341          return nextOperationID.getAndIncrement();
342        }
343      }
344    }
345
346    return opID;
347  }
348
349
350
351  /**
352   * Retrieves the message ID that should be used for the next
353   * internal operation.
354   *
355   * @return  The message ID that should be used for the next internal
356   *          operation.
357   */
358  public static int nextMessageID()
359  {
360    int msgID = nextMessageID.getAndIncrement();
361    if (msgID < 0)
362    {
363      synchronized (nextMessageID)
364      {
365        if (nextMessageID.get() < 0)
366        {
367          nextMessageID.set(2);
368          return 1;
369        }
370        else
371        {
372          return nextMessageID.getAndIncrement();
373        }
374      }
375    }
376
377    return msgID;
378  }
379
380
381
382  /**
383   * Retrieves the unique identifier that has been assigned to this
384   * connection.
385   *
386   * @return  The unique identifier that has been assigned to this
387   *          connection.
388   */
389  @Override
390  public long getConnectionID()
391  {
392    return connectionID;
393  }
394
395
396
397  /**
398   * Retrieves the connection handler that accepted this client
399   * connection.
400   *
401   * @return  The connection handler that accepted this client
402   *          connection.
403   */
404  @org.opends.server.types.PublicAPI(
405       stability=org.opends.server.types.StabilityLevel.PRIVATE,
406       mayInstantiate=false,
407       mayExtend=false,
408       mayInvoke=false)
409  @Override
410  public ConnectionHandler<?> getConnectionHandler()
411  {
412    return InternalConnectionHandler.getInstance();
413  }
414
415
416
417  /**
418   * Retrieves the protocol that the client is using to communicate
419   * with the Directory Server.
420   *
421   * @return  The protocol that the client is using to communicate
422   *          with the Directory Server.
423   */
424  @Override
425  public String getProtocol()
426  {
427    return "internal";
428  }
429
430
431
432  /**
433   * Retrieves a string representation of the address of the client.
434   *
435   * @return  A string representation of the address of the client.
436   */
437  @Override
438  public String getClientAddress()
439  {
440    return "internal";
441  }
442
443
444
445  /**
446   * Retrieves the port number for this connection on the client
447   * system.
448   *
449   * @return The port number for this connection on the client system.
450   */
451  @Override
452  public int getClientPort()
453  {
454    return -1;
455  }
456
457
458
459  /**
460   * Retrieves a string representation of the address on the server to
461   * which the client connected.
462   *
463   * @return  A string representation of the address on the server to
464   *          which the client connected.
465   */
466  @Override
467  public String getServerAddress()
468  {
469    return "internal";
470  }
471
472
473
474  /**
475   * Retrieves the port number for this connection on the server
476   * system if available.
477   *
478   * @return The port number for this connection on the server system
479   *         or -1 if there is no server port associated with this
480   *         connection (e.g. internal client).
481   */
482  @Override
483  public int getServerPort()
484  {
485    return -1;
486  }
487
488
489
490  /**
491   * Retrieves the <CODE>java.net.InetAddress</CODE> associated with
492   * the remote client system.
493   *
494   * @return  The <CODE>java.net.InetAddress</CODE> associated with
495   *          the remote client system.  It may be <CODE>null</CODE>
496   *          if the client is not connected over an IP-based
497   *          connection.
498   */
499  @Override
500  public InetAddress getRemoteAddress()
501  {
502    return null;
503  }
504
505
506
507  /**
508   * Retrieves the <CODE>java.net.InetAddress</CODE> for the Directory
509   * Server system to which the client has established the connection.
510   *
511   * @return  The <CODE>java.net.InetAddress</CODE> for the Directory
512   *          Server system to which the client has established the
513   *          connection.  It may be <CODE>null</CODE> if the client
514   *          is not connected over an IP-based connection.
515   */
516  @Override
517  public InetAddress getLocalAddress()
518  {
519    return null;
520  }
521
522
523
524  /**
525   * Specifies the size limit that will be enforced for searches
526   * performed using this client connection.  This method does nothing
527   * because connection-level size limits will never be enforced for
528   * internal client connections.
529   *
530   * @param  sizeLimit  The size limit that will be enforced for
531   *                    searches performed using this client
532   *                    connection.
533   */
534  @Override
535  public void setSizeLimit(int sizeLimit)
536  {
537    // No implementation required.  We never want to set a nonzero
538    // size limit for internal client connections.
539  }
540
541
542
543  /**
544   * Specifies the default maximum number of entries that should
545   * be checked for matches during a search.  This method does nothing
546   * because connection-level lookthrough limits will never be
547   * enforced for internal client connections
548   *
549   * @param  lookthroughLimit  The default maximum number of
550   *                           entries that should be check for
551   *                           matches during a search.
552   */
553  @Override
554  public void setLookthroughLimit(int lookthroughLimit)
555  {
556    // No implementation required.  We never want to set a nonzero
557    // lookthrough limit for internal client connections.
558  }
559
560
561
562  /**
563   * Specifies the maximum length of time in milliseconds that this
564   * client connection will be allowed to remain idle before it should
565   * be disconnected.  This method does nothing because internal
566   * client connections will not be terminated due to an idle time
567   * limit.
568   *
569   * @param  idleTimeLimit  The maximum length of time in milliseconds
570   *                        that this client connection will be
571   *                        allowed to remain idle before it should be
572   *                        disconnected.
573   */
574  @Override
575  public void setIdleTimeLimit(long idleTimeLimit)
576  {
577    // No implementation required.  We never want to set a nonzero
578    // idle time limit for internal client connections.
579  }
580
581
582
583  /**
584   * Specifies the time limit that will be enforced for searches
585   * performed using this client connection.  This method does nothing
586   * because connection-level time limits will never be enforced for
587   * internal client connections.
588   *
589   * @param  timeLimit  The time limit that will be enforced for
590   *                    searches performed using this client
591   *                    connection.
592   */
593  @Override
594  public void setTimeLimit(int timeLimit)
595  {
596    // No implementation required.  We never want to set a nonzero
597    // time limit for internal client connections.
598  }
599
600  /** {@inheritDoc} */
601  @Override
602  public boolean isConnectionValid()
603  {
604    // This connection is always valid
605    return true;
606  }
607
608  /**
609   * Indicates whether this client connection is currently using a
610   * secure mechanism to communicate with the server.  Note that this
611   * may change over time based on operations performed by the client
612   * or server (e.g., it may go from <CODE>false</CODE> to
613   * <CODE>true</CODE> if the client uses the StartTLS extended
614   * operation).
615   *
616   * @return  <CODE>true</CODE> if the client connection is currently
617   *          using a secure mechanism to communicate with the server,
618   *          or <CODE>false</CODE> if not.
619   */
620  @Override
621  public boolean isSecure()
622  {
623      return true;
624  }
625
626
627
628  /**
629   * Sends a response to the client based on the information in the
630   * provided operation.
631   *
632   * @param  operation  The operation for which to send the response.
633   */
634  @org.opends.server.types.PublicAPI(
635       stability=org.opends.server.types.StabilityLevel.PRIVATE,
636       mayInstantiate=false,
637       mayExtend=false,
638       mayInvoke=false)
639  @Override
640  public void sendResponse(Operation operation)
641  {
642    // There will not be any response sent by this method, since there
643    // is not an actual connection.
644  }
645
646
647
648  /**
649   * This method has no effect, as the authentication info for
650   * internal client connections is set when the connection is created
651   * and cannot be changed after the fact.
652   *
653   * @param  authenticationInfo  Information about the authentication
654   *                             that has been performed for this
655   *                             connection.  It should not be
656   *                             <CODE>null</CODE>.
657   */
658  @org.opends.server.types.PublicAPI(
659       stability=org.opends.server.types.StabilityLevel.PRIVATE,
660       mayInstantiate=false,
661       mayExtend=false,
662       mayInvoke=false)
663  @Override
664  public void setAuthenticationInfo(AuthenticationInfo
665                                         authenticationInfo)
666  {
667    // No implementation required.
668  }
669
670
671
672  /**
673   * This method has no effect, as the authentication info for
674   * internal client connections is set when the connection is created
675   * and cannot be changed after the fact.
676   */
677  @org.opends.server.types.PublicAPI(
678       stability=org.opends.server.types.StabilityLevel.PRIVATE,
679       mayInstantiate=false,
680       mayExtend=false,
681       mayInvoke=false)
682  @Override
683  public void setUnauthenticated()
684  {
685    // No implementation required.
686  }
687
688
689
690  /**
691   * Processes an internal add operation with the provided
692   * information.
693   *
694   * @param  rawEntryDN     The DN to use for the entry to add.
695   * @param  rawAttributes  The set of attributes to include in the
696   *                        entry to add.
697   *
698   * @return  A reference to the add operation that was processed and
699   *          contains information about the result of the processing.
700   */
701  public AddOperation processAdd(String rawEntryDN,
702                                 List<RawAttribute> rawAttributes)
703  {
704    return processAdd(ByteString.valueOfUtf8(rawEntryDN), rawAttributes, null);
705  }
706
707
708
709  /**
710   * Processes an internal add operation with the provided
711   * information.
712   *
713   * @param  rawEntryDN     The DN to use for the entry to add.
714   * @param  rawAttributes  The set of attributes to include in the
715   *                        entry to add.
716   *
717   * @return  A reference to the add operation that was processed and
718   *          contains information about the result of the processing.
719   */
720  public AddOperation processAdd(ByteString rawEntryDN,
721                                 List<RawAttribute> rawAttributes)
722  {
723    return processAdd(rawEntryDN, rawAttributes, null);
724  }
725
726
727
728  /**
729   * Processes an internal add operation with the provided
730   * information.
731   *
732   * @param  rawEntryDN     The DN to use for the entry to add.
733   * @param  rawAttributes  The set of attributes to include in the
734   *                        entry to add.
735   * @param  controls       The set of controls to include in the
736   *                        request.
737   *
738   * @return  A reference to the add operation that was processed and
739   *          contains information about the result of the processing.
740   */
741  public AddOperation processAdd(ByteString rawEntryDN,
742                                 List<RawAttribute> rawAttributes,
743                                 List<Control> controls)
744  {
745    AddOperationBasis addOperation =
746         new AddOperationBasis(this, nextOperationID(),
747                          nextMessageID(), controls, rawEntryDN,
748                          rawAttributes);
749    addOperation.setInternalOperation(true);
750
751    addOperation.run();
752    return addOperation;
753  }
754
755
756
757  /**
758   * Processes an internal add operation with the provided
759   * information.
760   *
761   * @param  entryDN                The entry DN for the add
762   *                                operation.
763   * @param  objectClasses          The set of object classes for the
764   *                                add operation.
765   * @param  userAttributes         The set of user attributes for the
766   *                                add operation.
767   * @param  operationalAttributes  The set of operational attributes
768   *                                for the add operation.
769   *
770   * @return  A reference to the add operation that was processed and
771   *          contains information about the result of the processing.
772   */
773  public AddOperation processAdd(DN entryDN,
774                           Map<ObjectClass,String> objectClasses,
775                           Map<AttributeType,List<Attribute>>
776                                userAttributes,
777                           Map<AttributeType,List<Attribute>>
778                                operationalAttributes)
779  {
780    return processAdd(entryDN, objectClasses, userAttributes,
781                      operationalAttributes, null);
782  }
783
784
785
786  /**
787   * Processes an internal add operation with the provided
788   * information.
789   *
790   * @param  entryDN                The entry DN for the add
791   *                                operation.
792   * @param  objectClasses          The set of object classes for the
793   *                                add operation.
794   * @param  userAttributes         The set of user attributes for the
795   *                                add operation.
796   * @param  operationalAttributes  The set of operational attributes
797   *                                for the add operation.
798   * @param  controls               The set of controls to include in
799   *                                the request.
800   *
801   * @return  A reference to the add operation that was processed and
802   *          contains information about the result of the processing.
803   */
804  public AddOperation processAdd(DN entryDN,
805                           Map<ObjectClass,String> objectClasses,
806                           Map<AttributeType,List<Attribute>>
807                                userAttributes,
808                           Map<AttributeType,List<Attribute>>
809                                operationalAttributes,
810                           List<Control> controls)
811  {
812    AddOperationBasis addOperation =
813         new AddOperationBasis(this, nextOperationID(),
814                          nextMessageID(), controls, entryDN,
815                          objectClasses, userAttributes,
816                          operationalAttributes);
817    addOperation.setInternalOperation(true);
818
819    addOperation.run();
820    return addOperation;
821  }
822
823
824
825  /**
826   * Processes an internal add operation with the provided
827   * information.
828   *
829   * @param  entry  The entry to be added.
830   *
831   * @return  A reference to the add operation that was processed and
832   *          contains information about the result of the processing.
833   */
834  public AddOperation processAdd(Entry entry)
835  {
836    return processAdd(entry, null);
837  }
838
839
840
841  /**
842   * Processes an internal add operation with the provided
843   * information.
844   *
845   * @param  entry     The entry to be added.
846   * @param  controls  The set of controls to include in the request.
847   *
848   * @return  A reference to the add operation that was processed and
849   *          contains information about the result of the processing.
850   */
851  public AddOperation processAdd(Entry entry, List<Control> controls)
852  {
853    return processAdd(entry.getName(), entry.getObjectClasses(),
854                      entry.getUserAttributes(),
855                      entry.getOperationalAttributes(),
856                      controls);
857  }
858
859
860
861  /**
862   * Processes an internal add operation based on the provided add
863   * change record entry.
864   *
865   * @param  addRecord  The add change record entry to be processed.
866   *
867   * @return  A reference to the add operation that was processed and
868   *          contains information about the result of the processing.
869   */
870  public AddOperation processAdd(AddChangeRecordEntry addRecord)
871  {
872    LinkedHashMap<ObjectClass,String> objectClasses = new LinkedHashMap<>();
873    LinkedHashMap<AttributeType,List<Attribute>> userAttrs = new LinkedHashMap<>();
874    LinkedHashMap<AttributeType,List<Attribute>> opAttrs = new LinkedHashMap<>();
875
876    Entry e = new Entry(addRecord.getDN(), objectClasses, userAttrs, opAttrs);
877
878    ArrayList<ByteString> duplicateValues = new ArrayList<>();
879    for (Attribute a : addRecord.getAttributes())
880    {
881      if (a.getAttributeDescription().getAttributeType().isObjectClass())
882      {
883        for (ByteString v : a)
884        {
885          String ocName = v.toString();
886          String lowerName = toLowerCase(ocName);
887          ObjectClass oc = DirectoryServer.getObjectClass(lowerName, true);
888          objectClasses.put(oc, ocName);
889        }
890      }
891      else
892      {
893        e.addAttribute(a, duplicateValues);
894      }
895    }
896
897    return processAdd(addRecord.getDN(), objectClasses, userAttrs, opAttrs);
898  }
899
900
901
902  /**
903   * Processes an internal bind operation with the provided
904   * information.  Note that regardless of whether the bind is
905   * successful, the authentication state for this internal connection
906   * will not be altered in any way.
907   *
908   * @param  rawBindDN  The bind DN for the operation.
909   * @param  password   The bind password for the operation.
910   *
911   * @return  A reference to the bind operation that was processed and
912   *          contains information about the result of the processing.
913   */
914  public BindOperation processSimpleBind(String rawBindDN,
915                                         String password)
916  {
917    return processSimpleBind(ByteString.valueOfUtf8(rawBindDN),
918        ByteString.valueOfUtf8(password), null);
919  }
920
921
922
923  /**
924   * Processes an internal bind operation with the provided
925   * information.  Note that regardless of whether the bind is
926   * successful, the authentication state for this internal connection
927   * will not be altered in any way.
928   *
929   * @param  rawBindDN  The bind DN for the operation.
930   * @param  password   The bind password for the operation.
931   * @param  controls   The set of controls to include in the
932   *                    request.
933   *
934   * @return  A reference to the bind operation that was processed and
935   *          contains information about the result of the processing.
936   */
937  public BindOperation processSimpleBind(String rawBindDN,
938                                         String password,
939                                         List<Control> controls)
940  {
941    return processSimpleBind(ByteString.valueOfUtf8(rawBindDN),
942        ByteString.valueOfUtf8(password), controls);
943  }
944
945
946
947  /**
948   * Processes an internal bind operation with the provided
949   * information.  Note that regardless of whether the bind is
950   * successful, the authentication state for this internal connection
951   * will not be altered in any way.
952   *
953   * @param  rawBindDN  The bind DN for the operation.
954   * @param  password   The bind password for the operation.
955   *
956   * @return  A reference to the bind operation that was processed and
957   *          contains information about the result of the processing.
958   */
959  public BindOperation processSimpleBind(ByteString rawBindDN,
960                                         ByteString password)
961  {
962    return processSimpleBind(rawBindDN, password, null);
963  }
964
965
966
967  /**
968   * Processes an internal bind operation with the provided
969   * information.  Note that regardless of whether the bind is
970   * successful, the authentication state for this internal connection
971   * will not be altered in any way.
972   *
973   * @param  rawBindDN  The bind DN for the operation.
974   * @param  password   The bind password for the operation.
975   * @param  controls   The set of controls to include in the request.
976   *
977   * @return  A reference to the bind operation that was processed and
978   *          contains information about the result of the processing.
979   */
980  public BindOperation processSimpleBind(ByteString rawBindDN,
981                                         ByteString password,
982                                         List<Control> controls)
983  {
984    BindOperationBasis bindOperation =
985         new BindOperationBasis(this, nextOperationID(),
986                           nextMessageID(), controls,
987                           PROTOCOL_VERSION, rawBindDN, password);
988    bindOperation.setInternalOperation(true);
989
990    bindOperation.run();
991    return bindOperation;
992  }
993
994
995
996  /**
997   * Processes an internal bind operation with the provided
998   * information.  Note that regardless of whether the bind is
999   * successful, the authentication state for this internal connection
1000   * will not be altered in any way.
1001   *
1002   * @param  bindDN    The bind DN for the operation.
1003   * @param  password  The bind password for the operation.
1004   *
1005   * @return  A reference to the bind operation that was processed and
1006   *          contains information about the result of the processing.
1007   */
1008  public BindOperation processSimpleBind(DN bindDN,
1009                                         ByteString password)
1010  {
1011    return processSimpleBind(bindDN, password, null);
1012  }
1013
1014
1015
1016  /**
1017   * Processes an internal bind operation with the provided
1018   * information.  Note that regardless of whether the bind is
1019   * successful, the authentication state for this internal connection
1020   * will not be altered in any way.
1021   *
1022   * @param  bindDN    The bind DN for the operation.
1023   * @param  password  The bind password for the operation.
1024   * @param  controls  The set of controls to include in the request.
1025   *
1026   * @return  A reference to the bind operation that was processed and
1027   *          contains information about the result of the processing.
1028   */
1029  public BindOperation processSimpleBind(DN bindDN,
1030                                         ByteString password,
1031                                         List<Control> controls)
1032  {
1033    BindOperationBasis bindOperation =
1034         new BindOperationBasis(this, nextOperationID(),
1035                           nextMessageID(), controls,
1036                           PROTOCOL_VERSION, bindDN, password);
1037    bindOperation.setInternalOperation(true);
1038
1039    bindOperation.run();
1040    return bindOperation;
1041  }
1042
1043
1044
1045  /**
1046   * Processes an internal bind operation with the provided
1047   * information.  Note that regardless of whether the bind is
1048   * successful, the authentication state for this internal connection
1049   * will not be altered in any way.
1050   *
1051   * @param  rawBindDN        The bind DN for the operation.
1052   * @param  saslMechanism    The SASL mechanism for the operation.
1053   * @param  saslCredentials  The SASL credentials for the operation.
1054   *
1055   * @return  A reference to the bind operation that was processed and
1056   *          contains information about the result of the processing.
1057   */
1058  public BindOperation processSASLBind(ByteString rawBindDN,
1059                            String saslMechanism,
1060                            ByteString saslCredentials)
1061  {
1062    return processSASLBind(rawBindDN, saslMechanism, saslCredentials,
1063                           null);
1064  }
1065
1066
1067
1068  /**
1069   * Processes an internal bind operation with the provided
1070   * information.  Note that regardless of whether the bind is
1071   * successful, the authentication state for this internal connection
1072   * will not be altered in any way.
1073   *
1074   * @param  rawBindDN        The bind DN for the operation.
1075   * @param  saslMechanism    The SASL mechanism for the operation.
1076   * @param  saslCredentials  The SASL credentials for the operation.
1077   * @param  controls         The set of controls to include in the
1078   *                          request.
1079   *
1080   * @return  A reference to the bind operation that was processed and
1081   *          contains information about the result of the processing.
1082   */
1083  public BindOperation processSASLBind(ByteString rawBindDN,
1084                            String saslMechanism,
1085                            ByteString saslCredentials,
1086                            List<Control> controls)
1087  {
1088    BindOperationBasis bindOperation =
1089         new BindOperationBasis(this, nextOperationID(),
1090                           nextMessageID(), controls,
1091                           PROTOCOL_VERSION, rawBindDN, saslMechanism,
1092                           saslCredentials);
1093    bindOperation.setInternalOperation(true);
1094
1095    bindOperation.run();
1096    return bindOperation;
1097  }
1098
1099
1100
1101  /**
1102   * Processes an internal bind operation with the provided
1103   * information.  Note that regardless of whether the bind is
1104   * successful, the authentication state for this internal connection
1105   * will not be altered in any way.
1106   *
1107   * @param  bindDN           The bind DN for the operation.
1108   * @param  saslMechanism    The SASL mechanism for the operation.
1109   * @param  saslCredentials  The SASL credentials for the operation.
1110   *
1111   * @return  A reference to the bind operation that was processed and
1112   *          contains information about the result of the processing.
1113   */
1114  public BindOperation processSASLBind(DN bindDN,
1115                            String saslMechanism,
1116                            ByteString saslCredentials)
1117  {
1118    return processSASLBind(bindDN, saslMechanism, saslCredentials,
1119                           null);
1120  }
1121
1122
1123
1124  /**
1125   * Processes an internal bind operation with the provided
1126   * information.  Note that regardless of whether the bind is
1127   * successful, the authentication state for this internal connection
1128   * will not be altered in any way.
1129   *
1130   * @param  bindDN           The bind DN for the operation.
1131   * @param  saslMechanism    The SASL mechanism for the operation.
1132   * @param  saslCredentials  The SASL credentials for the operation.
1133   * @param  controls         The set of controls to include in the
1134   *                          request.
1135   *
1136   * @return  A reference to the bind operation that was processed and
1137   *          contains information about the result of the processing.
1138   */
1139  public BindOperation processSASLBind(DN bindDN,
1140                            String saslMechanism,
1141                            ByteString saslCredentials,
1142                            List<Control> controls)
1143  {
1144    BindOperationBasis bindOperation =
1145         new BindOperationBasis(this, nextOperationID(),
1146                           nextMessageID(), controls,
1147                           PROTOCOL_VERSION, bindDN, saslMechanism,
1148                           saslCredentials);
1149    bindOperation.setInternalOperation(true);
1150
1151    bindOperation.run();
1152    return bindOperation;
1153  }
1154
1155
1156
1157  /**
1158   * Processes an internal compare operation with the provided
1159   * information.
1160   *
1161   * @param  rawEntryDN      The entry DN for the compare operation.
1162   * @param  attributeType   The attribute type for the compare
1163   *                         operation.
1164   * @param  assertionValue  The assertion value for the compare
1165   *                         operation.
1166   *
1167   * @return  A reference to the compare operation that was processed
1168   *          and contains information about the result of the
1169   *          processing.
1170   */
1171  public CompareOperation processCompare(String rawEntryDN,
1172                                         String attributeType,
1173                                         String assertionValue)
1174  {
1175    return processCompare(ByteString.valueOfUtf8(rawEntryDN), attributeType,
1176        ByteString.valueOfUtf8(assertionValue), null);
1177  }
1178
1179  /**
1180   * Processes an internal compare operation with the provided
1181   * information.
1182   *
1183   * @param  rawEntryDN      The entry DN for the compare operation.
1184   * @param  attributeType   The attribute type for the compare
1185   *                         operation.
1186   * @param  assertionValue  The assertion value for the compare
1187   *                         operation.
1188   * @param  controls        The set of controls to include in the
1189   *                         request.
1190   *
1191   * @return  A reference to the compare operation that was processed
1192   *          and contains information about the result of the
1193   *          processing.
1194   */
1195  public CompareOperation processCompare(ByteString rawEntryDN,
1196                                         String attributeType,
1197                                         ByteString assertionValue,
1198                                         List<Control> controls)
1199  {
1200    CompareOperationBasis compareOperation =
1201         new CompareOperationBasis(this, nextOperationID(),
1202                              nextMessageID(), controls, rawEntryDN,
1203                              attributeType, assertionValue);
1204    compareOperation.setInternalOperation(true);
1205
1206    compareOperation.run();
1207    return compareOperation;
1208  }
1209
1210  /**
1211   * Processes an internal compare operation with the provided information.
1212   *
1213   * @param entryDN
1214   *          The entry DN for the compare operation.
1215   * @param attributeDescription
1216   *          The attribute description for the compare operation.
1217   * @param assertionValue
1218   *          The assertion value for the compare operation.
1219   * @param controls
1220   *          The set of controls to include in the request.
1221   * @return A reference to the compare operation that was processed and contains information about
1222   *         the result of the processing.
1223   */
1224  public CompareOperation processCompare(DN entryDN,
1225                                         AttributeDescription attributeDescription,
1226                                         ByteString assertionValue,
1227                                         List<Control> controls)
1228  {
1229    CompareOperationBasis compareOperation =
1230         new CompareOperationBasis(this, nextOperationID(),
1231                              nextMessageID(), controls, entryDN,
1232                              attributeDescription, assertionValue);
1233    compareOperation.setInternalOperation(true);
1234
1235    compareOperation.run();
1236    return compareOperation;
1237  }
1238
1239
1240
1241  /**
1242   * Processes an internal delete operation with the provided
1243   * information.
1244   *
1245   * @param  rawEntryDN  The entry DN for the delete operation.
1246   *
1247   * @return  A reference to the delete operation that was processed
1248   *          and contains information about the result of the
1249   *          processing.
1250   */
1251  public DeleteOperation processDelete(String rawEntryDN)
1252  {
1253    return processDelete(ByteString.valueOfUtf8(rawEntryDN), null);
1254  }
1255
1256
1257
1258  /**
1259   * Processes an internal delete operation with the provided
1260   * information.
1261   *
1262   * @param  rawEntryDN  The entry DN for the delete operation.
1263   * @param  controls    The set of controls to include in the
1264   *                     request.
1265   *
1266   * @return  A reference to the delete operation that was processed
1267   *          and contains information about the result of the
1268   *          processing.
1269   */
1270  public DeleteOperation processDelete(String rawEntryDN,
1271                                       List<Control> controls)
1272  {
1273    return processDelete(ByteString.valueOfUtf8(rawEntryDN), controls);
1274  }
1275
1276
1277
1278  /**
1279   * Processes an internal delete operation with the provided
1280   * information.
1281   *
1282   * @param  rawEntryDN  The entry DN for the delete operation.
1283   *
1284   * @return  A reference to the delete operation that was processed
1285   *          and contains information about the result of the
1286   *          processing.
1287   */
1288  public DeleteOperation processDelete(ByteString rawEntryDN)
1289  {
1290    return processDelete(rawEntryDN, null);
1291  }
1292
1293
1294
1295  /**
1296   * Processes an internal delete operation with the provided
1297   * information.
1298   *
1299   * @param  rawEntryDN  The entry DN for the delete operation.
1300   * @param  controls    The set of controls to include in the
1301   *                     request.
1302   *
1303   * @return  A reference to the delete operation that was processed
1304   *          and contains information about the result of the
1305   *          processing.
1306   */
1307  public DeleteOperation processDelete(ByteString rawEntryDN,
1308                                       List<Control> controls)
1309  {
1310    DeleteOperationBasis deleteOperation =
1311         new DeleteOperationBasis(this, nextOperationID(),
1312                             nextMessageID(), controls, rawEntryDN);
1313    deleteOperation.setInternalOperation(true);
1314
1315    deleteOperation.run();
1316    return deleteOperation;
1317  }
1318
1319
1320
1321  /**
1322   * Processes an internal delete operation with the provided
1323   * information.
1324   *
1325   * @param  entryDN  The entry DN for the delete operation.
1326   *
1327   * @return  A reference to the delete operation that was processed
1328   *          and contains information about the result of the
1329   *          processing.
1330   */
1331  public DeleteOperation processDelete(DN entryDN)
1332  {
1333    return processDelete(entryDN, null);
1334  }
1335
1336
1337
1338  /**
1339   * Processes an internal delete operation with the provided
1340   * information.
1341   *
1342   * @param  entryDN   The entry DN for the delete operation.
1343   * @param  controls  The set of controls to include in the request.
1344   *
1345   * @return  A reference to the delete operation that was processed
1346   *          and contains information about the result of the
1347   *          processing.
1348   */
1349  public DeleteOperation processDelete(DN entryDN,
1350                                       List<Control> controls)
1351  {
1352    DeleteOperationBasis deleteOperation =
1353         new DeleteOperationBasis(this, nextOperationID(),
1354                             nextMessageID(), controls, entryDN);
1355    deleteOperation.setInternalOperation(true);
1356
1357    deleteOperation.run();
1358    return deleteOperation;
1359  }
1360
1361
1362
1363  /**
1364   * Processes an internal delete operation with the provided
1365   * information.
1366   *
1367   * @param  deleteRecord  The delete change record entry to be
1368   *                       processed.
1369   *
1370   * @return  A reference to the delete operation that was processed
1371   *          and contains information about the result of the
1372   *          processing.
1373   */
1374  public DeleteOperation processDelete(
1375                              DeleteChangeRecordEntry deleteRecord)
1376  {
1377    return processDelete(deleteRecord.getDN());
1378  }
1379
1380
1381
1382  /**
1383   * Processes an internal extended operation with the provided
1384   * information.
1385   *
1386   * @param  requestOID    The OID for the extended request.
1387   * @param  requestValue  The encoded value for the extended
1388   *                       operation, or <CODE>null</CODE> if there is
1389   *                       no value.
1390   *
1391   * @return  A reference to the extended operation that was processed
1392   *          and contains information about the result of the
1393   *          processing.
1394   */
1395  public ExtendedOperation processExtendedOperation(
1396                                String requestOID,
1397                                ByteString requestValue)
1398  {
1399    return processExtendedOperation(requestOID, requestValue, null);
1400  }
1401
1402
1403
1404  /**
1405   * Processes an internal extended operation with the provided
1406   * information.
1407   *
1408   * @param  requestOID    The OID for the extended request.
1409   * @param  requestValue  The encoded value for the extended
1410   *                       operation, or <CODE>null</CODE> if there is
1411   *                       no value.
1412   * @param  controls      The set of controls to include in the
1413   *                       request.
1414   *
1415   * @return  A reference to the extended operation that was processed
1416   *          and contains information about the result of the
1417   *          processing.
1418   */
1419  public ExtendedOperation processExtendedOperation(
1420                                String requestOID,
1421                                ByteString requestValue,
1422                                List<Control> controls)
1423  {
1424    ExtendedOperationBasis extendedOperation =
1425         new ExtendedOperationBasis(this, nextOperationID(),
1426                               nextMessageID(), controls, requestOID,
1427                               requestValue);
1428    extendedOperation.setInternalOperation(true);
1429    extendedOperation.run();
1430    return extendedOperation;
1431  }
1432
1433  /**
1434   * Processes an internal modify operation with the provided
1435   * information.
1436   *
1437   * @param  rawEntryDN        The raw entry DN for this modify
1438   *                           operation.
1439   * @param  rawModifications  The set of modifications for this
1440   *                           modify operation.
1441   *
1442   * @return  A reference to the modify operation that was processed
1443   *          and contains information about the result of the
1444   *          processing.
1445   */
1446  public ModifyOperation processModify(ByteString rawEntryDN,
1447                              List<RawModification> rawModifications)
1448  {
1449    return processModify(rawEntryDN, rawModifications, null);
1450  }
1451
1452
1453
1454  private ModifyOperation processModify(ByteString rawEntryDN,
1455                              List<RawModification> rawModifications,
1456                              List<Control> controls)
1457  {
1458    ModifyOperationBasis modifyOperation =
1459         new ModifyOperationBasis(this, nextOperationID(),
1460                             nextMessageID(), controls, rawEntryDN,
1461                             rawModifications);
1462    modifyOperation.setInternalOperation(true);
1463    modifyOperation.run();
1464    return modifyOperation;
1465  }
1466
1467
1468
1469  /**
1470   * Processes an internal modify operation with the provided
1471   * information.
1472   *
1473   * @param  entryDN        The entry DN for this modify operation.
1474   * @param  modifications  The set of modifications for this modify
1475   *                        operation.
1476   *
1477   * @return  A reference to the modify operation that was processed
1478   *          and contains information about the result of the
1479   *          processing.
1480   */
1481  public ModifyOperation processModify(DN entryDN,
1482                              List<Modification> modifications)
1483  {
1484    return processModify(entryDN, modifications, null);
1485  }
1486
1487
1488
1489  /**
1490   * Processes an internal modify operation with the provided
1491   * information.
1492   *
1493   * @param  entryDN        The entry DN for this modify operation.
1494   * @param  modifications  The set of modifications for this modify
1495   *                        operation.
1496   * @param  controls       The set of controls to include in the
1497   *                        request.
1498   *
1499   * @return  A reference to the modify operation that was processed
1500   *          and contains information about the result of the
1501   *          processing.
1502   */
1503  public ModifyOperation processModify(DN entryDN,
1504                              List<Modification> modifications,
1505                              List<Control> controls)
1506  {
1507    ModifyOperationBasis modifyOperation =
1508         new ModifyOperationBasis(this, nextOperationID(),
1509                             nextMessageID(), controls, entryDN,
1510                             modifications);
1511    modifyOperation.setInternalOperation(true);
1512    modifyOperation.run();
1513    return modifyOperation;
1514  }
1515
1516
1517
1518  /**
1519   * Processes an internal modify operation with the provided
1520   * information.
1521   *
1522   * @param  modifyRecord  The modify change record entry with
1523   *                       information about the changes to perform.
1524   *
1525   * @return  A reference to the modify operation that was processed
1526   *          and contains information about the result of the
1527   *          processing.
1528   */
1529  public ModifyOperation processModify(ModifyChangeRecordEntry modifyRecord)
1530  {
1531    return processModify(ByteString.valueOfObject(modifyRecord.getDN()),
1532        modifyRecord.getModifications(), null);
1533  }
1534
1535  /**
1536   * Processes an internal modify operation with the provided information.
1537   *
1538   * @param modifyRequest
1539   *          The modify request with information about the changes to perform.
1540   * @return A reference to the modify operation that was processed and contains information about
1541   *         the result of the processing.
1542   */
1543  public ModifyOperation processModify(ModifyRequest modifyRequest)
1544  {
1545    return processModify(ByteString.valueOfObject(modifyRequest.getName()),
1546        toRawModifications(modifyRequest.getModifications()), to(modifyRequest.getControls()));
1547  }
1548
1549
1550  /**
1551   * Processes an internal modify DN operation with the provided
1552   * information.
1553   *
1554   * @param  rawEntryDN    The current DN of the entry to rename.
1555   * @param  rawNewRDN     The new RDN to use for the entry.
1556   * @param  deleteOldRDN  The flag indicating whether the old RDN
1557   *                       value is to be removed from the entry.
1558   *
1559   * @return  A reference to the modify DN operation that was
1560   *          processed and contains information about the result of
1561   *          the processing.
1562   */
1563  public ModifyDNOperation processModifyDN(String rawEntryDN,
1564                                           String rawNewRDN,
1565                                           boolean deleteOldRDN)
1566  {
1567    return processModifyDN(ByteString.valueOfUtf8(rawEntryDN),
1568        ByteString.valueOfUtf8(rawNewRDN),
1569                           deleteOldRDN, null, null);
1570  }
1571
1572
1573
1574  /**
1575   * Processes an internal modify DN operation with the provided
1576   * information.
1577   *
1578   * @param  rawEntryDN    The current DN of the entry to rename.
1579   * @param  rawNewRDN     The new RDN to use for the entry.
1580   * @param  deleteOldRDN  The flag indicating whether the old RDN
1581   *                       value is to be removed from the entry.
1582   * @param  controls      The set of controls to include in the
1583   *                       request.
1584   *
1585   * @return  A reference to the modify DN operation that was
1586   *          processed and contains information about the result of
1587   *          the processing.
1588   */
1589  public ModifyDNOperation processModifyDN(String rawEntryDN,
1590                                           String rawNewRDN,
1591                                           boolean deleteOldRDN,
1592                                           List<Control> controls)
1593  {
1594    return processModifyDN(ByteString.valueOfUtf8(rawEntryDN),
1595        ByteString.valueOfUtf8(rawNewRDN),
1596                           deleteOldRDN, null, controls);
1597  }
1598
1599
1600
1601  /**
1602   * Processes an internal modify DN operation with the provided
1603   * information.
1604   *
1605   * @param  rawEntryDN    The current DN of the entry to rename.
1606   * @param  rawNewRDN     The new RDN to use for the entry.
1607   * @param  deleteOldRDN  The flag indicating whether the old RDN
1608   *                       value is to be removed from the entry.
1609   *
1610   * @return  A reference to the modify DN operation that was
1611   *          processed and contains information about the result of
1612   *          the processing.
1613   */
1614  public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
1615                                           ByteString rawNewRDN,
1616                                           boolean deleteOldRDN)
1617  {
1618    return processModifyDN(rawEntryDN, rawNewRDN, deleteOldRDN, null,
1619                           null);
1620  }
1621
1622
1623
1624  /**
1625   * Processes an internal modify DN operation with the provided
1626   * information.
1627   *
1628   * @param  rawEntryDN      The current DN of the entry to rename.
1629   * @param  rawNewRDN       The new RDN to use for the entry.
1630   * @param  deleteOldRDN    The flag indicating whether the old RDN
1631   *                         value is to be removed from the entry.
1632   * @param  rawNewSuperior  The new superior for the modify DN
1633   *                         operation, or <CODE>null</CODE> if the
1634   *                         entry will remain below the same parent.
1635   *
1636   * @return  A reference to the modify DN operation that was
1637   *          processed and contains information about the result of
1638   *          the processing.
1639   */
1640  public ModifyDNOperation processModifyDN(String rawEntryDN,
1641                                           String rawNewRDN,
1642                                           boolean deleteOldRDN,
1643                                           String rawNewSuperior)
1644  {
1645    return processModifyDN(ByteString.valueOfUtf8(rawEntryDN),
1646        ByteString.valueOfUtf8(rawNewRDN), deleteOldRDN,
1647        ByteString.valueOfUtf8(rawNewSuperior), null);
1648  }
1649
1650
1651
1652  /**
1653   * Processes an internal modify DN operation with the provided
1654   * information.
1655   *
1656   * @param  rawEntryDN      The current DN of the entry to rename.
1657   * @param  rawNewRDN       The new RDN to use for the entry.
1658   * @param  deleteOldRDN    The flag indicating whether the old RDN
1659   *                         value is to be removed from the entry.
1660   * @param  rawNewSuperior  The new superior for the modify DN
1661   *                         operation, or <CODE>null</CODE> if the
1662   *                         entry will remain below the same parent.
1663   * @param  controls        The set of controls to include in the
1664   *                         request.
1665   *
1666   * @return  A reference to the modify DN operation that was
1667   *          processed and contains information about the result of
1668   *          the processing.
1669   */
1670  public ModifyDNOperation processModifyDN(String rawEntryDN,
1671                                           String rawNewRDN,
1672                                           boolean deleteOldRDN,
1673                                           String rawNewSuperior,
1674                                           List<Control> controls)
1675  {
1676    return processModifyDN(ByteString.valueOfUtf8(rawEntryDN),
1677        ByteString.valueOfUtf8(rawNewRDN), deleteOldRDN,
1678        ByteString.valueOfUtf8(rawNewSuperior), controls);
1679  }
1680
1681
1682
1683  /**
1684   * Processes an internal modify DN operation with the provided
1685   * information.
1686   *
1687   * @param  rawEntryDN      The current DN of the entry to rename.
1688   * @param  rawNewRDN       The new RDN to use for the entry.
1689   * @param  deleteOldRDN    The flag indicating whether the old RDN
1690   *                         value is to be removed from the entry.
1691   * @param  rawNewSuperior  The new superior for the modify DN
1692   *                         operation, or <CODE>null</CODE> if the
1693   *                         entry will remain below the same parent.
1694   *
1695   * @return  A reference to the modify DN operation that was
1696   *          processed and contains information about the result of
1697   *          the processing.
1698   */
1699  public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
1700                                           ByteString rawNewRDN,
1701                                           boolean deleteOldRDN,
1702                                           ByteString rawNewSuperior)
1703  {
1704    return processModifyDN(rawEntryDN, rawNewRDN, deleteOldRDN,
1705                           rawNewSuperior, null);
1706  }
1707
1708
1709
1710  /**
1711   * Processes an internal modify DN operation with the provided
1712   * information.
1713   *
1714   * @param  rawEntryDN      The current DN of the entry to rename.
1715   * @param  rawNewRDN       The new RDN to use for the entry.
1716   * @param  deleteOldRDN    The flag indicating whether the old RDN
1717   *                         value is to be removed from the entry.
1718   * @param  rawNewSuperior  The new superior for the modify DN
1719   *                         operation, or <CODE>null</CODE> if the
1720   *                         entry will remain below the same parent.
1721   * @param  controls        The set of controls to include in the
1722   *                         request.
1723   *
1724   * @return  A reference to the modify DN operation that was
1725   *          processed and contains information about the result of
1726   *          the processing.
1727   */
1728  public ModifyDNOperation processModifyDN(ByteString rawEntryDN,
1729                                           ByteString rawNewRDN,
1730                                           boolean deleteOldRDN,
1731                                           ByteString rawNewSuperior,
1732                                           List<Control> controls)
1733  {
1734    ModifyDNOperationBasis modifyDNOperation =
1735         new ModifyDNOperationBasis(this, nextOperationID(),
1736                               nextMessageID(), controls, rawEntryDN,
1737                               rawNewRDN, deleteOldRDN,
1738                               rawNewSuperior);
1739    modifyDNOperation.setInternalOperation(true);
1740
1741    modifyDNOperation.run();
1742    return modifyDNOperation;
1743  }
1744
1745
1746
1747  /**
1748   * Processes an internal modify DN operation with the provided
1749   * information.
1750   *
1751   * @param  entryDN       The current DN of the entry to rename.
1752   * @param  newRDN        The new RDN to use for the entry.
1753   * @param  deleteOldRDN  The flag indicating whether the old RDN
1754   *                       value is to be removed from the entry.
1755   *
1756   * @return  A reference to the modify DN operation that was
1757   *          processed and contains information about the result of
1758   *          the processing.
1759   */
1760  public ModifyDNOperation processModifyDN(DN entryDN,
1761                                           RDN newRDN,
1762                                           boolean deleteOldRDN)
1763  {
1764    return processModifyDN(entryDN, newRDN, deleteOldRDN, null, null);
1765  }
1766
1767
1768
1769  /**
1770   * Processes an internal modify DN operation with the provided
1771   * information.
1772   *
1773   * @param  entryDN       The current DN of the entry to rename.
1774   * @param  newRDN        The new RDN to use for the entry.
1775   * @param  deleteOldRDN  The flag indicating whether the old RDN
1776   *                       value is to be removed from the entry.
1777   * @param  newSuperior   The new superior for the modify DN
1778   *                       operation, or <CODE>null</CODE> if the
1779   *                       entry will remain below the same parent.
1780   *
1781   * @return  A reference to the modify DN operation that was
1782   *          processed and contains information about the result of
1783   *          the processing.
1784   */
1785  public ModifyDNOperation processModifyDN(DN entryDN,
1786                                           RDN newRDN,
1787                                           boolean deleteOldRDN,
1788                                           DN newSuperior)
1789  {
1790    return processModifyDN(entryDN, newRDN, deleteOldRDN, newSuperior,
1791                           null);
1792  }
1793
1794
1795
1796  /**
1797   * Processes an internal modify DN operation with the provided
1798   * information.
1799   *
1800   * @param  entryDN       The current DN of the entry to rename.
1801   * @param  newRDN        The new RDN to use for the entry.
1802   * @param  deleteOldRDN  The flag indicating whether the old RDN
1803   *                       value is to be removed from the entry.
1804   * @param  newSuperior   The new superior for the modify DN
1805   *                       operation, or <CODE>null</CODE> if the
1806   *                       entry will remain below the same parent.
1807   * @param  controls      The set of controls to include in the
1808   *                       request.
1809   *
1810   * @return  A reference to the modify DN operation that was
1811   *          processed and contains information about the result of
1812   *          the processing.
1813   */
1814  public ModifyDNOperation processModifyDN(DN entryDN,
1815                                           RDN newRDN,
1816                                           boolean deleteOldRDN,
1817                                           DN newSuperior,
1818                                           List<Control> controls)
1819  {
1820    ModifyDNOperationBasis modifyDNOperation =
1821         new ModifyDNOperationBasis(this, nextOperationID(),
1822                               nextMessageID(), controls, entryDN,
1823                               newRDN, deleteOldRDN, newSuperior);
1824    modifyDNOperation.setInternalOperation(true);
1825
1826    modifyDNOperation.run();
1827    return modifyDNOperation;
1828  }
1829
1830  /**
1831   * Processes an internal modify DN operation with the provided
1832   * information.
1833   *
1834   * @param  modifyDNRecord  The modify DN change record entry with
1835   *                         information about the processing to
1836   *                         perform.
1837   *
1838   * @return  A reference to the modify DN operation that was
1839   *          processed and contains information about the result of
1840   *          the processing.
1841   */
1842  public ModifyDNOperation processModifyDN(
1843              ModifyDNChangeRecordEntry modifyDNRecord)
1844  {
1845    return processModifyDN(modifyDNRecord.getDN(),
1846                           modifyDNRecord.getNewRDN(),
1847                           modifyDNRecord.deleteOldRDN(),
1848                           modifyDNRecord.getNewSuperiorDN());
1849  }
1850
1851  /**
1852   * Processes an internal modify DN operation with the provided information.
1853   *
1854   * @param modifyDNRequest
1855   *          The modify DN request with information about the processing to perform.
1856   * @return A reference to the modify DN operation that was processed and contains information about
1857   *         the result of the processing.
1858   */
1859  public ModifyDNOperation processModifyDN(ModifyDNRequest modifyDNRequest)
1860  {
1861    return processModifyDN(modifyDNRequest.getName(),
1862                           modifyDNRequest.getNewRDN(),
1863                           modifyDNRequest.isDeleteOldRDN(),
1864                           modifyDNRequest.getNewSuperior());
1865  }
1866
1867  /**
1868   * Processes an internal search operation with the provided
1869   * information.
1870   *
1871   * @param  request         The search request.
1872   * @return  A reference to the internal search operation that was
1873   *          processed and contains information about the result of
1874   *          the processing.
1875   */
1876  public InternalSearchOperation processSearch(final SearchRequest request)
1877  {
1878    return processSearch(request, null);
1879  }
1880
1881
1882
1883  /**
1884   * Processes an internal search operation with the provided
1885   * information.
1886   *
1887   * @param  request         The search request.
1888   * @param  searchListener  The internal search listener that should
1889   *                         be used to handle the matching entries
1890   *                         and references.
1891   * @return  A reference to the internal search operation that was
1892   *          processed and contains information about the result of
1893   *          the processing.
1894   */
1895  public InternalSearchOperation processSearch(final SearchRequest request, InternalSearchListener searchListener)
1896  {
1897    // FIXME uncomment this after we move to the SDK:
1898    // if (Filter.objectClassPresent().equals(filter)) {
1899    // filter = Filter.alwaysTrue();
1900    // }
1901    InternalSearchOperation searchOperation =
1902        new InternalSearchOperation(this, nextOperationID(), nextMessageID(), request, searchListener);
1903    searchOperation.run();
1904    return searchOperation;
1905  }
1906
1907
1908
1909  /**
1910   * Sends the provided search result entry to the client.
1911   *
1912   * @param  searchOperation  The search operation with which the
1913   *                          entry is associated.
1914   * @param  searchEntry      The search result entry to be sent to
1915   *                          the client.
1916   *
1917   * @throws  DirectoryException  If a problem occurs while processing
1918   *                              the entry and the search should be
1919   *                              terminated.
1920   */
1921  @org.opends.server.types.PublicAPI(
1922       stability=org.opends.server.types.StabilityLevel.PRIVATE,
1923       mayInstantiate=false,
1924       mayExtend=false,
1925       mayInvoke=false)
1926  @Override
1927  public void sendSearchEntry(SearchOperation searchOperation,
1928                              SearchResultEntry searchEntry)
1929         throws DirectoryException
1930  {
1931    ((InternalSearchOperation) searchOperation).
1932         addSearchEntry(searchEntry);
1933  }
1934
1935
1936
1937  /**
1938   * Sends the provided search result reference to the client.
1939   *
1940   * @param  searchOperation  The search operation with which the
1941   *                          reference is associated.
1942   * @param  searchReference  The search result reference to be sent
1943   *                          to the client.
1944   *
1945   * @return  <CODE>true</CODE> if the client is able to accept
1946   *          referrals, or <CODE>false</CODE> if the client cannot
1947   *          handle referrals and no more attempts should be made to
1948   *          send them for the associated search operation.
1949   *
1950   * @throws  DirectoryException  If a problem occurs while processing
1951   *                              the entry and the search should be
1952   *                              terminated.
1953   */
1954  @org.opends.server.types.PublicAPI(
1955       stability=org.opends.server.types.StabilityLevel.PRIVATE,
1956       mayInstantiate=false,
1957       mayExtend=false,
1958       mayInvoke=false)
1959  @Override
1960  public boolean sendSearchReference(SearchOperation searchOperation,
1961                      SearchResultReference searchReference)
1962         throws DirectoryException
1963  {
1964    ((InternalSearchOperation)
1965     searchOperation).addSearchReference(searchReference);
1966    return true;
1967  }
1968
1969
1970
1971
1972  /**
1973   * Sends the provided intermediate response message to the client.
1974   *
1975   * @param  intermediateResponse  The intermediate response message
1976   *                               to be sent.
1977   *
1978   * @return  <CODE>true</CODE> if processing on the associated
1979   *          operation should continue, or <CODE>false</CODE> if not.
1980   */
1981  @org.opends.server.types.PublicAPI(
1982       stability=org.opends.server.types.StabilityLevel.PRIVATE,
1983       mayInstantiate=false,
1984       mayExtend=false,
1985       mayInvoke=false)
1986  @Override
1987  protected boolean sendIntermediateResponseMessage(
1988                         IntermediateResponse intermediateResponse)
1989  {
1990    // FIXME -- Do we need to support internal intermediate responses?
1991    //          If so, then implement this.
1992    return false;
1993  }
1994
1995
1996
1997
1998  /**
1999   * Closes the connection to the client, optionally sending it a
2000   * message indicating the reason for the closure.  Note that the
2001   * ability to send a notice of disconnection may not be available
2002   * for all protocols or under all circumstances.
2003   *
2004   * @param  disconnectReason  The disconnect reason that provides the
2005   *                           generic cause for the disconnect.
2006   * @param  sendNotification  Indicates whether to try to provide
2007   *                           notification to the client that the
2008   *                           connection will be closed.
2009   * @param  message           The message to send to the client.  It
2010   *                           may be <CODE>null</CODE> if no
2011   *                           notification is to be sent.
2012   */
2013  @org.opends.server.types.PublicAPI(
2014       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2015       mayInstantiate=false,
2016       mayExtend=false,
2017       mayInvoke=false)
2018  @Override
2019  public void disconnect(DisconnectReason disconnectReason,
2020                         boolean sendNotification,
2021                         LocalizableMessage message)
2022  {
2023    // No implementation is required since there is nothing to
2024    // disconnect.  Further, since there is no real disconnect, we can
2025    // wait to have the garbage collector call
2026    // finalizeConnectionInternal whenever this internal connection is
2027    // garbage collected.
2028  }
2029
2030
2031
2032  /**
2033   * Retrieves the set of operations in progress for this client
2034   * connection.  This list must not be altered by any caller.
2035   *
2036   * @return  The set of operations in progress for this client
2037   *          connection.
2038   */
2039  @org.opends.server.types.PublicAPI(
2040       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2041       mayInstantiate=false,
2042       mayExtend=false,
2043       mayInvoke=false)
2044  @Override
2045  public Collection<Operation> getOperationsInProgress()
2046  {
2047    return Collections.emptyList();
2048  }
2049
2050
2051
2052  /**
2053   * Retrieves the operation in progress with the specified message
2054   * ID.
2055   *
2056   * @param  messageID  The message ID of the operation to retrieve.
2057   *
2058   * @return  The operation in progress with the specified message ID,
2059   *          or <CODE>null</CODE> if no such operation could be
2060   *          found.
2061   */
2062  @org.opends.server.types.PublicAPI(
2063       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2064       mayInstantiate=false,
2065       mayExtend=false,
2066       mayInvoke=false)
2067  @Override
2068  public Operation getOperationInProgress(int messageID)
2069  {
2070    // Internal operations will not be tracked.
2071    return null;
2072  }
2073
2074
2075
2076  /**
2077   * Removes the provided operation from the set of operations in
2078   * progress for this client connection.  Note that this does not
2079   * make any attempt to cancel any processing that may already be in
2080   * progress for the operation.
2081   *
2082   * @param  messageID  The message ID of the operation to remove from
2083   *                    the set of operations in progress.
2084   *
2085   * @return  <CODE>true</CODE> if the operation was found and removed
2086   *          from the set of operations in progress, or
2087   *          <CODE>false</CODE> if not.
2088   */
2089  @org.opends.server.types.PublicAPI(
2090       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2091       mayInstantiate=false,
2092       mayExtend=false,
2093       mayInvoke=false)
2094  @Override
2095  public boolean removeOperationInProgress(int messageID)
2096  {
2097    // No implementation is required, since internal operations will
2098    // not be tracked.
2099    return false;
2100  }
2101
2102
2103
2104  /**
2105   * Attempts to cancel the specified operation.
2106   *
2107   * @param  messageID      The message ID of the operation to cancel.
2108   * @param  cancelRequest  An object providing additional information
2109   *                        about how the cancel should be processed.
2110   *
2111   * @return  A cancel result that either indicates that the cancel
2112   *          was successful or provides a reason that it was not.
2113   */
2114  @org.opends.server.types.PublicAPI(
2115       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2116       mayInstantiate=false,
2117       mayExtend=false,
2118       mayInvoke=false)
2119  @Override
2120  public CancelResult cancelOperation(int messageID,
2121                                      CancelRequest cancelRequest)
2122  {
2123    // Internal operations cannot be cancelled.
2124    // TODO: i18n
2125    return new CancelResult(ResultCode.CANNOT_CANCEL,
2126        LocalizableMessage.raw("Internal operations cannot be cancelled"));
2127  }
2128
2129
2130
2131  /**
2132   * Attempts to cancel all operations in progress on this connection.
2133   *
2134   * @param  cancelRequest  An object providing additional information
2135   *                        about how the cancel should be processed.
2136   */
2137  @org.opends.server.types.PublicAPI(
2138       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2139       mayInstantiate=false,
2140       mayExtend=false,
2141       mayInvoke=false)
2142  @Override
2143  public void cancelAllOperations(CancelRequest cancelRequest)
2144  {
2145    // No implementation is required since internal operations cannot
2146    // be cancelled.
2147  }
2148
2149
2150
2151  /**
2152   * Attempts to cancel all operations in progress on this connection
2153   * except the operation with the specified message ID.
2154   *
2155   * @param  cancelRequest  An object providing additional information
2156   *                        about how the cancel should be processed.
2157   * @param  messageID      The message ID of the operation that
2158   *                        should not be canceled.
2159   */
2160  @org.opends.server.types.PublicAPI(
2161       stability=org.opends.server.types.StabilityLevel.PRIVATE,
2162       mayInstantiate=false,
2163       mayExtend=false,
2164       mayInvoke=false)
2165  @Override
2166  public void cancelAllOperationsExcept(CancelRequest cancelRequest,
2167                                        int messageID)
2168  {
2169    // No implementation is required since internal operations cannot
2170    // be cancelled.
2171  }
2172
2173
2174
2175  /**
2176   * Retrieves a one-line summary of this client connection in a form
2177   * that is suitable for including in the monitor entry for the
2178   * associated connection handler.  It should be in a format that is
2179   * both human readable and machine parseable (e.g., a
2180   * space-delimited name-value list, with quotes around the values).
2181   *
2182   * @return  A one-line summary of this client connection in a form
2183   *          that is suitable for including in the monitor entry for
2184   *          the associated connection handler.
2185   */
2186  @Override
2187  public String getMonitorSummary()
2188  {
2189    StringBuilder buffer = new StringBuilder();
2190    buffer.append("connID=\"");
2191    buffer.append(connectionID);
2192    buffer.append("\" authDN=\"");
2193    buffer.append(getAuthenticationInfo().getAuthenticationDN());
2194    buffer.append("\"");
2195
2196    return buffer.toString();
2197  }
2198
2199
2200
2201  /**
2202   * Appends a string representation of this client connection to the
2203   * provided buffer.
2204   *
2205   * @param  buffer  The buffer to which the information should be
2206   *                 appended.
2207   */
2208  @Override
2209  public void toString(StringBuilder buffer)
2210  {
2211    buffer.append("InternalClientConnection(connID=");
2212    buffer.append(connectionID);
2213    buffer.append(", authDN=\"");
2214
2215    if (getAuthenticationInfo() != null)
2216    {
2217      buffer.append(getAuthenticationInfo().getAuthenticationDN());
2218    }
2219
2220    buffer.append("\")");
2221  }
2222
2223  /**
2224   * Called near the end of server shutdown.  This ensures that a new
2225   * InternalClientConnection is created if the server is immediately
2226   * restarted as part of an in-core restart.
2227   */
2228  static void clearRootClientConnectionAtShutdown()
2229  {
2230    rootConnection = null;
2231  }
2232
2233  /**
2234   * To be implemented.
2235   *
2236   * @return number of operations performed on this connection
2237   */
2238  @Override
2239  public long getNumberOfOperations() {
2240    // Internal operations will not be limited.
2241    return 0;
2242  }
2243
2244  /** {@inheritDoc} */
2245  @Override
2246  public int getSSF() {
2247      //Always return strongest value.
2248      return 256;
2249  }
2250}