0001: /*
0002:
0003: Derby - Class org.apache.derby.client.net.NetConnection
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to You under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021: package org.apache.derby.client.net;
0022:
0023: import java.sql.SQLException;
0024: import org.apache.derby.client.am.CallableStatement;
0025: import org.apache.derby.client.am.DatabaseMetaData;
0026: import org.apache.derby.client.am.DisconnectException;
0027: import org.apache.derby.client.am.EncryptionManager;
0028: import org.apache.derby.client.am.PreparedStatement;
0029: import org.apache.derby.client.am.ProductLevel;
0030: import org.apache.derby.client.am.SqlException;
0031: import org.apache.derby.client.am.ClientMessageId;
0032: import org.apache.derby.shared.common.reference.MessageId;
0033: import org.apache.derby.shared.common.i18n.MessageUtil;
0034: import org.apache.derby.client.am.Statement;
0035: import org.apache.derby.client.am.Utils;
0036: import org.apache.derby.jdbc.ClientBaseDataSource;
0037: import org.apache.derby.jdbc.ClientDataSource;
0038: import org.apache.derby.jdbc.ClientDriver;
0039: import org.apache.derby.client.ClientPooledConnection;
0040:
0041: import org.apache.derby.shared.common.reference.SQLState;
0042:
0043: public class NetConnection extends
0044: org.apache.derby.client.am.Connection {
0045:
0046: // Use this to get internationalized strings...
0047: protected static MessageUtil msgutil = SqlException
0048: .getMessageUtil();
0049:
0050: protected NetAgent netAgent_;
0051: //contains a reference to the PooledConnection from which this created
0052: //It then passes this reference to the PreparedStatement created from it
0053: //The PreparedStatement then uses this to pass the close and the error
0054: //occurred conditions back to the PooledConnection which can then throw the
0055: //appropriate events.
0056: protected ClientPooledConnection pooledConnection_ = null;
0057:
0058: // For XA Transaction
0059: protected int pendingEndXACallinfoOffset_ = -1;
0060:
0061: // byte[] to save the connect flows for connection reset
0062: protected byte[] cachedConnectBytes_ = null;
0063: protected boolean wroteConnectFromCache_ = false;
0064: //-----------------------------state------------------------------------------
0065:
0066: // these variables store the manager levels for the connection.
0067: // they are initialized to the highest value which this driver supports
0068: // at the current time. theses intial values should be increased when
0069: // new manager level support is added to this driver. these initial values
0070: // are sent to the server in the excsat command. the server will return a
0071: // set of values and these will be parsed out by parseExcsatrd and parseMgrlvlls.
0072: // during this parsing, these instance variable values will be reset to the negotiated
0073: // levels for the connection. these values may be less than the
0074: // values origionally set here at constructor time. it is these new values
0075: // (following the parse) which are the levels for the connection. after
0076: // a successful excsat command, these values can be checked to see
0077: // what protocol is supported by this particular connection.
0078: // if support for a new manager class is added, the buildExcsat and parseMgrlvlls
0079: // methods will need to be changed to accomodate sending and receiving the new class.
0080: protected int targetAgent_ = NetConfiguration.MGRLVL_7; //01292003jev monitoring
0081: protected int targetCmntcpip_ = NetConfiguration.MGRLVL_5;
0082: protected int targetRdb_ = NetConfiguration.MGRLVL_7;
0083: public int targetSecmgr_ = NetConfiguration.MGRLVL_7;
0084: protected int targetCmnappc_ = NetConfiguration.MGRLVL_NA; //NA since currently not used by net
0085: protected int targetXamgr_ = NetConfiguration.MGRLVL_7;
0086: protected int targetSyncptmgr_ = NetConfiguration.MGRLVL_NA;
0087: protected int targetRsyncmgr_ = NetConfiguration.MGRLVL_NA;
0088:
0089: // this is the external name of the target server.
0090: // it is set by the parseExcsatrd method but not really used for much at this
0091: // time. one possible use is for logging purposes and in the future it
0092: // may be placed in the trace.
0093: String targetExtnam_;
0094: String extnam_;
0095:
0096: // Server Class Name of the target server returned in excsatrd.
0097: // Again this is something which the driver is not currently using
0098: // to make any decions. Right now it is just stored for future logging.
0099: // It does contain some useful information however and possibly
0100: // the database meta data object will make use of this
0101: // for example, the product id (prdid) would give this driver an idea of
0102: // what type of sevrer it is connected to.
0103: public String targetSrvclsnm_;
0104:
0105: // Server Name of the target server returned in excsatrd.
0106: // Again this is something which we don't currently use but
0107: // keep it in case we want to log it in some problem determination
0108: // trace/dump later.
0109: protected String targetSrvnam_;
0110:
0111: // Server Product Release Level of the target server returned in excsatrd.
0112: // specifies the procuct release level of a ddm server.
0113: // Again this is something which we don't currently use but
0114: // keep it in case we want to log it in some problem determination
0115: // trace/dump later.
0116: public String targetSrvrlslv_;
0117:
0118: // Keys used for encryption.
0119: transient byte[] publicKey_;
0120: transient byte[] targetPublicKey_;
0121:
0122: // Seeds used for strong password substitute generation (USRSSBPWD)
0123: transient byte[] sourceSeed_; // Client seed
0124: transient byte[] targetSeed_; // Server seed
0125:
0126: // Product-Specific Data (prddta) sent to the server in the accrdb command.
0127: // The prddta has a specified format. It is saved in case it is needed again
0128: // since it takes a little effort to compute. Saving this information is
0129: // useful for when the connect flows need to be resent (right now the connect
0130: // flow is resent when this driver disconnects and reconnects with
0131: // non unicode ccsids. this is done when the server doesn't recoginze the
0132: // unicode ccsids).
0133: //
0134:
0135: byte[] prddta_;
0136:
0137: // Correlation Token of the source sent to the server in the accrdb.
0138: // It is saved like the prddta in case it is needed for a connect reflow.
0139: public byte[] crrtkn_;
0140:
0141: // The Secmec used by the target.
0142: // It contains the negotiated security mechanism for the connection.
0143: // Initially the value of this is 0. It is set only when the server and
0144: // the target successfully negotiate a security mechanism.
0145: int targetSecmec_;
0146:
0147: // the security mechanism requested by the application
0148: protected int securityMechanism_;
0149:
0150: // stored the password for deferred reset only.
0151: private transient char[] deferredResetPassword_ = null;
0152:
0153: //If Network Server gets null connection from the embedded driver,
0154: //it sends RDBAFLRM followed by SQLCARD with null SQLException.
0155: //Client will parse the SQLCARD and set connectionNull to true if the
0156: //SQLCARD is empty. If connectionNull=true, connect method in
0157: //ClientDriver will in turn return null connection.
0158: private boolean connectionNull = false;
0159:
0160: private void setDeferredResetPassword(String password) {
0161: deferredResetPassword_ = (password == null) ? null
0162: : flipBits(password.toCharArray());
0163: }
0164:
0165: private String getDeferredResetPassword() {
0166: if (deferredResetPassword_ == null) {
0167: return null;
0168: }
0169: String password = new String(flipBits(deferredResetPassword_));
0170: flipBits(deferredResetPassword_); // re-encrypt password
0171: return password;
0172: }
0173:
0174: protected byte[] cnntkn_ = null;
0175:
0176: // resource manager Id for XA Connections.
0177: private int rmId_ = 0;
0178: protected NetXAResource xares_ = null;
0179: protected java.util.Hashtable indoubtTransactions_ = null;
0180: protected int currXACallInfoOffset_ = 0;
0181: private short seqNo_ = 1;
0182:
0183: // Flag to indicate a read only transaction
0184: protected boolean readOnlyTransaction_ = true;
0185:
0186: //---------------------constructors/finalizer---------------------------------
0187:
0188: public NetConnection(NetLogWriter netLogWriter,
0189: String databaseName, java.util.Properties properties)
0190: throws SqlException {
0191: super (netLogWriter, 0, "", -1, databaseName, properties);
0192: }
0193:
0194: public NetConnection(NetLogWriter netLogWriter,
0195: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
0196: String user, String password) throws SqlException {
0197: super (netLogWriter, user, password, dataSource);
0198: setDeferredResetPassword(password);
0199: }
0200:
0201: // For jdbc 1 connections
0202: public NetConnection(NetLogWriter netLogWriter,
0203: int driverManagerLoginTimeout, String serverName,
0204: int portNumber, String databaseName,
0205: java.util.Properties properties) throws SqlException {
0206: super (netLogWriter, driverManagerLoginTimeout, serverName,
0207: portNumber, databaseName, properties);
0208: netAgent_ = (NetAgent) super .agent_;
0209: if (netAgent_.exceptionOpeningSocket_ != null) {
0210: throw netAgent_.exceptionOpeningSocket_;
0211: }
0212: checkDatabaseName();
0213: String password = ClientBaseDataSource.getPassword(properties);
0214: securityMechanism_ = ClientBaseDataSource
0215: .getSecurityMechanism(properties);
0216: flowConnect(password, securityMechanism_);
0217: if (!isConnectionNull())
0218: completeConnect();
0219: }
0220:
0221: // For JDBC 2 Connections
0222: public NetConnection(NetLogWriter netLogWriter, String user,
0223: String password,
0224: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
0225: int rmId, boolean isXAConn) throws SqlException {
0226: super (netLogWriter, user, password, isXAConn, dataSource);
0227: netAgent_ = (NetAgent) super .agent_;
0228: initialize(user, password, dataSource, rmId, isXAConn);
0229: }
0230:
0231: public NetConnection(NetLogWriter netLogWriter, String ipaddr,
0232: int portNumber,
0233: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
0234: boolean isXAConn) throws SqlException {
0235: super (netLogWriter, isXAConn, dataSource);
0236: netAgent_ = (NetAgent) super .agent_;
0237: if (netAgent_.exceptionOpeningSocket_ != null) {
0238: throw netAgent_.exceptionOpeningSocket_;
0239: }
0240: checkDatabaseName();
0241: this .isXAConnection_ = isXAConn;
0242: flowSimpleConnect();
0243: productID_ = targetSrvrlslv_;
0244: super .completeConnect();
0245: }
0246:
0247: // For JDBC 2 Connections
0248: /**
0249: * This constructor is called from the ClientPooledConnection object
0250: * to enable the NetConnection to pass <code>this</code> on to the associated
0251: * prepared statement object thus enabling the prepared statement object
0252: * to inturn raise the statement events to the ClientPooledConnection object
0253: * @param netLogWriter NetLogWriter object associated with this connection
0254: * @param user user id for this connection
0255: * @param password password for this connection
0256: * @param dataSource The DataSource object passed from the PooledConnection
0257: * object from which this constructor was called
0258: * @param rmId The Resource manager ID for XA Connections
0259: * @param isXAConn true if this is a XA connection
0260: * @param cpc The ClientPooledConnection object from which this
0261: * NetConnection constructor was called. This is used
0262: * to pass StatementEvents back to the pooledConnection
0263: * object
0264: * @throws SqlException
0265: */
0266:
0267: public NetConnection(NetLogWriter netLogWriter, String user,
0268: String password,
0269: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
0270: int rmId, boolean isXAConn, ClientPooledConnection cpc)
0271: throws SqlException {
0272: super (netLogWriter, user, password, isXAConn, dataSource);
0273: netAgent_ = (NetAgent) super .agent_;
0274: initialize(user, password, dataSource, rmId, isXAConn);
0275: this .pooledConnection_ = cpc;
0276: }
0277:
0278: private void initialize(String user, String password,
0279: org.apache.derby.jdbc.ClientBaseDataSource dataSource,
0280: int rmId, boolean isXAConn) throws SqlException {
0281: securityMechanism_ = dataSource.getSecurityMechanism(password);
0282:
0283: setDeferredResetPassword(password);
0284: checkDatabaseName();
0285: dataSource_ = dataSource;
0286: this .rmId_ = rmId;
0287: this .isXAConnection_ = isXAConn;
0288: flowConnect(password, securityMechanism_);
0289: completeConnect();
0290:
0291: }
0292:
0293: // preferably without password in the method signature.
0294: // We can probally get rid of flowReconnect method.
0295: public void resetNetConnection(
0296: org.apache.derby.client.am.LogWriter logWriter,
0297: String user, String password,
0298: org.apache.derby.jdbc.ClientBaseDataSource ds,
0299: boolean recomputeFromDataSource) throws SqlException {
0300: super .resetConnection(logWriter, user, ds,
0301: recomputeFromDataSource);
0302: //----------------------------------------------------
0303: if (recomputeFromDataSource) {
0304: // do not reset managers on a connection reset. this information shouldn't
0305: // change and can be used to check secmec support.
0306:
0307: targetExtnam_ = null;
0308: targetSrvclsnm_ = null;
0309: targetSrvnam_ = null;
0310: targetSrvrlslv_ = null;
0311: publicKey_ = null;
0312: targetPublicKey_ = null;
0313: sourceSeed_ = null;
0314: targetSeed_ = null;
0315: targetSecmec_ = 0;
0316: if (ds != null && securityMechanism_ == 0) {
0317: securityMechanism_ = ds.getSecurityMechanism(password);
0318: }
0319: resetConnectionAtFirstSql_ = false;
0320:
0321: }
0322: if (password != null) {
0323: deferredResetPassword_ = null;
0324: } else {
0325: password = getDeferredResetPassword();
0326: }
0327: // properties prddta_ and crrtkn_ will be initialized by
0328: // calls to constructPrddta() and constructCrrtkn()
0329: //----------------------------------------------------------
0330: boolean isDeferredReset = flowReconnect(password,
0331: securityMechanism_);
0332: completeReset(isDeferredReset, recomputeFromDataSource);
0333: }
0334:
0335: protected void reset_(
0336: org.apache.derby.client.am.LogWriter logWriter,
0337: String user, String password, ClientBaseDataSource ds,
0338: boolean recomputeFromDataSource) throws SqlException {
0339: checkResetPreconditions(logWriter, user, password, ds);
0340: resetNetConnection(logWriter, user, password, ds,
0341: recomputeFromDataSource);
0342: }
0343:
0344: protected void reset_(
0345: org.apache.derby.client.am.LogWriter logWriter,
0346: ClientBaseDataSource ds, boolean recomputeFromDataSource)
0347: throws SqlException {
0348: checkResetPreconditions(logWriter, null, null, ds);
0349: resetNetConnection(logWriter, ds, recomputeFromDataSource);
0350: }
0351:
0352: private void resetNetConnection(
0353: org.apache.derby.client.am.LogWriter logWriter,
0354: org.apache.derby.jdbc.ClientBaseDataSource ds,
0355: boolean recomputeFromDataSource) throws SqlException {
0356: super .resetConnection(logWriter, null, ds,
0357: recomputeFromDataSource);
0358: //----------------------------------------------------
0359: if (recomputeFromDataSource) {
0360: // do not reset managers on a connection reset. this information shouldn't
0361: // change and can be used to check secmec support.
0362:
0363: targetExtnam_ = null;
0364: targetSrvclsnm_ = null;
0365: targetSrvnam_ = null;
0366: targetSrvrlslv_ = null;
0367: publicKey_ = null;
0368: targetPublicKey_ = null;
0369: sourceSeed_ = null;
0370: targetSeed_ = null;
0371: targetSecmec_ = 0;
0372: if (ds != null && securityMechanism_ == 0) {
0373: securityMechanism_ = ds.getSecurityMechanism();
0374: }
0375: resetConnectionAtFirstSql_ = false;
0376: }
0377: // properties prddta_ and crrtkn_ will be initialized by
0378: // calls to constructPrddta() and constructCrrtkn()
0379: //----------------------------------------------------------
0380: boolean isDeferredReset = flowReconnect(null,
0381: securityMechanism_);
0382: completeReset(isDeferredReset, recomputeFromDataSource);
0383: }
0384:
0385: protected void checkResetPreconditions(
0386: org.apache.derby.client.am.LogWriter logWriter,
0387: String user, String password, ClientBaseDataSource ds)
0388: throws SqlException {
0389: if (inUnitOfWork_) {
0390: throw new SqlException(
0391: logWriter,
0392: new ClientMessageId(
0393: SQLState.NET_CONNECTION_RESET_NOT_ALLOWED_IN_UNIT_OF_WORK));
0394: }
0395: }
0396:
0397: java.util.List getSpecialRegisters() {
0398: if (xares_ != null) {
0399: return xares_.getSpecialRegisters();
0400: } else {
0401: return null;
0402: }
0403: }
0404:
0405: public void addSpecialRegisters(String s) {
0406: if (xares_ != null) {
0407: xares_.addSpecialRegisters(s);
0408: }
0409: }
0410:
0411: public void completeConnect() throws SqlException {
0412: super .completeConnect();
0413: }
0414:
0415: protected void completeReset(boolean isDeferredReset,
0416: boolean recomputeFromDataSource) throws SqlException {
0417: super .completeReset(isDeferredReset, recomputeFromDataSource);
0418: }
0419:
0420: public void flowConnect(String password, int securityMechanism)
0421: throws SqlException {
0422: netAgent_ = (NetAgent) super .agent_;
0423: constructExtnam();
0424: // these calls need to be after newing up the agent
0425: // because they require the ccsid manager
0426: constructPrddta(); // construct product data
0427:
0428: netAgent_.typdef_ = new Typdef(netAgent_, 1208,
0429: NetConfiguration.SYSTEM_ASC, 1200, 1208);
0430: netAgent_.targetTypdef_ = new Typdef(netAgent_);
0431: netAgent_.originalTargetTypdef_ = netAgent_.targetTypdef_;
0432: setDeferredResetPassword(password);
0433: try {
0434: switch (securityMechanism) {
0435: case NetConfiguration.SECMEC_USRIDPWD: // Clear text user id and password
0436: checkUserPassword(user_, password);
0437: flowUSRIDPWDconnect(password);
0438: break;
0439: case NetConfiguration.SECMEC_USRIDONL: // Clear text user, no password sent to server
0440: checkUser(user_);
0441: flowUSRIDONLconnect();
0442: break;
0443: case NetConfiguration.SECMEC_USRENCPWD: // Clear text user, encrypted password
0444: checkUserPassword(user_, password);
0445: flowUSRENCPWDconnect(password);
0446: break;
0447: case NetConfiguration.SECMEC_EUSRIDPWD: // Encrypted user, encrypted password
0448: checkUserPassword(user_, password);
0449: flowEUSRIDPWDconnect(password);
0450: break;
0451: case NetConfiguration.SECMEC_EUSRIDDTA:
0452: checkUserPassword(user_, password);
0453: flowEUSRIDDTAconnect();
0454: break;
0455: case NetConfiguration.SECMEC_EUSRPWDDTA:
0456: checkUserPassword(user_, password);
0457: flowEUSRPWDDTAconnect(password);
0458: break;
0459: case NetConfiguration.SECMEC_USRSSBPWD: // Clear text user, strong password substitute
0460: checkUserPassword(user_, password);
0461: flowUSRSSBPWDconnect(password);
0462: break;
0463:
0464: default:
0465: throw new SqlException(agent_.logWriter_,
0466: new ClientMessageId(
0467: SQLState.SECMECH_NOT_SUPPORTED),
0468: new Integer(securityMechanism));
0469: }
0470: } catch (java.lang.Throwable e) { // if *anything* goes wrong, make sure the connection is destroyed
0471: // always mark the connection closed in case of an error.
0472: // This prevents attempts to use this closed connection
0473: // to retrieve error message text if an error SQLCA
0474: // is returned in one of the connect flows.
0475: open_ = false;
0476: // logWriter may be closed in agent_.close(),
0477: // so SqlException needs to be created before that
0478: // but to be thrown after.
0479: SqlException exceptionToBeThrown;
0480: if (e instanceof SqlException) // rethrow original exception if it's an SqlException
0481: {
0482: exceptionToBeThrown = (SqlException) e;
0483: } else // any other exceptions will be wrapped by an SqlException first
0484: {
0485: exceptionToBeThrown = new SqlException(
0486: agent_.logWriter_, new ClientMessageId(
0487: SQLState.JAVA_EXCEPTION), e.getClass()
0488: .getName(), e.getMessage(), e);
0489: }
0490:
0491: try {
0492: if (agent_ != null) {
0493: agent_.close();
0494: }
0495: } catch (SqlException ignoreMe) {
0496: }
0497:
0498: throw exceptionToBeThrown;
0499: }
0500: }
0501:
0502: protected void flowSimpleConnect() throws SqlException {
0503: netAgent_ = (NetAgent) super .agent_;
0504: constructExtnam();
0505: // these calls need to be after newing up the agent
0506: // because they require the ccsid manager
0507: constructPrddta(); // construct product data
0508:
0509: netAgent_.typdef_ = new Typdef(netAgent_, 1208,
0510: NetConfiguration.SYSTEM_ASC, 1200, 1208);
0511: netAgent_.targetTypdef_ = new Typdef(netAgent_);
0512: netAgent_.originalTargetTypdef_ = netAgent_.targetTypdef_;
0513:
0514: try {
0515: flowServerAttributes();
0516: } catch (java.lang.Throwable e) { // if *anything* goes wrong, make sure the connection is destroyed
0517: // always mark the connection closed in case of an error.
0518: // This prevents attempts to use this closed connection
0519: // to retrieve error message text if an error SQLCA
0520: // is returned in one of the connect flows.
0521: open_ = false;
0522: // logWriter may be closed in agent_.close(),
0523: // so SqlException needs to be created before that
0524: // but to be thrown after.
0525: SqlException exceptionToBeThrown;
0526: if (e instanceof SqlException) // rethrow original exception if it's an SqlException
0527: {
0528: exceptionToBeThrown = (SqlException) e;
0529: } else // any other exceptions will be wrapped by an SqlException first
0530: {
0531: exceptionToBeThrown = new SqlException(
0532: agent_.logWriter_, new ClientMessageId(
0533: SQLState.JAVA_EXCEPTION), e.getClass()
0534: .getName(), e.getMessage(), e);
0535: }
0536:
0537: try {
0538: if (agent_ != null) {
0539: agent_.close();
0540: }
0541: } catch (SqlException ignoreMe) {
0542: }
0543:
0544: throw exceptionToBeThrown;
0545: }
0546: }
0547:
0548: protected boolean flowReconnect(String password,
0549: int securityMechanism) throws SqlException {
0550: constructExtnam();
0551: // these calls need to be after newing up the agent
0552: // because they require the ccsid manager
0553: constructPrddta(); //modify this to not new up an array
0554:
0555: checkSecmgrForSecmecSupport(securityMechanism);
0556: try {
0557: switch (securityMechanism) {
0558: case NetConfiguration.SECMEC_USRIDPWD: // Clear text user id and password
0559: checkUserPassword(user_, password);
0560: resetConnectionAtFirstSql_ = true;
0561: setDeferredResetPassword(password);
0562: return true;
0563: case NetConfiguration.SECMEC_USRIDONL: // Clear text user, no password sent to server
0564: checkUser(user_);
0565: resetConnectionAtFirstSql_ = true;
0566: return true;
0567: case NetConfiguration.SECMEC_USRENCPWD: // Clear text user, encrypted password
0568: checkUserPassword(user_, password);
0569: resetConnectionAtFirstSql_ = true;
0570: setDeferredResetPassword(password);
0571: return true;
0572: case NetConfiguration.SECMEC_EUSRIDPWD: // Encrypted user, encrypted password
0573: checkUserPassword(user_, password);
0574: resetConnectionAtFirstSql_ = true;
0575: setDeferredResetPassword(password);
0576: return true;
0577: case NetConfiguration.SECMEC_EUSRIDDTA:
0578: checkUserPassword(user_, password);
0579: resetConnectionAtFirstSql_ = true;
0580: setDeferredResetPassword(password);
0581: return true;
0582: case NetConfiguration.SECMEC_EUSRPWDDTA:
0583: checkUserPassword(user_, password);
0584: resetConnectionAtFirstSql_ = true;
0585: setDeferredResetPassword(password);
0586: return true;
0587: case NetConfiguration.SECMEC_USRSSBPWD: // Clear text user, strong password substitute
0588: checkUserPassword(user_, password);
0589: resetConnectionAtFirstSql_ = true;
0590: setDeferredResetPassword(password);
0591: return true;
0592: default:
0593: throw new SqlException(agent_.logWriter_,
0594: new ClientMessageId(
0595: SQLState.SECMECH_NOT_SUPPORTED),
0596: new Integer(securityMechanism));
0597: }
0598: } catch (SqlException sqle) { // this may not be needed because on method up the stack
0599: open_ = false; // all reset exceptions are caught and wrapped in disconnect exceptions
0600: try {
0601: if (agent_ != null) {
0602: agent_.close();
0603: }
0604: } catch (SqlException ignoreMe) {
0605: }
0606: throw sqle;
0607: }
0608: }
0609:
0610: protected void finalize() throws java.lang.Throwable {
0611: super .finalize();
0612: }
0613:
0614: protected byte[] getCnnToken() {
0615: return cnntkn_;
0616: }
0617:
0618: protected short getSequenceNumber() {
0619: return ++seqNo_;
0620: }
0621:
0622: //--------------------------------flow methods--------------------------------
0623:
0624: private void flowUSRIDPWDconnect(String password)
0625: throws SqlException {
0626: flowServerAttributesAndKeyExchange(
0627: NetConfiguration.SECMEC_USRIDPWD, null); // publicKey
0628:
0629: flowSecurityCheckAndAccessRdb(targetSecmec_, //securityMechanism
0630: user_, password, null, //encryptedUserid
0631: null); //encryptedPassword
0632: }
0633:
0634: private void flowUSRIDONLconnect() throws SqlException {
0635: flowServerAttributesAndKeyExchange(
0636: NetConfiguration.SECMEC_USRIDONL, null); //publicKey
0637:
0638: flowSecurityCheckAndAccessRdb(targetSecmec_, //securityMechanism
0639: user_, null, //password
0640: null, //encryptedUserid
0641: null); //encryptedPassword
0642: }
0643:
0644: private void flowUSRENCPWDconnect(String password)
0645: throws SqlException {
0646: flowServerAttributes();
0647:
0648: checkSecmgrForSecmecSupport(NetConfiguration.SECMEC_USRENCPWD);
0649: initializePublicKeyForEncryption();
0650: flowKeyExchange(NetConfiguration.SECMEC_USRENCPWD, publicKey_);
0651:
0652: flowSecurityCheckAndAccessRdb(targetSecmec_, //securityMechanism
0653: user_, null, //password
0654: null, //encryptedUserid
0655: encryptedPasswordForUSRENCPWD(password));
0656: }
0657:
0658: private void flowEUSRIDPWDconnect(String password)
0659: throws SqlException {
0660: flowServerAttributes();
0661:
0662: checkSecmgrForSecmecSupport(NetConfiguration.SECMEC_EUSRIDPWD);
0663: initializePublicKeyForEncryption();
0664: flowKeyExchange(NetConfiguration.SECMEC_EUSRIDPWD, publicKey_);
0665:
0666: flowSecurityCheckAndAccessRdb(
0667: targetSecmec_, //securityMechanism
0668: null, //user
0669: null, //password
0670: encryptedUseridForEUSRIDPWD(),
0671: encryptedPasswordForEUSRIDPWD(password));
0672: }
0673:
0674: private void flowEUSRIDDTAconnect() throws SqlException {
0675: flowServerAttributes();
0676:
0677: checkSecmgrForSecmecSupport(NetConfiguration.SECMEC_EUSRIDPWD);
0678: initializePublicKeyForEncryption();
0679: flowKeyExchange(NetConfiguration.SECMEC_EUSRIDDTA, publicKey_);
0680:
0681: flowSecurityCheckAndAccessRdb(targetSecmec_, //securityMechanism
0682: null, //user
0683: null, //password
0684: encryptedUseridForEUSRIDPWD(), null);//encryptedPasswordForEUSRIDPWD (password),
0685: }
0686:
0687: private void flowEUSRPWDDTAconnect(String password)
0688: throws SqlException {
0689: flowServerAttributes();
0690:
0691: checkSecmgrForSecmecSupport(NetConfiguration.SECMEC_EUSRPWDDTA);
0692: initializePublicKeyForEncryption();
0693: flowKeyExchange(NetConfiguration.SECMEC_EUSRPWDDTA, publicKey_);
0694:
0695: flowSecurityCheckAndAccessRdb(
0696: targetSecmec_, //securityMechanism
0697: null, //user
0698: null, //password
0699: encryptedUseridForEUSRIDPWD(),
0700: encryptedPasswordForEUSRIDPWD(password));
0701: }
0702:
0703: /**
0704: * The User ID and Strong Password Substitute mechanism (USRSSBPWD)
0705: * authenticates the user like the user ID and password mechanism, but
0706: * the password does not flow. A password substitute is generated instead
0707: * using the SHA-1 algorithm, and is sent to the application server.
0708: *
0709: * The application server generates a password substitute using the same
0710: * algorithm and compares it with the application requester's password
0711: * substitute. If equal, the user is authenticated.
0712: *
0713: * The SECTKN parameter is used to flow the client and server encryption
0714: * seeds on the ACCSEC and ACCSECRD commands.
0715: *
0716: * More information in DRDA, V3, Volume 3 standard - PWDSSB (page 650)
0717: */
0718: private void flowUSRSSBPWDconnect(String password)
0719: throws SqlException {
0720: flowServerAttributes();
0721:
0722: checkSecmgrForSecmecSupport(NetConfiguration.SECMEC_USRSSBPWD);
0723: // Generate a random client seed to send to the target server - in
0724: // response we will also get a generated seed from this last one.
0725: // Seeds are used on both sides to generate the password substitute.
0726: initializeClientSeed();
0727:
0728: flowSeedExchange(NetConfiguration.SECMEC_USRSSBPWD, sourceSeed_);
0729:
0730: flowSecurityCheckAndAccessRdb(
0731: targetSecmec_, //securityMechanism
0732: user_, null, null,
0733: passwordSubstituteForUSRSSBPWD(password)); // PWD Substitute
0734: }
0735:
0736: private void flowServerAttributes() throws SqlException {
0737: agent_.beginWriteChainOutsideUOW();
0738: netAgent_.netConnectionRequest_.writeExchangeServerAttributes(
0739: extnam_, //externalName
0740: targetAgent_, netAgent_.targetSqlam_, targetRdb_,
0741: targetSecmgr_, targetCmntcpip_, targetCmnappc_,
0742: targetXamgr_, targetSyncptmgr_, targetRsyncmgr_);
0743: agent_.flowOutsideUOW();
0744: netAgent_.netConnectionReply_
0745: .readExchangeServerAttributes(this );
0746: agent_.endReadChain();
0747: }
0748:
0749: private void flowKeyExchange(int securityMechanism, byte[] publicKey)
0750: throws SqlException {
0751: agent_.beginWriteChainOutsideUOW();
0752: netAgent_.netConnectionRequest_.writeAccessSecurity(
0753: securityMechanism, databaseName_, publicKey);
0754: agent_.flowOutsideUOW();
0755: netAgent_.netConnectionReply_.readAccessSecurity(this ,
0756: securityMechanism);
0757: agent_.endReadChain();
0758: }
0759:
0760: private void flowSeedExchange(int securityMechanism,
0761: byte[] sourceSeed) throws SqlException {
0762: agent_.beginWriteChainOutsideUOW();
0763: netAgent_.netConnectionRequest_.writeAccessSecurity(
0764: securityMechanism, databaseName_, sourceSeed);
0765: agent_.flowOutsideUOW();
0766: netAgent_.netConnectionReply_.readAccessSecurity(this ,
0767: securityMechanism);
0768: agent_.endReadChain();
0769: }
0770:
0771: private void flowServerAttributesAndKeyExchange(
0772: int securityMechanism, byte[] publicKey)
0773: throws SqlException {
0774: agent_.beginWriteChainOutsideUOW();
0775: writeServerAttributesAndKeyExchange(securityMechanism,
0776: publicKey);
0777: agent_.flowOutsideUOW();
0778: readServerAttributesAndKeyExchange(securityMechanism);
0779: agent_.endReadChain();
0780: }
0781:
0782: private void flowServerAttributesAndSeedExchange(
0783: int securityMechanism, byte[] sourceSeed)
0784: throws SqlException {
0785: agent_.beginWriteChainOutsideUOW();
0786: writeServerAttributesAndSeedExchange(sourceSeed);
0787: agent_.flowOutsideUOW();
0788: readServerAttributesAndSeedExchange();
0789: agent_.endReadChain();
0790: }
0791:
0792: private void flowSecurityCheckAndAccessRdb(int securityMechanism,
0793: String user, String password, byte[] encryptedUserid,
0794: byte[] encryptedPassword) throws SqlException {
0795: agent_.beginWriteChainOutsideUOW();
0796: writeSecurityCheckAndAccessRdb(securityMechanism, user,
0797: password, encryptedUserid, encryptedPassword);
0798: agent_.flowOutsideUOW();
0799: readSecurityCheckAndAccessRdb();
0800: agent_.endReadChain();
0801: }
0802:
0803: private void writeAllConnectCommandsChained(int securityMechanism,
0804: String user, String password) throws SqlException {
0805: writeServerAttributesAndKeyExchange(securityMechanism, null); // publicKey
0806: writeSecurityCheckAndAccessRdb(securityMechanism, user,
0807: password, null, //encryptedUserid
0808: null); //encryptedPassword,
0809: }
0810:
0811: private void readAllConnectCommandsChained(int securityMechanism)
0812: throws SqlException {
0813: readServerAttributesAndKeyExchange(securityMechanism);
0814: readSecurityCheckAndAccessRdb();
0815: }
0816:
0817: private void writeServerAttributesAndKeyExchange(
0818: int securityMechanism, byte[] publicKey)
0819: throws SqlException {
0820: netAgent_.netConnectionRequest_.writeExchangeServerAttributes(
0821: extnam_, //externalName
0822: targetAgent_, netAgent_.targetSqlam_, targetRdb_,
0823: targetSecmgr_, targetCmntcpip_, targetCmnappc_,
0824: targetXamgr_, targetSyncptmgr_, targetRsyncmgr_);
0825: netAgent_.netConnectionRequest_.writeAccessSecurity(
0826: securityMechanism, databaseName_, publicKey);
0827: }
0828:
0829: private void writeServerAttributesAndSeedExchange(byte[] sourceSeed)
0830: throws SqlException {
0831:
0832: // For now, we're just calling our cousin method to do the job
0833: writeServerAttributesAndKeyExchange(
0834: NetConfiguration.SECMEC_USRSSBPWD, sourceSeed);
0835: }
0836:
0837: private void readServerAttributesAndKeyExchange(
0838: int securityMechanism) throws SqlException {
0839: netAgent_.netConnectionReply_
0840: .readExchangeServerAttributes(this );
0841: netAgent_.netConnectionReply_.readAccessSecurity(this ,
0842: securityMechanism);
0843: }
0844:
0845: private void readServerAttributesAndSeedExchange()
0846: throws SqlException {
0847: // For now, we're just calling our cousin method to do the job
0848: readServerAttributesAndKeyExchange(NetConfiguration.SECMEC_USRSSBPWD);
0849: }
0850:
0851: private void writeSecurityCheckAndAccessRdb(int securityMechanism,
0852: String user, String password, byte[] encryptedUserid,
0853: byte[] encryptedPassword) throws SqlException {
0854: netAgent_.netConnectionRequest_.writeSecurityCheck(
0855: securityMechanism, databaseName_, user, password,
0856: encryptedUserid, encryptedPassword);
0857: netAgent_.netConnectionRequest_.writeAccessDatabase(
0858: databaseName_, false, crrtkn_, prddta_,
0859: netAgent_.typdef_);
0860: }
0861:
0862: private void cacheConnectBytes(int beginOffset, int endOffset) {
0863: int length = endOffset - beginOffset;
0864: cachedConnectBytes_ = new byte[length];
0865: netAgent_.netConnectionRequest_
0866: .finalizePreviousChainedDss(false);
0867: System.arraycopy(netAgent_.netConnectionRequest_.bytes_,
0868: beginOffset, cachedConnectBytes_, 0, length);
0869: netAgent_.netConnectionRequest_
0870: .setDssLengthLocation(netAgent_.netConnectionRequest_.offset_);
0871: }
0872:
0873: private void readSecurityCheckAndAccessRdb() throws SqlException {
0874: netAgent_.netConnectionReply_.readSecurityCheck(this );
0875: netAgent_.netConnectionReply_.readAccessDatabase(this );
0876: }
0877:
0878: void writeDeferredReset() throws SqlException {
0879: if (canUseCachedConnectBytes_
0880: && cachedConnectBytes_ != null
0881: && (securityMechanism_ == NetConfiguration.SECMEC_USRIDPWD || securityMechanism_ == NetConfiguration.SECMEC_USRIDONL)) {
0882: writeDeferredResetFromCache();
0883: wroteConnectFromCache_ = true;
0884: } else {
0885: int beginOffset = netAgent_.netConnectionRequest_.offset_;
0886: int endOffset = 0;
0887: // NetConfiguration.SECMEC_USRIDPWD
0888: if (securityMechanism_ == NetConfiguration.SECMEC_USRIDPWD) {
0889: writeAllConnectCommandsChained(
0890: NetConfiguration.SECMEC_USRIDPWD, user_,
0891: getDeferredResetPassword());
0892: endOffset = netAgent_.netConnectionRequest_.offset_;
0893: cacheConnectBytes(beginOffset, endOffset);
0894: }
0895: // NetConfiguration.SECMEC_USRIDONL
0896: else if (securityMechanism_ == NetConfiguration.SECMEC_USRIDONL) {
0897: writeAllConnectCommandsChained(
0898: NetConfiguration.SECMEC_USRIDONL, user_, null); //password
0899: endOffset = netAgent_.netConnectionRequest_.offset_;
0900: cacheConnectBytes(beginOffset, endOffset);
0901: }
0902: // Either NetConfiguration.SECMEC_USRENCPWD,
0903: // NetConfiguration.SECMEC_EUSRIDPWD or
0904: // NetConfiguration.SECMEC_USRSSBPWD
0905: else {
0906: if (securityMechanism_ == NetConfiguration.SECMEC_USRSSBPWD)
0907: initializeClientSeed();
0908: else
0909: // SECMEC_USRENCPWD, SECMEC_EUSRIDPWD
0910: initializePublicKeyForEncryption();
0911:
0912: // Set the resetConnectionAtFirstSql_ to false to avoid going in an
0913: // infinite loop, since all the flow methods call beginWriteChain which then
0914: // calls writeDeferredResetConnection where the check for resetConnectionAtFirstSql_
0915: // is done. By setting the resetConnectionAtFirstSql_ to false will avoid calling the
0916: // writeDeferredReset method again.
0917: resetConnectionAtFirstSql_ = false;
0918:
0919: if (securityMechanism_ == NetConfiguration.SECMEC_USRSSBPWD)
0920: flowSeedExchange(securityMechanism_, sourceSeed_);
0921: else
0922: // SECMEC_USRENCPWD, SECMEC_EUSRIDPWD
0923: flowServerAttributesAndKeyExchange(
0924: securityMechanism_, publicKey_);
0925:
0926: agent_.beginWriteChainOutsideUOW();
0927:
0928: // Reset the resetConnectionAtFirstSql_ to true since we are done
0929: // with the flow method.
0930: resetConnectionAtFirstSql_ = true;
0931:
0932: // NetConfiguration.SECMEC_USRENCPWD
0933: if (securityMechanism_ == NetConfiguration.SECMEC_USRENCPWD) {
0934: writeSecurityCheckAndAccessRdb(
0935: NetConfiguration.SECMEC_USRENCPWD,
0936: user_,
0937: null, //password
0938: null, //encryptedUserid
0939: encryptedPasswordForUSRENCPWD(getDeferredResetPassword()));
0940: }
0941: // NetConfiguration.SECMEC_USRSSBPWD
0942: else if (securityMechanism_ == NetConfiguration.SECMEC_USRSSBPWD) {
0943: writeSecurityCheckAndAccessRdb(
0944: NetConfiguration.SECMEC_USRSSBPWD,
0945: user_,
0946: null,
0947: null,
0948: passwordSubstituteForUSRSSBPWD(getDeferredResetPassword()));
0949: } else { // NetConfiguration.SECMEC_EUSRIDPWD
0950: writeSecurityCheckAndAccessRdb(
0951: NetConfiguration.SECMEC_EUSRIDPWD,
0952: null, //user
0953: null, //password
0954: encryptedUseridForEUSRIDPWD(),
0955: encryptedPasswordForEUSRIDPWD(getDeferredResetPassword()));
0956: }
0957: }
0958: }
0959: }
0960:
0961: void readDeferredReset() throws SqlException {
0962: resetConnectionAtFirstSql_ = false;
0963: if (wroteConnectFromCache_) {
0964: netAgent_.netConnectionReply_.verifyDeferredReset();
0965: return;
0966: }
0967: // either NetConfiguration.SECMEC_USRIDPWD or NetConfiguration.SECMEC_USRIDONL
0968: if (securityMechanism_ == NetConfiguration.SECMEC_USRIDPWD
0969: || securityMechanism_ == NetConfiguration.SECMEC_USRIDONL) {
0970: readAllConnectCommandsChained(securityMechanism_);
0971: }
0972: // either NetConfiguration.SECMEC_USRENCPWD or NetConfiguration.SECMEC_EUSRIDPWD
0973: else {
0974: // either NetConfiguration.SECMEC_USRENCPWD or NetConfiguration.SECMEC_EUSRIDPWD
0975: readSecurityCheckAndAccessRdb();
0976: }
0977: if (agent_.loggingEnabled()) {
0978: agent_.logWriter_.traceConnectResetExit(this );
0979: }
0980: }
0981:
0982: //-------------------parse callback methods--------------------------------
0983:
0984: void setServerAttributeData(String extnam, String srvclsnm,
0985: String srvnam, String srvrlslv) {
0986: targetExtnam_ = extnam; // any of these could be null
0987: targetSrvclsnm_ = srvclsnm; // since then can be optionally returned from the
0988: targetSrvnam_ = srvnam; // server
0989: targetSrvrlslv_ = srvrlslv;
0990: }
0991:
0992: // secmecList is always required and will not be null.
0993: // secchkcd has an implied severity of error.
0994: // it will be returned if an error is detected.
0995: // if no errors and security mechanism requires a sectkn, then
0996: void setAccessSecurityData(int secchkcd, int desiredSecmec,
0997: int[] secmecList, boolean sectknReceived, byte[] sectkn)
0998: throws DisconnectException {
0999: // - if the secchkcd is not 0, then map to an exception.
1000: if (secchkcd != CodePoint.SECCHKCD_00) {
1001: // the implied severity code is error
1002: netAgent_.setSvrcod(CodePoint.SVRCOD_ERROR);
1003: agent_.accumulateReadException(mapSecchkcd(secchkcd));
1004: } else {
1005: // - verify that the secmec parameter reflects the value sent
1006: // in the ACCSEC command.
1007: // should we check for null list
1008: if ((secmecList.length == 1)
1009: && (secmecList[0] == desiredSecmec)) {
1010: // the security mechanism returned from the server matches
1011: // the mechanism requested by the client.
1012: targetSecmec_ = secmecList[0];
1013:
1014: if ((targetSecmec_ == NetConfiguration.SECMEC_USRENCPWD)
1015: || (targetSecmec_ == NetConfiguration.SECMEC_EUSRIDPWD)
1016: || (targetSecmec_ == NetConfiguration.SECMEC_USRSSBPWD)
1017: || (targetSecmec_ == NetConfiguration.SECMEC_EUSRIDDTA)
1018: || (targetSecmec_ == NetConfiguration.SECMEC_EUSRPWDDTA)) {
1019:
1020: // a security token is required for USRENCPWD, or EUSRIDPWD.
1021: if (!sectknReceived) {
1022: agent_
1023: .accumulateChainBreakingReadExceptionAndThrow(new DisconnectException(
1024: agent_,
1025: new ClientMessageId(
1026: SQLState.NET_SECTKN_NOT_RETURNED)));
1027: } else {
1028: if (targetSecmec_ == NetConfiguration.SECMEC_USRSSBPWD)
1029: targetSeed_ = sectkn;
1030: else
1031: targetPublicKey_ = sectkn;
1032: if (encryptionManager_ != null) {
1033: encryptionManager_.resetSecurityKeys();
1034: }
1035: }
1036: }
1037: } else {
1038: // accumulate an SqlException and don't disconnect yet
1039: // if a SECCHK was chained after this it would receive a secchk code
1040: // indicating the security mechanism wasn't supported and that would be a
1041: // chain breaking exception. if no SECCHK is chained this exception
1042: // will be surfaced by endReadChain
1043: // agent_.accumulateChainBreakingReadExceptionAndThrow (
1044: // new DisconnectException (agent_,"secmec not supported ","0000", -999));
1045: agent_.accumulateReadException(new SqlException(
1046: agent_.logWriter_, new ClientMessageId(
1047: SQLState.NET_SECKTKN_NOT_RETURNED)));
1048: }
1049: }
1050: }
1051:
1052: void securityCheckComplete(int svrcod, int secchkcd) {
1053: netAgent_.setSvrcod(svrcod);
1054: if (secchkcd == CodePoint.SECCHKCD_00) {
1055: return;
1056: }
1057: agent_.accumulateReadException(mapSecchkcd(secchkcd));
1058: }
1059:
1060: void rdbAccessed(int svrcod, String prdid, boolean crrtknReceived,
1061: byte[] crrtkn) {
1062: if (crrtknReceived) {
1063: crrtkn_ = crrtkn;
1064: }
1065:
1066: netAgent_.setSvrcod(svrcod);
1067: productID_ = prdid;
1068: }
1069:
1070: //-------------------Abstract object factories--------------------------------
1071:
1072: protected org.apache.derby.client.am.Agent newAgent_(
1073: org.apache.derby.client.am.LogWriter logWriter,
1074: int loginTimeout, String serverName, int portNumber)
1075: throws SqlException {
1076: return new NetAgent(this , (NetLogWriter) logWriter,
1077: loginTimeout, serverName, portNumber);
1078: }
1079:
1080: protected Statement newStatement_(int type, int concurrency,
1081: int holdability) throws SqlException {
1082: return new NetStatement(netAgent_, this , type, concurrency,
1083: holdability).statement_;
1084: }
1085:
1086: protected void resetStatement_(Statement statement, int type,
1087: int concurrency, int holdability) throws SqlException {
1088: ((NetStatement) statement.materialStatement_)
1089: .resetNetStatement(netAgent_, this , type, concurrency,
1090: holdability);
1091: }
1092:
1093: protected PreparedStatement newPositionedUpdatePreparedStatement_(
1094: String sql, org.apache.derby.client.am.Section section)
1095: throws SqlException {
1096: //passing the pooledConnection_ object which will be used to raise
1097: //StatementEvents to the PooledConnection
1098: return new NetPreparedStatement(netAgent_, this , sql, section,
1099: pooledConnection_).preparedStatement_;
1100: }
1101:
1102: protected PreparedStatement newPreparedStatement_(String sql,
1103: int type, int concurrency, int holdability,
1104: int autoGeneratedKeys, String[] columnNames)
1105: throws SqlException {
1106:
1107: //passing the pooledConnection_ object which will be used to raise
1108: //StatementEvents to the PooledConnection
1109: return new NetPreparedStatement(netAgent_, this , sql, type,
1110: concurrency, holdability, autoGeneratedKeys,
1111: columnNames, pooledConnection_).preparedStatement_;
1112: }
1113:
1114: protected void resetPreparedStatement_(PreparedStatement ps,
1115: String sql, int resultSetType, int resultSetConcurrency,
1116: int resultSetHoldability, int autoGeneratedKeys,
1117: String[] columnNames) throws SqlException {
1118: ((NetPreparedStatement) ps.materialPreparedStatement_)
1119: .resetNetPreparedStatement(netAgent_, this , sql,
1120: resultSetType, resultSetConcurrency,
1121: resultSetHoldability, autoGeneratedKeys,
1122: columnNames);
1123: }
1124:
1125: protected CallableStatement newCallableStatement_(String sql,
1126: int type, int concurrency, int holdability)
1127: throws SqlException {
1128: //passing the pooledConnection_ object which will be used to raise
1129: //StatementEvents to the PooledConnection
1130: return new NetCallableStatement(netAgent_, this , sql, type,
1131: concurrency, holdability, pooledConnection_).callableStatement_;
1132: }
1133:
1134: protected void resetCallableStatement_(CallableStatement cs,
1135: String sql, int resultSetType, int resultSetConcurrency,
1136: int resultSetHoldability) throws SqlException {
1137: ((NetCallableStatement) cs.materialCallableStatement_)
1138: .resetNetCallableStatement(netAgent_, this , sql,
1139: resultSetType, resultSetConcurrency,
1140: resultSetHoldability);
1141: }
1142:
1143: protected DatabaseMetaData newDatabaseMetaData_() {
1144: return ClientDriver.getFactory().newNetDatabaseMetaData(
1145: netAgent_, this );
1146: }
1147:
1148: //-------------------private helper methods--------------------------------
1149:
1150: private void checkDatabaseName() throws SqlException {
1151: // netAgent_.logWriter may not be initialized yet
1152: if (databaseName_ == null) {
1153: throw new SqlException(
1154: agent_.logWriter_,
1155: new ClientMessageId(
1156: SQLState.CONNECT_REQUIRED_PROPERTY_NOT_SET),
1157: "databaseName");
1158: }
1159: }
1160:
1161: private void checkUserLength(String user) throws SqlException {
1162: int usridLength = user.length();
1163: if ((usridLength == 0)
1164: || (usridLength > NetConfiguration.USRID_MAXSIZE)) {
1165: throw new SqlException(
1166: netAgent_.logWriter_,
1167: new ClientMessageId(
1168: SQLState.CONNECT_USERID_LENGTH_OUT_OF_RANGE),
1169: new Integer(usridLength), new Integer(
1170: NetConfiguration.USRID_MAXSIZE));
1171: }
1172: }
1173:
1174: private void checkPasswordLength(String password)
1175: throws SqlException {
1176: int passwordLength = password.length();
1177: if ((passwordLength == 0)
1178: || (passwordLength > NetConfiguration.PASSWORD_MAXSIZE)) {
1179: throw new SqlException(
1180: netAgent_.logWriter_,
1181: new ClientMessageId(
1182: SQLState.CONNECT_PASSWORD_LENGTH_OUT_OF_RANGE),
1183: new Integer(passwordLength), new Integer(
1184: NetConfiguration.PASSWORD_MAXSIZE));
1185: }
1186: }
1187:
1188: private void checkUser(String user) throws SqlException {
1189: if (user == null) {
1190: throw new SqlException(netAgent_.logWriter_,
1191: new ClientMessageId(SQLState.CONNECT_USERID_ISNULL));
1192: }
1193: checkUserLength(user);
1194: }
1195:
1196: private void checkUserPassword(String user, String password)
1197: throws SqlException {
1198: checkUser(user);
1199: if (password == null) {
1200: throw new SqlException(netAgent_.logWriter_,
1201: new ClientMessageId(
1202: SQLState.CONNECT_PASSWORD_ISNULL));
1203: }
1204: checkPasswordLength(password);
1205: }
1206:
1207: // Determine if a security mechanism is supported by
1208: // the security manager used for the connection.
1209: // An exception is thrown if the security mechanism is not supported
1210: // by the secmgr.
1211: private void checkSecmgrForSecmecSupport(int securityMechanism)
1212: throws SqlException {
1213: boolean secmecSupported = false;
1214: int[] supportedSecmecs = null;
1215:
1216: // Point to a list (array) of supported security mechanisms.
1217: supportedSecmecs = NetConfiguration.SECMGR_SECMECS;
1218:
1219: // check to see if the security mechanism is on the supported list.
1220: for (int i = 0; (i < supportedSecmecs.length)
1221: && (!secmecSupported); i++) {
1222: if (supportedSecmecs[i] == securityMechanism) {
1223: secmecSupported = true;
1224: }
1225: }
1226:
1227: // throw an exception if not supported (not on list).
1228: if (!secmecSupported) {
1229: throw new SqlException(
1230: agent_.logWriter_,
1231: new ClientMessageId(SQLState.SECMECH_NOT_SUPPORTED),
1232: new Integer(securityMechanism));
1233: }
1234: }
1235:
1236: // If secchkcd is not 0, map to SqlException
1237: // according to the secchkcd received.
1238: private SqlException mapSecchkcd(int secchkcd) {
1239: if (secchkcd == CodePoint.SECCHKCD_00) {
1240: return null;
1241: }
1242:
1243: // the net driver will not support new password at this time.
1244: // Here is the message for -30082 (STATE "08001"):
1245: // Attempt to establish connection failed with security
1246: // reason {0} {1} + reason-code + reason-string.
1247: switch (secchkcd) {
1248: case CodePoint.SECCHKCD_01: // ERROR SVRCOD
1249: return new SqlException(
1250: agent_.logWriter_,
1251: new ClientMessageId(
1252: SQLState.NET_CONNECT_AUTH_FAILED),
1253: msgutil
1254: .getTextMessage(MessageId.CONN_SECMECH_NOT_SUPPORTED));
1255: case CodePoint.SECCHKCD_10: // ERROR SVRCOD
1256: return new SqlException(
1257: agent_.logWriter_,
1258: new ClientMessageId(
1259: SQLState.NET_CONNECT_AUTH_FAILED),
1260: msgutil
1261: .getTextMessage(MessageId.CONN_PASSWORD_MISSING));
1262: case CodePoint.SECCHKCD_12: // ERROR SVRCOD
1263: return new SqlException(
1264: agent_.logWriter_,
1265: new ClientMessageId(
1266: SQLState.NET_CONNECT_AUTH_FAILED),
1267: msgutil
1268: .getTextMessage(MessageId.CONN_USERID_MISSING));
1269: case CodePoint.SECCHKCD_13: // ERROR SVRCOD
1270: return new SqlException(
1271: agent_.logWriter_,
1272: new ClientMessageId(
1273: SQLState.NET_CONNECT_AUTH_FAILED),
1274: msgutil
1275: .getTextMessage(MessageId.CONN_USERID_OR_PASSWORD_INVALID));
1276: case CodePoint.SECCHKCD_14: // ERROR SVRCOD
1277: return new SqlException(
1278: agent_.logWriter_,
1279: new ClientMessageId(
1280: SQLState.NET_CONNECT_AUTH_FAILED),
1281: msgutil
1282: .getTextMessage(MessageId.CONN_USERID_REVOKED));
1283: case CodePoint.SECCHKCD_15: // ERROR SVRCOD
1284: return new SqlException(
1285: agent_.logWriter_,
1286: new ClientMessageId(
1287: SQLState.NET_CONNECT_AUTH_FAILED),
1288: msgutil
1289: .getTextMessage(MessageId.CONN_NEW_PASSWORD_INVALID));
1290: case CodePoint.SECCHKCD_0A: // ERROR SVRCOD
1291: return new SqlException(
1292: agent_.logWriter_,
1293: new ClientMessageId(
1294: SQLState.NET_CONNECT_AUTH_FAILED),
1295: msgutil
1296: .getTextMessage(MessageId.CONN_SECSVC_NONRETRYABLE_ERR));
1297: case CodePoint.SECCHKCD_0B: // ERROR SVRCOD
1298: return new SqlException(
1299: agent_.logWriter_,
1300: new ClientMessageId(
1301: SQLState.NET_CONNECT_AUTH_FAILED),
1302: msgutil
1303: .getTextMessage(MessageId.CONN_SECTKN_MISSING_OR_INVALID));
1304: case CodePoint.SECCHKCD_0E: // ERROR SVRCOD
1305: return new SqlException(
1306: agent_.logWriter_,
1307: new ClientMessageId(
1308: SQLState.NET_CONNECT_AUTH_FAILED),
1309: msgutil
1310: .getTextMessage(MessageId.CONN_PASSWORD_EXPIRED));
1311: case CodePoint.SECCHKCD_0F: // ERROR SVRCOD
1312: return new SqlException(
1313: agent_.logWriter_,
1314: new ClientMessageId(
1315: SQLState.NET_CONNECT_AUTH_FAILED),
1316: msgutil
1317: .getTextMessage(MessageId.CONN_USERID_OR_PASSWORD_INVALID));
1318: default: // ERROR SVRCOD
1319: return new SqlException(
1320: agent_.logWriter_,
1321: new ClientMessageId(
1322: SQLState.NET_CONNECT_AUTH_FAILED),
1323: msgutil
1324: .getTextMessage(MessageId.CONN_NOT_SPECIFIED));
1325: }
1326: }
1327:
1328: // Construct the correlation token.
1329: // The crrtkn has the following format.
1330: //
1331: // <Almost IP address>.<local port number><current time in millis>
1332: // | | | || |
1333: // +----+--------------+ +-----+---------++---------+--------+
1334: // | | |
1335: // 8 bytes 4 bytes 6 bytes
1336: // Total lengtho of 19 bytes.
1337: //
1338: // 1 char for each 1/2 byte in the IP address.
1339: // If the first character of the <IP address> or <port number>
1340: // starts with '0' thru '9', it will be mapped to 'G' thru 'P'.
1341: // Reason for mapping the IP address is in order to use the crrtkn as the LUWID when using SNA in a hop site.
1342: protected void constructCrrtkn() throws SqlException {
1343: byte[] localAddressBytes = null;
1344: long time = 0;
1345: int num = 0;
1346: int halfByte = 0;
1347: int i = 0;
1348: int j = 0;
1349:
1350: // allocate the crrtkn array.
1351: if (crrtkn_ == null) {
1352: crrtkn_ = new byte[19];
1353: } else {
1354: java.util.Arrays.fill(crrtkn_, (byte) 0);
1355: }
1356:
1357: localAddressBytes = netAgent_.socket_.getLocalAddress()
1358: .getAddress();
1359:
1360: // IP addresses are returned in a 4 byte array.
1361: // Obtain the character representation of each half byte.
1362: for (i = 0, j = 0; i < 4; i++, j += 2) {
1363:
1364: // since a byte is signed in java, convert any negative
1365: // numbers to positive before shifting.
1366: num = localAddressBytes[i] < 0 ? localAddressBytes[i] + 256
1367: : localAddressBytes[i];
1368: halfByte = (num >> 4) & 0x0f;
1369:
1370: // map 0 to G
1371: // The first digit of the IP address is is replaced by
1372: // the characters 'G' thro 'P'(in order to use the crrtkn as the LUWID when using
1373: // SNA in a hop site). For example, 0 is mapped to G, 1 is mapped H,etc.
1374: if (i == 0) {
1375: crrtkn_[j] = netAgent_.sourceCcsidManager_.numToSnaRequiredCrrtknChar_[halfByte];
1376: } else {
1377: crrtkn_[j] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
1378: }
1379:
1380: halfByte = (num) & 0x0f;
1381: crrtkn_[j + 1] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
1382: }
1383:
1384: // fill the '.' in between the IP address and the port number
1385: crrtkn_[8] = netAgent_.sourceCcsidManager_.dot_;
1386:
1387: // Port numbers have values which fit in 2 unsigned bytes.
1388: // Java returns port numbers in an int so the value is not negative.
1389: // Get the character representation by converting the
1390: // 4 low order half bytes to the character representation.
1391: num = netAgent_.socket_.getLocalPort();
1392:
1393: halfByte = (num >> 12) & 0x0f;
1394: crrtkn_[9] = netAgent_.sourceCcsidManager_.numToSnaRequiredCrrtknChar_[halfByte];
1395: halfByte = (num >> 8) & 0x0f;
1396: crrtkn_[10] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
1397: halfByte = (num >> 4) & 0x0f;
1398: crrtkn_[11] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
1399: halfByte = (num) & 0x0f;
1400: crrtkn_[12] = netAgent_.sourceCcsidManager_.numToCharRepresentation_[halfByte];
1401:
1402: // The final part of CRRTKN is a 6 byte binary number that makes the
1403: // crrtkn unique, which is usually the time stamp/process id.
1404: // If the new time stamp is the
1405: // same as one of the already created ones, then recreate the time stamp.
1406: time = System.currentTimeMillis();
1407:
1408: for (i = 0; i < 6; i++) {
1409: // store 6 bytes of 8 byte time into crrtkn
1410: crrtkn_[i + 13] = (byte) (time >>> (40 - (i * 8)));
1411: }
1412: }
1413:
1414: private void constructExtnam() throws SqlException {
1415: extnam_ = "derbydnc"
1416: + java.lang.Thread.currentThread().getName();
1417: }
1418:
1419: private void constructPrddta() throws SqlException {
1420: int prddtaLen = 1;
1421:
1422: if (prddta_ == null) {
1423: prddta_ = new byte[NetConfiguration.PRDDTA_MAXSIZE];
1424: } else {
1425: java.util.Arrays.fill(prddta_, (byte) 0);
1426: }
1427:
1428: for (int i = 0; i < NetConfiguration.PRDDTA_ACCT_SUFFIX_LEN_BYTE; i++) {
1429: prddta_[i] = netAgent_.sourceCcsidManager_.space_;
1430: }
1431:
1432: prddtaLen = netAgent_.sourceCcsidManager_.convertFromUCS2(
1433: NetConfiguration.PRDID, prddta_, prddtaLen, netAgent_);
1434:
1435: prddtaLen = netAgent_.sourceCcsidManager_.convertFromUCS2(
1436: NetConfiguration.PRDDTA_PLATFORM_ID, prddta_,
1437: prddtaLen, netAgent_);
1438:
1439: int extnamTruncateLength = Utils.min(extnam_.length(),
1440: NetConfiguration.PRDDTA_APPL_ID_FIXED_LEN);
1441: netAgent_.sourceCcsidManager_.convertFromUCS2(extnam_
1442: .substring(0, extnamTruncateLength), prddta_,
1443: prddtaLen, netAgent_);
1444: prddtaLen += NetConfiguration.PRDDTA_APPL_ID_FIXED_LEN;
1445:
1446: if (user_ != null) {
1447: int userTruncateLength = Utils.min(user_.length(),
1448: NetConfiguration.PRDDTA_USER_ID_FIXED_LEN);
1449: netAgent_.sourceCcsidManager_.convertFromUCS2(user_
1450: .substring(0, userTruncateLength), prddta_,
1451: prddtaLen, netAgent_);
1452: }
1453:
1454: prddtaLen += NetConfiguration.PRDDTA_USER_ID_FIXED_LEN;
1455:
1456: prddta_[NetConfiguration.PRDDTA_ACCT_SUFFIX_LEN_BYTE] = 0;
1457: prddtaLen++;
1458: // the length byte value does not include itself.
1459: prddta_[NetConfiguration.PRDDTA_LEN_BYTE] = (byte) (prddtaLen - 1);
1460: }
1461:
1462: private void initializePublicKeyForEncryption() throws SqlException {
1463: if (encryptionManager_ == null) {
1464: encryptionManager_ = new EncryptionManager(agent_);
1465: }
1466: publicKey_ = encryptionManager_.obtainPublicKey();
1467: }
1468:
1469: // SECMEC_USRSSBPWD security mechanism - Generate a source (client) seed
1470: // to send to the target (application) server.
1471: private void initializeClientSeed() throws SqlException {
1472: if (encryptionManager_ == null) {
1473: encryptionManager_ = new EncryptionManager(agent_,
1474: EncryptionManager.SHA_1_DIGEST_ALGORITHM);
1475: }
1476: sourceSeed_ = encryptionManager_.generateSeed();
1477: }
1478:
1479: private byte[] encryptedPasswordForUSRENCPWD(String password)
1480: throws SqlException {
1481: return encryptionManager_.encryptData(
1482: netAgent_.sourceCcsidManager_.convertFromUCS2(password,
1483: netAgent_), NetConfiguration.SECMEC_USRENCPWD,
1484: netAgent_.sourceCcsidManager_.convertFromUCS2(user_,
1485: netAgent_), targetPublicKey_);
1486: }
1487:
1488: private byte[] encryptedUseridForEUSRIDPWD() throws SqlException {
1489: return encryptionManager_.encryptData(
1490: netAgent_.sourceCcsidManager_.convertFromUCS2(user_,
1491: netAgent_), NetConfiguration.SECMEC_EUSRIDPWD,
1492: targetPublicKey_, targetPublicKey_);
1493: }
1494:
1495: private byte[] encryptedPasswordForEUSRIDPWD(String password)
1496: throws SqlException {
1497: return encryptionManager_.encryptData(
1498: netAgent_.sourceCcsidManager_.convertFromUCS2(password,
1499: netAgent_), NetConfiguration.SECMEC_EUSRIDPWD,
1500: targetPublicKey_, targetPublicKey_);
1501: }
1502:
1503: private byte[] passwordSubstituteForUSRSSBPWD(String password)
1504: throws SqlException {
1505: String userName = user_;
1506:
1507: // Define which userName takes precedence - If we have a dataSource
1508: // available here, it is posible that the userName has been
1509: // overriden by some defined as part of the connection attributes
1510: // (see ClientBaseDataSource.updateDataSourceValues().
1511: // We need to use the right userName as strong password
1512: // substitution depends on the userName when the substitute
1513: // password is generated; if we were not using the right userName
1514: // then authentication would fail when regenerating the substitute
1515: // password on the engine server side, where userName as part of the
1516: // connection attributes would get used to authenticate the user.
1517: if (dataSource_ != null) {
1518: String dataSourceUserName = dataSource_.getUser();
1519: if (!dataSourceUserName.equals("")
1520: && userName
1521: .equalsIgnoreCase(dataSource_.propertyDefault_user)
1522: && !dataSourceUserName
1523: .equalsIgnoreCase(dataSource_.propertyDefault_user)) {
1524: userName = dataSourceUserName;
1525: }
1526: }
1527: return encryptionManager_.substitutePassword(userName,
1528: password, sourceSeed_, targetSeed_);
1529: }
1530:
1531: // Methods to get the manager levels for Regression harness only.
1532: public int getSQLAM() {
1533: return netAgent_.targetSqlam_;
1534: }
1535:
1536: public int getAGENT() {
1537: return targetAgent_;
1538: }
1539:
1540: public int getCMNTCPIP() {
1541: return targetCmntcpip_;
1542: }
1543:
1544: public int getRDB() {
1545: return targetRdb_;
1546: }
1547:
1548: public int getSECMGR() {
1549: return targetSecmgr_;
1550: }
1551:
1552: public int getXAMGR() {
1553: return targetXamgr_;
1554: }
1555:
1556: public int getSYNCPTMGR() {
1557: return targetSyncptmgr_;
1558: }
1559:
1560: public int getRSYNCMGR() {
1561: return targetRsyncmgr_;
1562: }
1563:
1564: private char[] flipBits(char[] array) {
1565: for (int i = 0; i < array.length; i++) {
1566: array[i] ^= 0xff;
1567: }
1568: return array;
1569: }
1570:
1571: private void writeDeferredResetFromCache() {
1572: int length = cachedConnectBytes_.length;
1573: System.arraycopy(cachedConnectBytes_, 0,
1574: netAgent_.netConnectionRequest_.bytes_,
1575: netAgent_.netConnectionRequest_.offset_, length);
1576: netAgent_.netConnectionRequest_.offset_ += length;
1577: netAgent_.netConnectionRequest_
1578: .setDssLengthLocation(netAgent_.netConnectionRequest_.offset_);
1579: netAgent_.netConnectionRequest_.setCorrelationID(4);
1580: }
1581:
1582: public void writeCommitSubstitute_() throws SqlException {
1583: netAgent_.connectionRequest_.writeCommitSubstitute(this );
1584: }
1585:
1586: public void readCommitSubstitute_() throws SqlException {
1587: netAgent_.connectionReply_.readCommitSubstitute(this );
1588: }
1589:
1590: public void writeLocalXAStart_() throws SqlException {
1591: netAgent_.connectionRequest_.writeLocalXAStart(this );
1592: }
1593:
1594: public void readLocalXAStart_() throws SqlException {
1595: netAgent_.connectionReply_.readLocalXAStart(this );
1596: }
1597:
1598: public void writeLocalXACommit_() throws SqlException {
1599: netAgent_.connectionRequest_.writeLocalXACommit(this );
1600: }
1601:
1602: public void readLocalXACommit_() throws SqlException {
1603: netAgent_.connectionReply_.readLocalXACommit(this );
1604: }
1605:
1606: public void writeLocalXARollback_() throws SqlException {
1607: netAgent_.connectionRequest_.writeLocalXARollback(this );
1608: }
1609:
1610: public void readLocalXARollback_() throws SqlException {
1611: netAgent_.connectionReply_.readLocalXARollback(this );
1612: }
1613:
1614: public void writeLocalCommit_() throws SqlException {
1615: netAgent_.connectionRequest_.writeLocalCommit(this );
1616: }
1617:
1618: public void readLocalCommit_() throws SqlException {
1619: netAgent_.connectionReply_.readLocalCommit(this );
1620: }
1621:
1622: public void writeLocalRollback_() throws SqlException {
1623: netAgent_.connectionRequest_.writeLocalRollback(this );
1624: }
1625:
1626: public void readLocalRollback_() throws SqlException {
1627: netAgent_.connectionReply_.readLocalRollback(this );
1628: }
1629:
1630: protected void markClosed_() {
1631: }
1632:
1633: protected boolean isGlobalPending_() {
1634: return false;
1635: }
1636:
1637: protected boolean doCloseStatementsOnClose_() {
1638: return true;
1639: }
1640:
1641: protected boolean allowCloseInUOW_() {
1642: return false;
1643: }
1644:
1645: // Driver-specific determination if local COMMIT/ROLLBACK is allowed;
1646: // Allow local COMMIT/ROLLBACK only if we are not in an XA transaction
1647: protected boolean allowLocalCommitRollback_()
1648: throws org.apache.derby.client.am.SqlException {
1649:
1650: if (getXAState() == XA_T0_NOT_ASSOCIATED) {
1651: return true;
1652: }
1653: return false;
1654: }
1655:
1656: public void setInputStream(java.io.InputStream inputStream) {
1657: netAgent_.setInputStream(inputStream);
1658: }
1659:
1660: public void setOutputStream(java.io.OutputStream outputStream) {
1661: netAgent_.setOutputStream(outputStream);
1662: }
1663:
1664: public java.io.InputStream getInputStream() {
1665: return netAgent_.getInputStream();
1666: }
1667:
1668: public java.io.OutputStream getOutputStream() {
1669: return netAgent_.getOutputStream();
1670: }
1671:
1672: public void writeTransactionStart(Statement statement)
1673: throws SqlException {
1674: }
1675:
1676: public void readTransactionStart() throws SqlException {
1677: super .readTransactionStart();
1678: }
1679:
1680: public void setIndoubtTransactions(
1681: java.util.Hashtable indoubtTransactions) {
1682: if (isXAConnection_) {
1683: if (indoubtTransactions_ != null) {
1684: indoubtTransactions_.clear();
1685: }
1686: indoubtTransactions_ = indoubtTransactions;
1687: }
1688: }
1689:
1690: protected void setReadOnlyTransactionFlag(boolean flag) {
1691: readOnlyTransaction_ = flag;
1692: }
1693:
1694: public org.apache.derby.client.am.SectionManager newSectionManager(
1695: String collection, org.apache.derby.client.am.Agent agent,
1696: String databaseName) {
1697: return new org.apache.derby.client.am.SectionManager(
1698: collection, agent, databaseName);
1699: }
1700:
1701: protected int getSocketAndInputOutputStreams(String server, int port) {
1702: try {
1703: netAgent_.socket_ = (java.net.Socket) java.security.AccessController
1704: .doPrivileged(new OpenSocketAction(server, port));
1705: } catch (java.security.PrivilegedActionException e) {
1706: Exception openSocketException = e.getException();
1707: if (netAgent_.loggingEnabled()) {
1708: netAgent_.logWriter_.tracepoint("[net]", 101,
1709: "Client Re-route: "
1710: + openSocketException.getClass()
1711: .getName() + " : "
1712: + openSocketException.getMessage());
1713: }
1714: return -1;
1715: }
1716:
1717: try {
1718: netAgent_.rawSocketOutputStream_ = netAgent_.socket_
1719: .getOutputStream();
1720: netAgent_.rawSocketInputStream_ = netAgent_.socket_
1721: .getInputStream();
1722: } catch (java.io.IOException e) {
1723: if (netAgent_.loggingEnabled()) {
1724: netAgent_.logWriter_.tracepoint("[net]", 103,
1725: "Client Re-route: java.io.IOException "
1726: + e.getMessage());
1727: }
1728: try {
1729: netAgent_.socket_.close();
1730: } catch (java.io.IOException doNothing) {
1731: }
1732: return -1;
1733: }
1734: return 0;
1735: }
1736:
1737: protected int checkAlternateServerHasEqualOrHigherProductLevel(
1738: ProductLevel orgLvl, int orgServerType) {
1739: if (orgLvl == null && orgServerType == 0) {
1740: return 0;
1741: }
1742: ProductLevel alternateServerProductLvl = netAgent_.netConnection_.databaseMetaData_.productLevel_;
1743: boolean alternateServerIsEqualOrHigherToOriginalServer = (alternateServerProductLvl
1744: .greaterThanOrEqualTo(orgLvl.versionLevel_,
1745: orgLvl.releaseLevel_, orgLvl.modificationLevel_)) ? true
1746: : false;
1747: // write an entry to the trace
1748: if (!alternateServerIsEqualOrHigherToOriginalServer
1749: && netAgent_.loggingEnabled()) {
1750: netAgent_.logWriter_
1751: .tracepoint(
1752: "[net]",
1753: 99,
1754: "Client Re-route failed because the alternate server is on a lower product level than the origianl server.");
1755: }
1756: return (alternateServerIsEqualOrHigherToOriginalServer) ? 0
1757: : -1;
1758: }
1759:
1760: public boolean willAutoCommitGenerateFlow() {
1761: // this logic must be in sync with writeCommit() logic
1762: if (!autoCommit_) {
1763: return false;
1764: }
1765: if (!isXAConnection_) {
1766: return true;
1767: }
1768: boolean doCommit = false;
1769: int xaState = getXAState();
1770:
1771: if (xaState == XA_T0_NOT_ASSOCIATED) {
1772: doCommit = true;
1773: }
1774:
1775: return doCommit;
1776: }
1777:
1778: public int getSecurityMechanism() {
1779: return securityMechanism_;
1780: }
1781:
1782: public EncryptionManager getEncryptionManager() {
1783: return encryptionManager_;
1784: }
1785:
1786: public byte[] getTargetPublicKey() {
1787: return targetPublicKey_;
1788: }
1789:
1790: public String getProductID() {
1791: return targetSrvclsnm_;
1792: }
1793:
1794: public void doResetNow() throws SqlException {
1795: if (!resetConnectionAtFirstSql_) {
1796: return; // reset not needed
1797: }
1798: agent_.beginWriteChainOutsideUOW();
1799: agent_.flowOutsideUOW();
1800: agent_.endReadChain();
1801: }
1802:
1803: /**
1804: * @return Returns the connectionNull.
1805: */
1806: public boolean isConnectionNull() {
1807: return connectionNull;
1808: }
1809:
1810: /**
1811: * @param connectionNull The connectionNull to set.
1812: */
1813: public void setConnectionNull(boolean connectionNull) {
1814: this .connectionNull = connectionNull;
1815: }
1816:
1817: /**
1818: * Check whether the server has full support for the QRYCLSIMP
1819: * parameter in OPNQRY.
1820: *
1821: * @return true if QRYCLSIMP is fully supported
1822: */
1823: public final boolean serverSupportsQryclsimp() {
1824: NetDatabaseMetaData metadata = (NetDatabaseMetaData) databaseMetaData_;
1825: return metadata.serverSupportsQryclsimp();
1826: }
1827:
1828: /**
1829: * Returns if a transaction is in process
1830: * @return open
1831: */
1832: public boolean isOpen() {
1833: return open_;
1834: }
1835:
1836: /**
1837: * closes underlying connection and associated resource.
1838: */
1839: synchronized public void close() throws SQLException {
1840: // call super.close*() to do the close*
1841: super .close();
1842: if (!isXAConnection_)
1843: return;
1844: if (isOpen()) {
1845: return; // still open, return
1846: }
1847: if (xares_ != null) {
1848: xares_.removeXaresFromSameRMchain();
1849: }
1850: }
1851:
1852: /**
1853: * closes underlying connection and associated resource.
1854: */
1855: synchronized public void closeX() throws SQLException {
1856: // call super.close*() to do the close*
1857: super .closeX();
1858: if (!isXAConnection_)
1859: return;
1860: if (isOpen()) {
1861: return; // still open, return
1862: }
1863: if (xares_ != null) {
1864: xares_.removeXaresFromSameRMchain();
1865: }
1866: }
1867:
1868: /**
1869: * Invalidates connection but keeps socket open.
1870: */
1871: synchronized public void closeForReuse() throws SqlException {
1872: // call super.close*() to do the close*
1873: super .closeForReuse();
1874: if (!isXAConnection_)
1875: return;
1876: if (isOpen()) {
1877: return; // still open, return
1878: }
1879: if (xares_ != null) {
1880: xares_.removeXaresFromSameRMchain();
1881: }
1882: }
1883:
1884: /**
1885: * closes resources connection will be not available
1886: * for reuse.
1887: */
1888: synchronized public void closeResources() throws SQLException {
1889: // call super.close*() to do the close*
1890: super .closeResources();
1891: if (!isXAConnection_)
1892: return;
1893:
1894: if (isOpen()) {
1895: return; // still open, return
1896: }
1897: if (xares_ != null) {
1898: xares_.removeXaresFromSameRMchain();
1899: }
1900: }
1901:
1902: /**
1903: * Invokes write commit on NetXAConnection
1904: */
1905: protected void writeXACommit_() throws SqlException {
1906: xares_.netXAConn_.writeCommit();
1907: }
1908:
1909: /**
1910: * Invokes readCommit on NetXAConnection
1911: */
1912: protected void readXACommit_() throws SqlException {
1913: xares_.netXAConn_.readCommit();
1914: }
1915:
1916: /**
1917: * Invokes writeRollback on NetXAConnection
1918: */
1919: protected void writeXARollback_() throws SqlException {
1920: xares_.netXAConn_.writeRollback();
1921: }
1922:
1923: /**
1924: * Invokes writeRollback on NetXAConnection
1925: */
1926: protected void readXARollback_() throws SqlException {
1927: xares_.netXAConn_.readRollback();
1928: }
1929:
1930: protected void writeXATransactionStart(Statement statement)
1931: throws SqlException {
1932: xares_.netXAConn_.writeTransactionStart(statement);
1933: }
1934: }
|