📄 drdaconnthread.java
字号:
default: codePointNotSupported(codePoint); } // Set the correct chaining bits for whatever // reply DSS(es) we just wrote. If we've reached // the end of the chain, this method will send // the DSS(es) across. finalizeChain(); } while (reader.isChainedWithSameID() || reader.isChainedWithDiffID()); } /** * If there's a severe error in the DDM chain, and if the header indicates * "terminate chain on error", we stop processing further commands in the chain * nor do we send any reply for them. In accordance to this, a SQLERRRM message * indicating the severe error must have been sent! (otherwise application requestor, * such as JCC, would not terminate the receiving of chain replies.) * * Each DRDA command is processed independently. DRDA defines no interdependencies * across chained commands. A command is processed the same when received within * a set of chained commands or received separately. The chaining was originally * defined as a way to save network costs. * * @param e the SQLException raised * @exception DRDAProtocolException */ private void errorInChain(SQLException e) throws DRDAProtocolException { if (reader.terminateChainOnErr() && (getExceptionSeverity(e) > CodePoint.SVRCOD_ERROR)) { if (SanityManager.DEBUG) trace("terminating the chain on error..."); skipRemainder(false); } } /** * Exchange server attributes with application requester * * @exception DRDAProtocolException */ private void exchangeServerAttributes() throws DRDAProtocolException { int codePoint; correlationID = reader.readDssHeader(); if (SanityManager.DEBUG) { if (correlationID == 0) { SanityManager.THROWASSERT( "Unexpected value for correlationId = " + correlationID); } } codePoint = reader.readLengthAndCodePoint(); // The first code point in the exchange of attributes must be EXCSAT if (codePoint != CodePoint.EXCSAT) { //Throw PRCCNVRM throw new DRDAProtocolException(DRDAProtocolException.DRDA_Proto_PRCCNVRM, this, codePoint, CodePoint.PRCCNVCD_EXCSAT_FIRST_AFTER_CONN); } parseEXCSAT(); writeEXCSATRD(); finalizeChain(); session.setState(session.ATTEXC); } private boolean parseDRDAConnection() throws DRDAProtocolException { int codePoint; boolean sessionOK = true; int securityCheckCode = parseSECCHK(); if (SanityManager.DEBUG) trace("*** SECCHKRM securityCheckCode is: "+securityCheckCode); writeSECCHKRM(securityCheckCode); //at this point if the security check failed, we're done, the session failed if (securityCheckCode != 0) { return false; } correlationID = reader.readDssHeader(); codePoint = reader.readLengthAndCodePoint(); verifyRequiredObject(codePoint,CodePoint.ACCRDB); int svrcod = parseACCRDB(); //If network server gets a null connection form InternalDriver, reply with //RDBAFLRM and SQLCARD with null SQLException if(database.getConnection() == null && databaseAccessException == null){ writeRDBfailure(CodePoint.RDBAFLRM); return false; } //if earlier we couldn't access the database if (databaseAccessException != null) { //if the Database was not found we will try DS int failureType = getRdbAccessErrorCodePoint(); if (failureType == CodePoint.RDBNFNRM || failureType == CodePoint.RDBATHRM) { writeRDBfailure(failureType); } else { writeRDBfailure(CodePoint.RDBAFLRM); } return false; } else if (database.accessCount > 1 ) // already in conversation with database { writeRDBfailure(CodePoint.RDBACCRM); return false; } else // everything is fine writeACCRDBRM(svrcod); // compare this application requester with previously stored // application requesters and if we have already seen this one // use stored application requester session.appRequester = server.getAppRequester(appRequester); return sessionOK; } /** * Write RDB Failure * * Instance Variables * SVRCOD - Severity Code - required * RDBNAM - Relational Database name - required * SRVDGN - Server Diagnostics - optional (not sent for now) * * @param codePoint codepoint of failure */ private void writeRDBfailure(int codePoint) throws DRDAProtocolException { writer.createDssReply(); writer.startDdm(codePoint); writer.writeScalar2Bytes(CodePoint.SVRCOD, CodePoint.SVRCOD_ERROR); writeRDBNAM(database.dbName); writer.endDdmAndDss(); switch(codePoint){ case CodePoint.RDBAFLRM: //RDBAFLRM requires TYPDEFNAM and TYPDEFOVR writer.createDssObject(); writer.writeScalarString(CodePoint.TYPDEFNAM, CodePoint.TYPDEFNAM_QTDSQLASC); writeTYPDEFOVR(); writer.endDss(); case CodePoint.RDBNFNRM: case CodePoint.RDBATHRM: writeSQLCARD(databaseAccessException,CodePoint.SVRCOD_ERROR,0,0); case CodePoint.RDBACCRM: //Ignore anything that was chained to the ACCRDB. skipRemainder(false); // Finalize chain state for whatever we wrote in // response to ACCRDB. finalizeChain(); break; } } /* Check the database access exception and return the appropriate error codepoint. RDBNFNRM - Database not found RDBATHRM - Not Authorized RDBAFLRM - Access failure @return RDB Access codepoint */ private int getRdbAccessErrorCodePoint() { String sqlState = databaseAccessException.getSQLState(); if (sqlState.regionMatches(0,SQLState.DATABASE_NOT_FOUND,0,5) | sqlState.regionMatches(0,SQLState.NO_SUCH_DATABASE,0,5)) return CodePoint.RDBNFNRM; else if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5) || sqlState.regionMatches(0,SQLState.AUTH_INVALID_USER_NAME,0,5)) return CodePoint.RDBATHRM; else return CodePoint.RDBAFLRM; } /** * Verify userId and password * * Username and password is verified by making a connection to the * database * * @return security check code, 0 is O.K. * @exception DRDAProtocolException */ private int verifyUserIdPassword() throws DRDAProtocolException { databaseAccessException = null; int retSecChkCode = 0; String realName = database.dbName; //first strip off properties int endOfName = realName.indexOf(';'); if (endOfName != -1) realName = realName.substring(0, endOfName); retSecChkCode = getConnFromDatabaseName(); return retSecChkCode; } /** * Get connection from a database name * * Username and password is verified by making a connection to the * database * * @return security check code, 0 is O.K. * @exception DRDAProtocolException */ private int getConnFromDatabaseName() throws DRDAProtocolException { Properties p = new Properties(); databaseAccessException = null; //if we haven't got the correlation token yet, use session number for drdaID if (session.drdaID == null) session.drdaID = leftBrace + session.connNum + rightBrace; p.put(Attribute.DRDAID_ATTR, session.drdaID); try { database.makeConnection(p); } catch (SQLException se) { String sqlState = se.getSQLState(); // need to set the security check code based on the reason the connection // was denied, Cloudscape doesn't say whether the userid or password caused // the problem, so we will just return userid invalid databaseAccessException = se; for (; se != null; se = se.getNextException()) { if (SanityManager.DEBUG) trace(se.getMessage()); println2Log(database.dbName, session.drdaID, se.getMessage()); } if (sqlState.regionMatches(0,SQLState.LOGIN_FAILED,0,5)) return CodePoint.SECCHKCD_USERIDINVALID; return 0; } catch (Exception e) { // If cloudscape has shut down for some reason, // we will send an agent error and then try to // get the driver loaded again. We have to get // rid of the client first in case they are holding // the DriverManager lock. println2Log(database.dbName, session.drdaID, "Driver not loaded" + e.getMessage()); try { agentError("Driver not loaded"); } catch (DRDAProtocolException dpe) { // Retry starting the server before rethrowing // the protocol exception. Then hopfully all // will be well when they try again. try { server.startNetworkServer(); } catch (Exception re) { println2Log(database.dbName, session.drdaID, "Failed attempt to reload driver " +re.getMessage() ); } throw dpe; } } // Everything worked so log connection to the database. if (getLogConnections()) println2Log(database.dbName, session.drdaID, "Cloudscape Network Server connected to database " + database.dbName); return 0; } /** * Parses EXCSAT (Exchange Server Attributes) * Instance variables * EXTNAM(External Name) - optional * MGRLVLLS(Manager Levels) - optional * SPVNAM(Supervisor Name) - optional * SRVCLSNM(Server Class Name) - optional * SRVNAM(Server Name) - optional, ignorable * SRVRLSLV(Server Product Release Level) - optional, ignorable * * @exception DRDAProtocolException */ private void parseEXCSAT() throws DRDAProtocolException { int codePoint; String strVal; // There are three kinds of EXCSAT's we might get. // 1) Initial Exchange attributes. // For this we need to initialize the apprequester. // Session state is set to ATTEXC and then the AR must // follow up with ACCSEC and SECCHK to get the connection. // 2) Send of EXCSAT as ping or mangager level adjustment. // (see parseEXCSAT2()) // For this we just ignore the EXCSAT objects that // are already set. // 3) Send of EXCSAT for connection reset. (see parseEXCSAT2()) // This is treated just like ping and will be followed up // by an ACCSEC request if in fact it is a connection reset. // If we have already exchanged attributes once just // process any new manager levels and return (case 2 and 3 above) if (appRequester != null) { parseEXCSAT2(); return; } // set up a new Application Requester to store information about the // application requester for this session appRequester = new AppRequester(); reader.markCollection(); codePoint = reader.getCodePoint(); while (codePoint != -1) { switch (codePoint) { // optional case CodePoint.EXTNAM: appRequester.extnam = reader.readString(); if (SanityManager.DEBUG) trace("extName = " + appRequester.extnam); if (appRequester.extnam.length() > CodePoint.MAX_NAME) tooBig(CodePoint.EXTNAM); break; // optional case CodePoint.MGRLVLLS: parseMGRLVLLS(1); break; // optional case CodePoint.SPVNAM: appRequester.spvnam = reader.readString(); // This is specified as a null parameter so length should // be zero if (appRequester.spvnam != null) badObjectLength(CodePoint.SPVNAM); break; // optional case CodePoint.SRVNAM: appRequester.srvnam = reader.readString(); if (SanityManager.DEBUG) trace("serverName = " + appRequester.srvnam); if (appRequester.srvnam.length() > CodePoint.MAX_NAME) tooBig(CodePoint.SRVNAM); break; // optional case CodePoint.SRVRLSLV: appRequester.srvrlslv = reader.readString(); if (SanityManager.DEBUG) trace("serverlslv = " + appRequester.srvrlslv); if (appRequester.srvrlslv.length() > CodePoint.MAX_NAME) tooBig(CodePoint.SRVRLSLV); break; // optional case CodePoint.SRVCLSNM: appRequester.srvclsnm = reader.readString(); if (SanityManager.DEBUG) trace("serverClassName = " + appRequester.srvclsnm); if (appRequester.srvclsnm.length() > CodePoint.MAX_NAME) tooBig(CodePoint.SRVCLSNM); break; default: invalidCodePoint(codePoint); } codePoint = reader.getCodePoint(); } } /** * Parses EXCSAT2 (Exchange Server Attributes) * Instance variables * EXTNAM(External Name) - optional * MGRLVLLS(Manager Levels) - optional * SPVNAM(Supervisor Name) - optional * SRVCLSNM(Server Class Name) - optional * SRVNAM(Server Name) - optional, ignorable * SRVRLSLV(Server Product Release Level) - optional, ignorable * * @exception DRDAProtocolException * * This parses a second occurrence of an EXCSAT command * The target must ignore the values for extnam, srvclsnm, srvnam and srvrlslv. * I am also going to ignore spvnam since it should be null anyway. * Only new managers can be added. */ private void parseEXCSAT2() throws DRDAProtocolException { int codePoint; reader.markCollection(); codePoint = reader.getCodePoint(); while (codePoint != -1) { switch (codePoint) { // optional case CodePoint.EXTNAM: case CodePoint.SRVNAM: case CodePoint.SRVRLSLV: case CodePoint.SRVCLSNM: case CodePoint.SPVNAM: reader.skipBytes(); break; // optional case CodePoint.MGRLVLLS: parseMGRLVLLS(2); break; default: invalidCodePoint(codePoint); } codePoint = reader.getCodePoint(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -