J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <!-- |
Kelly O'Hair | fe008ae | 2010-05-25 15:58:33 -0700 | [diff] [blame] | 5 | Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 6 | DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 7 | |
| 8 | This code is free software; you can redistribute it and/or modify it |
| 9 | under the terms of the GNU General Public License version 2 only, as |
Kelly O'Hair | fe008ae | 2010-05-25 15:58:33 -0700 | [diff] [blame] | 10 | published by the Free Software Foundation. Oracle designates this |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 11 | particular file as subject to the "Classpath" exception as provided |
Kelly O'Hair | fe008ae | 2010-05-25 15:58:33 -0700 | [diff] [blame] | 12 | by Oracle in the LICENSE file that accompanied this code. |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 13 | |
| 14 | This code is distributed in the hope that it will be useful, but WITHOUT |
| 15 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 17 | version 2 for more details (a copy is included in the LICENSE file that |
| 18 | accompanied this code). |
| 19 | |
| 20 | You should have received a copy of the GNU General Public License version |
| 21 | 2 along with this work; if not, write to the Free Software Foundation, |
| 22 | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 23 | |
Kelly O'Hair | 80b67f8 | 2010-05-26 20:28:04 -0700 | [diff] [blame] | 24 | Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 25 | or visit www.oracle.com if you need additional information or have any |
| 26 | questions. |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 27 | |
| 28 | --> |
| 29 | </head> |
| 30 | <body bgcolor="white"> |
| 31 | |
| 32 | Provides support for LDAPv3 extended operations and controls. |
| 33 | |
| 34 | <p> |
| 35 | This package extends the directory operations of the Java Naming and |
Joe Darcy | 5899576 | 2015-05-19 13:30:03 -0700 | [diff] [blame] | 36 | Directory Interface™ (JNDI). |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 37 | JNDI provides naming and directory functionality to applications |
| 38 | written in the Java programming language. It is designed to be |
| 39 | independent of any specific naming or directory service |
| 40 | implementation. Thus a variety of services--new, emerging, and |
| 41 | already deployed ones--can be accessed in a common way. |
| 42 | |
| 43 | <p> |
| 44 | This package is for applications and service providers that deal with |
| 45 | LDAPv3 extended operations and controls, as defined by |
| 46 | <a href=http://www.ietf.org/rfc/rfc2251.txt>RFC 2251</a>. |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 47 | The core interface in this package is <code>LdapContext</code>, which defines |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 48 | methods on a context for performing extended operations and handling |
| 49 | controls. |
| 50 | |
Kumar Srinivasan | 2bfca02 | 2017-05-12 10:26:25 -0700 | [diff] [blame] | 51 | <h3>Extended Operations</h3> |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 52 | <p> |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 53 | This package defines the interface <code>ExtendedRequest</code> |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 54 | to represent the argument to an extended operation, |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 55 | and the interface <code>ExtendedResponse</code> to represent the result |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 56 | of the extended operation. |
| 57 | An extended response is always paired with an extended request |
| 58 | but not necessarily vice versa. That is, you can have an extended request |
| 59 | that has no corresponding extended response. |
| 60 | <p> |
| 61 | An application typically does not deal directly with these interfaces. |
| 62 | Instead, it deals with classes that <em>implement</em> these |
| 63 | interfaces. |
| 64 | The application gets these classes either as part of a |
| 65 | repertoire of extended operations standardized through the IETF, or |
| 66 | from directory vendors for vendor-specific extended operations. |
| 67 | The request classes should have constructors that accept |
| 68 | arguments in a type-safe and user-friendly manner, while the |
| 69 | response classes should have access methods for getting the data |
| 70 | of the response in a type-safe and user-friendly manner. |
| 71 | Internally, the request/response classes deal with encoding and decoding |
| 72 | BER values. |
| 73 | <p> |
| 74 | For example, suppose an LDAP server supports a "get time" extended operation. |
| 75 | It would supply classes such as |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 76 | <code>GetTimeRequest</code> and <code>GetTimeResponse</code>, |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 77 | so that applications can use this feature. |
| 78 | An application would use these classes as follows: |
| 79 | <blockquote><pre> |
| 80 | GetTimeResponse resp = |
| 81 | (GetTimeResponse) ectx.extendedOperation(new GetTimeRequest()); |
| 82 | long time = resp.getTime(); |
| 83 | </pre></blockquote> |
| 84 | <p> |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 85 | The <code>GetTimeRequest</code> and <code>GetTimeResponse</code> classes might |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 86 | be defined as follows: |
| 87 | <blockquote><pre> |
| 88 | public class GetTimeRequest implements ExtendedRequest { |
| 89 | // User-friendly constructor |
| 90 | public GetTimeRequest() { |
| 91 | }; |
| 92 | |
| 93 | // Methods used by service providers |
| 94 | public String getID() { |
| 95 | return GETTIME_REQ_OID; |
| 96 | } |
| 97 | public byte[] getEncodedValue() { |
| 98 | return null; // no value needed for get time request |
| 99 | } |
| 100 | public ExtendedResponse createExtendedResponse( |
| 101 | String id, byte[] berValue, int offset, int length) throws NamingException { |
| 102 | return new GetTimeResponse(id, berValue, offset, length); |
| 103 | } |
| 104 | } |
| 105 | public class GetTimeResponse() implements ExtendedResponse { |
| 106 | long time; |
| 107 | // called by GetTimeRequest.createExtendedResponse() |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 108 | public GetTimeResponse(String id, byte[] berValue, int offset, int length) |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 109 | throws NamingException { |
| 110 | // check validity of id |
| 111 | long time = ... // decode berValue to get time |
| 112 | } |
| 113 | |
| 114 | // Type-safe and User-friendly methods |
| 115 | public java.util.Date getDate() { return new java.util.Date(time); } |
| 116 | public long getTime() { return time; } |
| 117 | |
| 118 | // Low level methods |
| 119 | public byte[] getEncodedValue() { |
| 120 | return // berValue saved; |
| 121 | } |
| 122 | public String getID() { |
| 123 | return GETTIME_RESP_OID; |
| 124 | } |
| 125 | } |
| 126 | </pre></blockquote> |
| 127 | |
Kumar Srinivasan | 2bfca02 | 2017-05-12 10:26:25 -0700 | [diff] [blame] | 128 | <h3>Controls</h3> |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 129 | |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 130 | This package defines the interface <code>Control</code> to represent an LDAPv3 |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 131 | control. It can be a control that is sent to an LDAP server |
| 132 | (<em>request control</em>) or a control returned by an LDAP server |
| 133 | (<em>response control</em>). Unlike extended requests and responses, |
| 134 | there is not necessarily any pairing between request controls and |
| 135 | response controls. You can send request controls and expect no |
| 136 | response controls back, or receive response controls without sending |
| 137 | any request controls. |
| 138 | <p> |
| 139 | An application typically does not deal directly with this interface. |
| 140 | Instead, it deals with classes that <em>implement</em> this interface. |
| 141 | The application gets control classes either as part of a repertoire of |
| 142 | controls standardized through the IETF, or from directory vendors for |
| 143 | vendor-specific controls. The request control classes should have |
| 144 | constructors that accept arguments in a type-safe and user-friendly |
| 145 | manner, while the response control classes should have access methods |
| 146 | for getting the data of the response in a type-safe and user-friendly |
| 147 | manner. Internally, the request/response control classes deal with |
| 148 | encoding and decoding BER values. |
| 149 | <p> |
| 150 | For example, suppose an LDAP server supports a "signed results" |
| 151 | request control, which when sent with a request, asks the |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 152 | server to digitally sign the results of an operation. |
| 153 | It would supply a class <code>SignedResultsControl</code> so that applications |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 154 | can use this feature. |
| 155 | An application would use this class as follows: |
| 156 | <blockquote> |
| 157 | <pre> |
| 158 | Control[] reqCtls = new Control[] {new SignedResultsControl(Control.CRITICAL)}; |
| 159 | ectx.setRequestControls(reqCtls); |
| 160 | NamingEnumeration enum = ectx.search(...); |
| 161 | </pre> |
| 162 | </blockquote> |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 163 | The <code>SignedResultsControl</code> class might be defined as follows: |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 164 | <blockquote><pre> |
| 165 | public class SignedResultsControl implements Control { |
| 166 | // User-friendly constructor |
| 167 | public SignedResultsControl(boolean criticality) { |
| 168 | // assemble the components of the request control |
| 169 | }; |
| 170 | |
| 171 | // Methods used by service providers |
| 172 | public String getID() { |
| 173 | return // control's object identifier |
| 174 | } |
| 175 | public byte[] getEncodedValue() { |
| 176 | return // ASN.1 BER encoded control value |
| 177 | } |
| 178 | ... |
| 179 | } |
| 180 | </pre></blockquote> |
| 181 | <p> |
| 182 | When a service provider receives response controls, it uses |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 183 | the <code>ControlFactory</code> class to produce specific classes |
| 184 | that implement the <code>Control</code> interface. |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 185 | <p> |
| 186 | An LDAP server can send back response controls with an LDAP operation |
| 187 | and also with enumeration results, such as those returned |
| 188 | by a list or search operation. |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 189 | The <code>LdapContext</code> provides a method (<code>getResponseControls()</code>) |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 190 | for getting the response controls sent with an LDAP operation, |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 191 | while the <code>HasControls</code> interface is used to retrieve |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 192 | response controls associated with enumeration results. |
| 193 | <p> |
| 194 | For example, suppose an LDAP server sends back a "change ID" control in response |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 195 | to a successful modification. It would supply a class <code>ChangeIDControl</code> |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 196 | so that the application can use this feature. |
| 197 | An application would perform an update, and then try to get the change ID. |
| 198 | <blockquote><pre> |
| 199 | // Perform update |
| 200 | Context ctx = ectx.createSubsubcontext("cn=newobj"); |
| 201 | |
| 202 | // Get response controls |
| 203 | Control[] respCtls = ectx.getResponseControls(); |
| 204 | if (respCtls != null) { |
| 205 | // Find the one we want |
Kumar Srinivasan | 2bfca02 | 2017-05-12 10:26:25 -0700 | [diff] [blame] | 206 | for (int i = 0; i < respCtls; i++) { |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 207 | if(respCtls[i] instanceof ChangeIDControl) { |
| 208 | ChangeIDControl cctl = (ChangeIDControl)respCtls[i]; |
| 209 | System.out.println(cctl.getChangeID()); |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | </pre></blockquote> |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 214 | The vendor might supply the following <code>ChangeIDControl</code> and |
| 215 | <code>VendorXControlFactory</code> classes. The <code>VendorXControlFactory</code> |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 216 | will be used by the service provider when the provider receives response |
| 217 | controls from the LDAP server. |
| 218 | <blockquote><pre> |
| 219 | public class ChangeIDControl implements Control { |
| 220 | long id; |
| 221 | |
| 222 | // Constructor used by ControlFactory |
| 223 | public ChangeIDControl(String OID, byte[] berVal) throws NamingException { |
| 224 | // check validity of OID |
| 225 | id = // extract change ID from berVal |
| 226 | }; |
| 227 | |
| 228 | // Type-safe and User-friendly method |
| 229 | public long getChangeID() { |
| 230 | return id; |
| 231 | } |
| 232 | |
| 233 | // Low-level methods |
| 234 | public String getID() { |
| 235 | return CHANGEID_OID; |
| 236 | } |
| 237 | public byte[] getEncodedValue() { |
| 238 | return // original berVal |
| 239 | } |
| 240 | ... |
| 241 | } |
| 242 | public class VendorXControlFactory extends ControlFactory { |
| 243 | public VendorXControlFactory () { |
| 244 | } |
| 245 | |
| 246 | public Control getControlInstance(Control orig) throws NamingException { |
| 247 | if (isOneOfMyControls(orig.getID())) { |
Alexander Stepanov | ff767bf | 2015-08-05 13:40:18 +0300 | [diff] [blame] | 248 | ... |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 249 | |
| 250 | // determine which of ours it is and call its constructor |
| 251 | return (new ChangeIDControl(orig.getID(), orig.getEncodedValue())); |
| 252 | } |
| 253 | return null; // not one of ours |
| 254 | } |
| 255 | } |
| 256 | </pre></blockquote> |
| 257 | |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 258 | <h2>Package Specification</h2> |
| 259 | |
| 260 | The JNDI API Specification and related documents can be found in the |
Daniel Fuchs | 915eecd | 2017-05-12 19:06:56 +0100 | [diff] [blame] | 261 | {@extLink jndi_overview JNDI documentation}. |
J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 262 | |
| 263 | @since 1.3 |
| 264 | |
| 265 | </body> |
| 266 | </html> |