From derby-commits-return-15123-apmail-db-derby-commits-archive=db.apache.org@db.apache.org Mon Dec 19 15:49:57 2011
Return-Path:
+ * This is a special setter for forcing this SQLChar to carry a password. + * See the discussion of passwords on DERBY-866. This zeroes the old + * character array and pokes in the new value. + *
+ */ + public void setAndZeroOldValue( char[] val ) + { + zeroRawData(); + + if ( val == null ) + { + value = null; + } + else + { + int length = val.length; + char[] localCopy = new char[ length ]; + System.arraycopy( val, 0, localCopy, 0, length ); + + copyState + ( + null, + localCopy, + length, + null, + null, + null, + null + ); + } + } + + /** + ** Zero out the wrapped char[] so that it can't be memory-sniffed. * This helps us protect passwords. See * the comment on the SQLChar( char[] ) constructor. @@ -1398,7 +1417,8 @@ readingLoop: * difference of this method from cloneValue is this method does not * objectify a stream. */ - public DataValueDescriptor cloneHolder() { + public DataValueDescriptor cloneHolder() throws StandardException + { if ((stream == null) && (_clobValue == null)) { return cloneValue(false); } @@ -1415,6 +1435,7 @@ readingLoop: /** @see DataValueDescriptor#cloneValue */ public DataValueDescriptor cloneValue(boolean forceMaterialization) + throws StandardException { try { Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLPassword.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLPassword.java?rev=1220807&view=auto ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLPassword.java (added) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLPassword.java Mon Dec 19 15:49:19 2011 @@ -0,0 +1,195 @@ +/* + + Derby - Class org.apache.derby.iapi.types.SQLPassword + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + */ + +package org.apache.derby.iapi.types; + +import java.sql.Clob; +import java.text.RuleBasedCollator; +import java.util.Arrays; + +import org.apache.derby.iapi.error.StandardException; + +import org.apache.derby.iapi.services.io.StoredFormatIds; + +import org.apache.derby.iapi.services.sanity.SanityManager; + +/** + * SQLPassword represents a VARCHAR value with UCS_BASIC collation + * which can only be used to wrap a char[]. See DERBY-866. This is a special + * internal type which should never leak outside Derby into application code. + */ +public class SQLPassword extends SQLVarchar +{ + + /* + * DataValueDescriptor interface. + * + */ + + public String getTypeName() + { + return TypeId.PASSWORD_NAME; + } + + /* + * DataValueDescriptor interface + */ + + /** @see DataValueDescriptor#cloneValue */ + public DataValueDescriptor cloneValue(boolean forceMaterialization) + throws StandardException + { + return new SQLPassword( getRawDataAndZeroIt() ); + } + + /** + * @see DataValueDescriptor#getNewNull + * + */ + public DataValueDescriptor getNewNull() + { + return new SQLPassword(); + } + + /** @see StringDataValue#getValue(RuleBasedCollator) */ + public StringDataValue getValue(RuleBasedCollator collatorForComparison) + { + // passwords are never search/sorted or ever used in a collation-sensitive context + return this; + } + + + /* + * Storable interface, implies Externalizable, TypedFormat + */ + + /** + Return my format identifier. + + @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId + */ + public int getTypeFormatId() { + return StoredFormatIds.SQL_PASSWORD_ID; + } + + /* + * constructors + */ + + public SQLPassword() + { + } + + /** + *
+ * This is a special constructor used when we need to represent a password + * as a VARCHAR (see DERBY-866). If you need a general-purpose constructor + * for char[] values and you want to re-use this constructor, make sure to + * read the comment on the SQLChar( char[] ) constructor. + *
+ */ + public SQLPassword( char[] val ) { super( val ); } + + /** + * Normalization method - this method may be called when putting + * a value into a SQLPassword, for example, when inserting into a SQLPassword + * column. See NormalizeResultSet in execution. + * + * @param desiredType The type to normalize the source column to + * @param source The value to normalize + * + * + * @exception StandardException Thrown for null into + * non-nullable column, and for + * truncation error + */ + + public void normalize( + DataTypeDescriptor desiredType, + DataValueDescriptor source) + throws StandardException + { + if ( source == null ) + { + throwLangSetMismatch("null"); + } + else if ( !(source instanceof SQLChar) ) + { + throwLangSetMismatch( source.getClass().getName() ); + } + else + { + normalize(desiredType, ((SQLChar) source).getRawDataAndZeroIt() ); + } + } + + /** The passed-in sourceValue may be zeroed out */ + protected void normalize(DataTypeDescriptor desiredType, char[] sourceValue) + throws StandardException + { + + int desiredWidth = desiredType.getMaximumWidth(); + + int sourceWidth = sourceValue.length; + + /* + ** If the input is already the right length or shorter, no normalization is + ** necessary. + */ + + char[] result = sourceValue; + + if (sourceWidth > desiredWidth) + { + result = new char[ desiredWidth ]; + System.arraycopy( sourceValue, 0, result, 0, desiredWidth ); + + // we can't count on our caller to zero out the old array + Arrays.fill( sourceValue, (char) 0 ); + } + + setAndZeroOldValue( result ); + } + + protected void setFrom(DataValueDescriptor theValue) + throws StandardException + { + if ( !(theValue instanceof SQLChar ) ) + { + throwLangSetMismatch( theValue.getClass().getName() ); + } + else + { + setAndZeroOldValue( ((SQLChar) theValue).getRawDataAndZeroIt() ); + } + } + + /* + * DataValueDescriptor interface + */ + + /* @see DataValueDescriptor#typePrecedence */ + public int typePrecedence() + { + return TypeId.PASSWORD_PRECEDENCE; + } + +} Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLPassword.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLRef.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLRef.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLRef.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLRef.java Mon Dec 19 15:49:19 2011 @@ -190,6 +190,7 @@ public class SQLRef extends DataType imp /** @see DataValueDescriptor#cloneValue */ public DataValueDescriptor cloneValue(boolean forceMaterialization) + throws StandardException { /* In order to avoid a throws clause nightmare, we only call * the constructors which do not have a throws clause. Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLVarchar.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLVarchar.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLVarchar.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLVarchar.java Mon Dec 19 15:49:19 2011 @@ -57,6 +57,7 @@ public class SQLVarchar /** @see DataValueDescriptor#cloneValue */ public DataValueDescriptor cloneValue(boolean forceMaterialization) + throws StandardException { try { Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/StringDataValue.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/StringDataValue.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/StringDataValue.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/StringDataValue.java Mon Dec 19 15:49:19 2011 @@ -195,6 +195,15 @@ public interface StringDataValue extends */ public char[] getCharArray() throws StandardException; + /** + * Gets the enclosed character array and zeroes it. Used for covering + * our tracks as we ship a password across the system. We want the + * passwords to be smudged out as soon as possible so that they + * can't be memory-sniffed. + */ + public char[] getRawDataAndZeroIt() throws StandardException; + + /** * Gets either SQLChar/SQLVarchar/SQLLongvarchar/SQLClob(base classes) or * CollatorSQLChar/CollatorSQLVarchar/CollatorSQLLongvarch/CollatorSQLClob Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/TypeId.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/TypeId.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/TypeId.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/TypeId.java Mon Dec 19 15:49:19 2011 @@ -150,6 +150,7 @@ public final class TypeId public static final String NUMERIC_NAME = "NUMERIC"; public static final String DECIMAL_NAME = "DECIMAL"; public static final String CHAR_NAME = "CHAR"; + public static final String PASSWORD_NAME = "PASSWORD"; public static final String VARCHAR_NAME = "VARCHAR"; public static final String LONGVARCHAR_NAME = "LONG VARCHAR"; public static final String DATE_NAME = "DATE"; @@ -210,6 +211,7 @@ public final class TypeId public static final int CLOB_PRECEDENCE = 14; public static final int LONGVARCHAR_PRECEDENCE = 12; public static final int VARCHAR_PRECEDENCE = 10; + public static final int PASSWORD_PRECEDENCE = 200; public static final int CHAR_PRECEDENCE = 0; /* @@ -245,6 +247,8 @@ public final class TypeId StoredFormatIds.DOUBLE_TYPE_ID, StoredFormatIds.DOUBLE_TYPE_ID_IMPL); private static final TypeId DECIMAL_ID = new TypeId(StoredFormatIds.DECIMAL_TYPE_ID, new DecimalTypeIdImpl(false)); private static final TypeId NUMERIC_ID = new TypeId(StoredFormatIds.DECIMAL_TYPE_ID, new DecimalTypeIdImpl(true)); + public static final TypeId PASSWORD_ID = create( + StoredFormatIds.PASSWORD_TYPE_ID, StoredFormatIds.PASSWORD_TYPE_ID_IMPL); private static final TypeId VARCHAR_ID = create( StoredFormatIds.VARCHAR_TYPE_ID, StoredFormatIds.VARCHAR_TYPE_ID_IMPL); private static final TypeId DATE_ID = create( @@ -641,6 +645,12 @@ public final class TypeId public static TypeId getTypeId(TypeDescriptor catalogType) { TypeDescriptorImpl tdi = (TypeDescriptorImpl) catalogType; + + if ( tdi.getTypeId().getTypeFormatId() == StoredFormatIds.PASSWORD_TYPE_ID_IMPL ) + { + return PASSWORD_ID; + } + final int jdbcType = catalogType.getJDBCTypeId(); TypeId typeId = TypeId.getBuiltInTypeId(jdbcType); if (typeId != null) @@ -675,6 +685,7 @@ public final class TypeId private boolean isLongConcatableTypeId; private boolean isNumericTypeId; private boolean isRefTypeId; + private boolean isPasswordTypeId; private boolean isStringTypeId; private boolean isFloatingPointTypeId; private boolean isRealTypeId; @@ -911,6 +922,15 @@ public final class TypeId isLOBTypeId = true; break; + case StoredFormatIds.PASSWORD_TYPE_ID: + typePrecedence = PASSWORD_PRECEDENCE; + javaTypeName = "char[]"; + maxMaxWidth = TypeId.VARCHAR_MAXWIDTH; + isStringTypeId = true; + isPasswordTypeId = true; + isConcatableTypeId = true; + break; + case StoredFormatIds.VARCHAR_TYPE_ID: typePrecedence = VARCHAR_PRECEDENCE; javaTypeName = "java.lang.String"; @@ -1028,6 +1048,16 @@ public final class TypeId } /** + * Does this TypeId represent a TypeId for a PASSWORD. + * + * @return Whether or not this TypeId represents a TypeId for a PASSWORD. + */ + public boolean isPasswordTypeId() + { + return isPasswordTypeId; + } + + /** * Does this TypeId represent a TypeId for a StringDataType. * * @return Whether or not this TypeId represents a TypeId for a StringDataType. @@ -1471,6 +1501,9 @@ public final class TypeId case StoredFormatIds.VARCHAR_TYPE_ID: return new SQLVarchar(); + case StoredFormatIds.PASSWORD_TYPE_ID: + return new SQLPassword(); + case StoredFormatIds.XML_TYPE_ID: return new XML(); Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/XML.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/XML.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/XML.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/XML.java Mon Dec 19 15:49:19 2011 @@ -163,7 +163,9 @@ public class XML * underlying source data */ private XML(SQLChar val, int xmlType, boolean seqWithAttr, - boolean materialize) { + boolean materialize) + throws StandardException + { xmlStringValue = (val == null ? null : (SQLChar)val.cloneValue(materialize)); setXType(xmlType); @@ -178,7 +180,9 @@ public class XML /** * @see DataValueDescriptor#cloneValue */ - public DataValueDescriptor cloneValue(boolean forceMaterialization) { + public DataValueDescriptor cloneValue(boolean forceMaterialization) + throws StandardException + { return new XML(xmlStringValue, getXType(), hasTopLevelAttr(), forceMaterialization); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java Mon Dec 19 15:49:19 2011 @@ -1034,24 +1034,28 @@ public abstract class EmbedPreparedState * @exception SQLException if a database-access error occurs. */ public void addBatch() throws SQLException { - checkStatus(); + checkStatus(); + + // need to synchronize to ensure that two threads + // don't both create a Vector at the same time. This + // would lead to one of the set of parameters being thrown + // away + synchronized (getConnectionSynchronization()) { + if (batchStatements == null) + batchStatements = new Vector(); - // need to synchronized to ensure that two threads - // don't both create a Vector at the same time. This - // would lead to one of the set of parameters being thrown - // away - synchronized (getConnectionSynchronization()) { - if (batchStatements == null) - batchStatements = new Vector(); - - //get a clone of the parameterValueSet and save it in the vector - //which will be used later on at the time of batch execution. - //This way we will get a copy of the current statement's parameter - //values rather than a pointer to the statement's parameter value - //set which will change with every new statement in the batch. - batchStatements.add(getParms().getClone()); - clearParameters(); - } + try { + //get a clone of the parameterValueSet and save it in the vector + //which will be used later on at the time of batch execution. + //This way we will get a copy of the current statement's parameter + //values rather than a pointer to the statement's parameter value + //set which will change with every new statement in the batch. + batchStatements.add(getParms().getClone()); + clearParameters(); + } catch (StandardException t) { + throw EmbedResultSet.noStateChangeException(t); + } + } } boolean executeBatchElement(Object batchElement) throws SQLException, StandardException { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java Mon Dec 19 15:49:19 2011 @@ -1204,7 +1204,9 @@ public class IndexStatisticsDaemonImpl * * @param ir index row (template) */ - public KeyComparator(ExecIndexRow ir) { + public KeyComparator(ExecIndexRow ir) + throws StandardException + { rowBufferArray = new DataValueDescriptor[FETCH_SIZE][]; rowBufferArray[0] = ir.getRowArray(); // 1 gets old objects. lastUniqueKey = ir.getRowArrayClone(); Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java Mon Dec 19 15:49:19 2011 @@ -421,6 +421,7 @@ final public class GenericActivationHold * @see Activation#getRowLocationTemplate */ public RowLocation getRowLocationTemplate(int itemNumber) + throws StandardException { return ac.getRowLocationTemplate(itemNumber); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameter.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameter.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameter.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameter.java Mon Dec 19 15:49:19 2011 @@ -124,6 +124,7 @@ final class GenericParameter * @return a new generic parameter. */ public GenericParameter getClone(GenericParameterValueSet pvs) + throws StandardException { GenericParameter gpClone = new GenericParameter(pvs, isReturnOutputParameter); gpClone.initialize(this.getValue().cloneValue(false), Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameterValueSet.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameterValueSet.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameterValueSet.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericParameterValueSet.java Mon Dec 19 15:49:19 2011 @@ -79,6 +79,7 @@ final class GenericParameterValueSet imp ** Construct a pvs by cloning a pvs. */ private GenericParameterValueSet(int numParms, GenericParameterValueSet pvs) + throws StandardException { this.hasReturnOutputParam = pvs.hasReturnOutputParam; this.ci = pvs.ci; @@ -326,6 +327,7 @@ final class GenericParameterValueSet imp public ParameterValueSet getClone() + throws StandardException { return(new GenericParameterValueSet(parms.length, this)); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java Mon Dec 19 15:49:19 2011 @@ -497,11 +497,11 @@ public class DD_Version implements Forma { // On ugrade from versions before 10.9, create system procedures // added in 10.9. + bootingDictionary.create_10_9_system_procedures( tc, newlyCreatedRoutines ); // On upgrade from versions before 10.9, create system catalogs // added in 10.9 - bootingDictionary.upgradeMakeCatalog( - tc, DataDictionary.SYSUSERS_CATALOG_NUM); + bootingDictionary.upgradeMakeCatalog(tc, DataDictionary.SYSUSERS_CATALOG_NUM ); } // Grant PUBLIC access to some system routines Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Mon Dec 19 15:49:19 2011 @@ -7786,6 +7786,27 @@ public final class DataDictionaryImpl } + /** + * Drop a User from the DataDictionary + * + * @param ad The AliasDescriptor to drop + * @param tc The TransactionController + * + * @exception StandardException Thrown on failure + */ + + public void dropUser( String userName, TransactionController tc ) + throws StandardException + { + TabInfoImpl ti = getNonCoreTI(SYSUSERS_CATALOG_NUM); + + /* Set up the start/stop position for the scan */ + ExecIndexRow keyRow1 = (ExecIndexRow) exFactory.getIndexableRow( 1 ); + keyRow1.setColumn( 1, new SQLVarchar( userName ) ); + + ti.deleteRow( tc, keyRow1, SYSUSERSRowFactory.SYSUSERS_INDEX1_ID ); + } + // // class implementation // @@ -11352,6 +11373,8 @@ public final class DataDictionaryImpl create_10_5_system_procedures(tc, newlyCreatedRoutines ); // add 10.6 specific system procedures create_10_6_system_procedures(tc, newlyCreatedRoutines ); + // add 10.9 specific system procedures + create_10_9_system_procedures( tc, newlyCreatedRoutines ); } /** @@ -12975,6 +12998,83 @@ public final class DataDictionaryImpl } + /** + *+ * Create system procedures that are part of the + * SYSCS_UTIL schema added in version 10.9. These include the procedures for managing NATIVE credentials. + * See DERBY-866. + *
+ * + * @param tc an instance of the Transaction Controller. + * @param newlyCreatedRoutines set of routines we are creating (used to add permissions later on) + **/ + void create_10_9_system_procedures( TransactionController tc, HashSet newlyCreatedRoutines ) + throws StandardException + { + UUID sysUtilUUID = getSystemUtilSchemaDescriptor().getUUID(); + + // + // SYSCS_CREATE_USER( IN USERNAME VARCHAR(128), IN PASSWORD VARCHAR(32672) ) + // + + { + // procedure argument names + String[] arg_names = { "userName", "password" }; + + // procedure argument types + TypeDescriptor[] arg_types = + { + CATALOG_TYPE_SYSTEM_IDENTIFIER, + DataTypeDescriptor.getPasswordDataTypeDescriptor( false ) + }; + + createSystemProcedureOrFunction + ( + "SYSCS_CREATE_USER", + sysUtilUUID, + arg_names, + arg_types, + 0, + 0, + RoutineAliasInfo.MODIFIES_SQL_DATA, + false, + (TypeDescriptor) null, + newlyCreatedRoutines, + tc + ); + } + + // + // SYSCS_DROP_USER( IN USERNAME VARCHAR(128) ) + // + + { + // procedure argument names + String[] arg_names = { "userName" }; + + // procedure argument types + TypeDescriptor[] arg_types = + { + CATALOG_TYPE_SYSTEM_IDENTIFIER + }; + + createSystemProcedureOrFunction + ( + "SYSCS_DROP_USER", + sysUtilUUID, + arg_names, + arg_types, + 0, + 0, + RoutineAliasInfo.MODIFIES_SQL_DATA, + false, + (TypeDescriptor) null, + newlyCreatedRoutines, + tc + ); + } + } + /* ** Priv block code to load net work server meta data queries. Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CharTypeCompiler.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CharTypeCompiler.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CharTypeCompiler.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CharTypeCompiler.java Mon Dec 19 15:49:19 2011 @@ -147,6 +147,9 @@ public final class CharTypeCompiler exte case StoredFormatIds.VARCHAR_TYPE_ID: return "getNullVarchar"; + case StoredFormatIds.PASSWORD_TYPE_ID: + return "getNullPassword"; + default: if (SanityManager.DEBUG) { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SQLToJavaValueNode.java Mon Dec 19 15:49:19 2011 @@ -433,12 +433,23 @@ public class SQLToJavaValueNode extends if (returnsNullOnNullState != null) generateReturnsNullOnNullCheck(mbex); - /* Call getObject() to get the right type of Java value */ - mbex.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "getObject", - "java.lang.Object", 0); - - mbex.cast(value.getTypeId().getCorrespondingJavaTypeName()); - } + if ( value.getTypeId().isPasswordTypeId() ) + { + // if we are setting a password, make sure we zero out the value + // that was passed in so that it can't be memory-sniffed + + mbex.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.StringDataValue, "getRawDataAndZeroIt", + "char[]", 0); + } + else + { + /* Call getObject() to get the right type of Java value */ + mbex.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.DataValueDescriptor, "getObject", + "java.lang.Object", 0); + + mbex.cast(value.getTypeId().getCorrespondingJavaTypeName()); + } + } } /** Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TypeCompilerFactoryImpl.java Mon Dec 19 15:49:19 2011 @@ -45,6 +45,7 @@ public class TypeCompilerFactoryImpl imp static TypeCompiler bitTypeCompiler; static TypeCompiler booleanTypeCompiler; static TypeCompiler charTypeCompiler; + static TypeCompiler passwordTypeCompiler; static TypeCompiler decimalTypeCompiler ; static TypeCompiler doubleTypeCompiler ; static TypeCompiler intTypeCompiler ; @@ -81,6 +82,14 @@ public class TypeCompilerFactoryImpl imp { String sqlTypeName; + if ( typeId.isPasswordTypeId() ) + { + return passwordTypeCompiler = + getAnInstance(PACKAGE_NAME + "CharTypeCompiler", + passwordTypeCompiler, + typeId); + } + switch (typeId.getJDBCTypeId()) { case Types.BINARY: Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java Mon Dec 19 15:49:19 2011 @@ -314,6 +314,7 @@ public abstract class BaseActivation imp @return A RowLocation template for the conglomerate */ public RowLocation getRowLocationTemplate(int itemNumber) + throws StandardException { if (SanityManager.DEBUG) { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicSortObserver.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicSortObserver.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicSortObserver.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicSortObserver.java Mon Dec 19 15:49:19 2011 @@ -135,6 +135,7 @@ public class BasicSortObserver implement private DataValueDescriptor[] getClone(DataValueDescriptor[] origArray) + throws StandardException { /* If the free list is not empty, then * get an DataValueDescriptor[] from there and swap Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java Mon Dec 19 15:49:19 2011 @@ -99,6 +99,7 @@ public class CardinalityCounter implemen } private DataValueDescriptor[] clone(DataValueDescriptor[] clonee) + throws StandardException { DataValueDescriptor[] cloned; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexValueRow.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexValueRow.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexValueRow.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexValueRow.java Mon Dec 19 15:49:19 2011 @@ -69,7 +69,8 @@ class IndexValueRow implements ExecIndex @see ExecRow#getRowArray */ - public DataValueDescriptor[] getRowArrayClone() + public DataValueDescriptor[] getRowArrayClone() + throws StandardException { return valueRow.getRowArrayClone(); } @@ -93,11 +94,11 @@ class IndexValueRow implements ExecIndex } // position is 1-based - public ExecRow getClone() { + public ExecRow getClone() throws StandardException { return new IndexValueRow(valueRow.getClone()); } - public ExecRow getClone(FormatableBitSet clonedCols) { + public ExecRow getClone(FormatableBitSet clonedCols) throws StandardException { return new IndexValueRow(valueRow.getClone(clonedCols)); } @@ -114,6 +115,7 @@ class IndexValueRow implements ExecIndex // position is 1-based public DataValueDescriptor cloneColumn(int columnPosition) + throws StandardException { return valueRow.cloneColumn(columnPosition); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java Mon Dec 19 15:49:19 2011 @@ -2439,7 +2439,7 @@ class InsertResultSet extends DMLWriteRe this.row = row; } - public Object invoke(Object ref) + public Object invoke(Object ref) throws StandardException { return row.getClone(); } Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java Mon Dec 19 15:49:19 2011 @@ -105,6 +105,7 @@ public class RIBulkChecker ConglomerateController unreferencedCC, ExecRow firstRowToFail ) + throws StandardException { this.referencedKeyScan = referencedKeyScan; this.foreignKeyScan = foreignKeyScan; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowUtil.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowUtil.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowUtil.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowUtil.java Mon Dec 19 15:49:19 2011 @@ -69,6 +69,7 @@ public class RowUtil @param count Clone this number of columns. */ public static void copyCloneColumns(ExecRow to, ExecRow from, int count) + throws StandardException { for (int ix = 1; ix <= count; ix++) { Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderImpl.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderImpl.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderImpl.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderImpl.java Mon Dec 19 15:49:19 2011 @@ -200,6 +200,7 @@ class TemporaryRowHolderImpl implements * Beetle 4896. */ private ExecRow cloneRow(ExecRow inputRow) + throws StandardException { DataValueDescriptor[] cols = inputRow.getRowArray(); int ncols = cols.length; Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValueRow.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValueRow.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValueRow.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValueRow.java Mon Dec 19 15:49:19 2011 @@ -21,6 +21,7 @@ package org.apache.derby.impl.sql.execute; +import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.services.io.FormatableBitSet; import org.apache.derby.iapi.sql.execute.ExecRow; import org.apache.derby.iapi.types.DataValueDescriptor; @@ -102,12 +103,13 @@ public class ValueRow implements ExecRow */ // position is 1-based - public ExecRow getClone() + public ExecRow getClone() throws StandardException { return getClone((FormatableBitSet) null); } public ExecRow getClone(FormatableBitSet clonedCols) + throws StandardException { int numColumns = column.length; @@ -168,6 +170,7 @@ public class ValueRow implements ExecRow // position is 1-based public final DataValueDescriptor cloneColumn(int columnPosition) + throws StandardException { return column[columnPosition -1].cloneValue(false); } @@ -207,7 +210,8 @@ public class ValueRow implements ExecRow @see ExecRow#getRowArray */ - public DataValueDescriptor[] getRowArrayClone() + public DataValueDescriptor[] getRowArrayClone() + throws StandardException { int numColumns = column.length; DataValueDescriptor[] columnClones = new DataValueDescriptor[numColumns]; Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Mon Dec 19 15:49:19 2011 @@ -1229,6 +1229,11 @@ Guide.+ * Master test entry point. + *
+ */ + public void testAll() throws Exception + { + println( "authorizationIsOn() = " + authorizationIsOn() ); + + Connection dboConnection = openUserConnection( TEST_DBO ); + Connection janetConnection = openUserConnection( JANET ); + + createUserTests( dboConnection, janetConnection ); + } + + private void createUserTests + ( Connection dboConnection, Connection janetConnection ) + throws Exception + { + vetCreateDropUser( dboConnection, true ); + vetCreateDropUser( janetConnection, !authorizationIsOn() ); + + // Make sure that we can create a user in the approved fashion. + char[] password = new char[] { 'r','u','t','h','p','a','s','s','w','o','r','d' }; + CharArrayReader reader = new CharArrayReader( password ); + + CallableStatement cs = dboConnection.prepareCall( "call syscs_util.syscs_create_user( 'ruth', ? )" ); + cs.setCharacterStream( 1, reader, password.length ); + cs.execute(); + cs.close(); + Arrays.fill( password, (char) 0 ); + + vetQuery + ( + dboConnection, true, + "select username from sys.sysusers order by username", + new String[][] + { + new String[] { "ruth" }, + }, + true, null + ); + + // ok, now drop the new user + goodStatement( dboConnection, "call syscs_util.syscs_drop_user( 'ruth' )" ); + } + private void vetCreateDropUser( Connection conn, boolean shouldSucceed ) + throws Exception + { + vetExecution( conn, shouldSucceed, "call syscs_util.syscs_create_user( 'fred', 'fredpassword' )", NO_EXECUTE_PERMISSION ); + vetQuery + ( + conn, shouldSucceed, + "select username from sys.sysusers order by username", + new String[][] + { + new String[] { "fred" }, + }, + true, "4251D" + ); + vetExecution + ( + conn, false, "call syscs_util.syscs_create_user( 'fred', 'fredpassword' )", + shouldSucceed ? DUPLICATE_USER : NO_EXECUTE_PERMISSION + ); + vetExecution( conn, shouldSucceed, "call syscs_util.syscs_drop_user( 'fred' )", NO_EXECUTE_PERMISSION ); + vetQuery + ( + conn, shouldSucceed, + "select username from sys.sysusers order by username", + new String[][] {}, + true, "4251D" + ); + + // no-one can drop the credentials of the DBO + String dbo = authorizationIsOn() ? "TEST_DBO" : "APP"; + expectExecutionError + ( + conn, shouldSucceed ? CANT_DROP_DBO : NO_EXECUTE_PERMISSION, + "call syscs_util.syscs_drop_user( '" + dbo + "' )" + ); + } + private void vetExecution + ( Connection conn, boolean shouldSucceed, String query, String expectedSQLState ) + throws Exception + { + if ( shouldSucceed ) { goodStatement( conn, query ); } + else { expectExecutionError( conn, expectedSQLState, query ); } + } + private void vetQuery + ( + Connection conn, + boolean shouldSucceed, + String query, + String[][] expectedResults, + boolean compileTimeError, + String expectedSQLState + ) + throws Exception + { + if ( shouldSucceed ) { assertResults( conn, query, expectedResults, true ); } + else + { + if ( compileTimeError ) { expectCompilationError( conn, expectedSQLState, query ); } + else { expectExecutionError( conn, expectedSQLState, query ); } + } + } + +} + + + + Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NativeAuthProcs.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Mon Dec 19 15:49:19 2011 @@ -221,6 +221,7 @@ public class _Suite extends BaseTestCase suite.addTest(Derby5005Test.suite()); suite.addTest(AutoIncrementTest.suite()); suite.addTest(HalfCreatedDatabaseTest.suite()); + suite.addTest(NativeAuthProcs.suite()); return suite; } } Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_9.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_9.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_9.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_9.java Mon Dec 19 15:49:19 2011 @@ -168,18 +168,22 @@ public class Changes10_9 extends Upgrade { case PH_CREATE: // create with old version vetSYSUSERS( s, false ); + vetNativeProcs( s, false ); break; case PH_SOFT_UPGRADE: // boot with new version and soft-upgrade vetSYSUSERS( s, false ); + vetNativeProcs( s, false ); break; case PH_POST_SOFT_UPGRADE: // soft-downgrade: boot with old version after soft-upgrade vetSYSUSERS( s, false ); + vetNativeProcs( s, false ); break; case PH_HARD_UPGRADE: // boot with new version and hard-upgrade vetSYSUSERS( s, true ); + vetNativeProcs( s, true ); break; } @@ -196,5 +200,35 @@ public class Changes10_9 extends Upgrade rs.close(); } + private void vetNativeProcs( Statement s, boolean shouldExist ) throws Exception + { + try { + s.execute( "call syscs_util.syscs_create_user( 'fred', 'fredpassword' )" ); + + ResultSet rs = s.executeQuery( "select username from sys.sysusers order by username" ); + rs.next(); + assertEquals( "fred", rs.getString( 1 ) ); + + s.execute( "call syscs_util.syscs_drop_user( 'fred' )" ); + + rs = s.executeQuery( "select username from sys.sysusers order by username" ); + assertFalse( rs.next() ); + + rs.close(); + + if ( !shouldExist ) + { + fail( "syscs_util.syscs_create_user should not exist." ); + } + } catch (SQLException se ) + { + if ( shouldExist ) + { + fail( "Saw unexpected error: " + se.getMessage() ); + } + assertSQLState( "42Y03", se ); + } + + } } Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/CleanDatabaseTestSetup.java Mon Dec 19 15:49:19 2011 @@ -165,6 +165,7 @@ public class CleanDatabaseTestSetup exte if (compress) compressObjects(conn); removeRoles(conn); + removeUsers( conn ); } /** @@ -260,6 +261,31 @@ public class CleanDatabaseTestSetup exte conn.commit(); } + /** Drop all credentials stored in SYSUSERS */ + private static void removeUsers(Connection conn) throws SQLException + { + // Get the users + Statement stm = conn.createStatement(); + ResultSet rs = stm.executeQuery( "select username from sys.sysusers" ); + ArrayList users = new ArrayList(); + + while ( rs.next() ) { users.add( rs.getString( 1 ) ); } + rs.close(); + stm.close(); + + // Now delete them + PreparedStatement ps = conn.prepareStatement( "call syscs_util.syscs_drop_user( ? )" ); + + for ( int i = 0; i < users.size(); i++ ) + { + ps.setString( 1, (String) users.get( i ) ); + ps.executeUpdate(); + } + + ps.close(); + conn.commit(); + } + /** * Set of objects that will be compressed as part of cleaning a database. */ Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessRow.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessRow.java?rev=1220807&r1=1220806&r2=1220807&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessRow.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/unitTests/store/T_AccessRow.java Mon Dec 19 15:49:19 2011 @@ -126,7 +126,9 @@ public class T_AccessRow return column; } - public DataValueDescriptor[] getRowArrayClone() { + public DataValueDescriptor[] getRowArrayClone() + throws StandardException + { DataValueDescriptor[] retval = new DataValueDescriptor[column.length]; for (int index = 0; index < column.length; index++) retval[index] = column[index].cloneValue(false);