1 21 22 package org.apache.derby.impl.sql.conn; 23 24 import org.apache.derby.iapi.sql.Activation; 25 import org.apache.derby.iapi.reference.Property; 26 import org.apache.derby.iapi.util.IdUtil; 27 import org.apache.derby.iapi.util.StringUtil; 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 import org.apache.derby.iapi.error.StandardException; 30 import org.apache.derby.iapi.sql.conn.Authorizer; 31 import org.apache.derby.iapi.reference.SQLState; 32 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 33 import org.apache.derby.iapi.services.property.PropertyUtil; 34 import org.apache.derby.iapi.services.property.PersistentSet; 35 import org.apache.derby.catalog.types.RoutineAliasInfo; 36 import org.apache.derby.iapi.sql.dictionary.DataDictionary; 37 import org.apache.derby.iapi.sql.dictionary.StatementPermission; 38 import org.apache.derby.iapi.store.access.TransactionController; 39 40 import java.util.Properties ; 41 import java.util.List ; 42 import java.util.Iterator ; 43 44 class GenericAuthorizer 45 implements Authorizer 46 { 47 private static final int NO_ACCESS = 0; 50 private static final int READ_ACCESS = 1; 51 private static final int FULL_ACCESS = 2; 52 53 private int userAccessLevel; 57 58 boolean readOnlyConnection; 61 62 private final LanguageConnectionContext lcc; 63 64 private final String authorizationId; 66 GenericAuthorizer(String authorizationId, 67 LanguageConnectionContext lcc, 68 boolean sqlConnection) 69 throws StandardException 70 { 71 this.lcc = lcc; 72 this.authorizationId = authorizationId; 73 74 if(sqlConnection) 77 refresh(); 78 } 79 80 83 private boolean connectionMustRemainReadOnly() 84 { 85 if (lcc.getDatabase().isReadOnly() || 86 (userAccessLevel==READ_ACCESS)) 87 return true; 88 else 89 return false; 90 } 91 92 98 public void authorize( int operation) throws StandardException 99 { 100 authorize( (Activation) null, operation); 101 } 102 103 107 public void authorize( Activation activation, int operation) throws StandardException 108 { 109 int sqlAllowed = lcc.getStatementContext().getSQLAllowed(); 110 111 switch (operation) 112 { 113 case Authorizer.SQL_ARBITARY_OP: 114 case Authorizer.SQL_CALL_OP: 115 if (sqlAllowed == RoutineAliasInfo.NO_SQL) 116 throw externalRoutineException(operation, sqlAllowed); 117 break; 118 case Authorizer.SQL_SELECT_OP: 119 if (sqlAllowed > RoutineAliasInfo.READS_SQL_DATA) 120 throw externalRoutineException(operation, sqlAllowed); 121 break; 122 123 case Authorizer.SQL_WRITE_OP: 125 case Authorizer.PROPERTY_WRITE_OP: 126 if (isReadOnlyConnection()) 127 throw StandardException.newException(SQLState.AUTH_WRITE_WITH_READ_ONLY_CONNECTION); 128 if (sqlAllowed > RoutineAliasInfo.MODIFIES_SQL_DATA) 129 throw externalRoutineException(operation, sqlAllowed); 130 break; 131 132 case Authorizer.JAR_WRITE_OP: 134 case Authorizer.SQL_DDL_OP: 135 if (isReadOnlyConnection()) 136 throw StandardException.newException(SQLState.AUTH_DDL_WITH_READ_ONLY_CONNECTION); 137 138 if (sqlAllowed > RoutineAliasInfo.MODIFIES_SQL_DATA) 139 throw externalRoutineException(operation, sqlAllowed); 140 break; 141 142 default: 143 if (SanityManager.DEBUG) 144 SanityManager.THROWASSERT("Bad operation code "+operation); 145 } 146 if( activation != null) 147 { 148 List requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList(); 149 DataDictionary dd = lcc.getDataDictionary(); 150 151 if( requiredPermissionsList != null && 154 !requiredPermissionsList.isEmpty() && 155 !authorizationId.equals(dd.getAuthorizationDatabaseOwner())) 156 { 157 int ddMode = dd.startReading(lcc); 158 159 180 lcc.beginNestedTransaction(true); 181 182 try 183 { 184 try 185 { 186 for (Iterator iter = requiredPermissionsList.iterator(); 188 iter.hasNext();) 189 { 190 ((StatementPermission) iter.next()).check(lcc, 191 authorizationId, false); 192 } 193 } 194 finally 195 { 196 dd.doneReading(ddMode, lcc); 197 } 198 } 199 finally 200 { 201 lcc.commitNestedTransaction(); 204 } 205 } 206 } 207 } 208 209 private static StandardException externalRoutineException(int operation, int sqlAllowed) { 210 211 String sqlState; 212 if (sqlAllowed == RoutineAliasInfo.READS_SQL_DATA) 213 sqlState = SQLState.EXTERNAL_ROUTINE_NO_MODIFIES_SQL; 214 else if (sqlAllowed == RoutineAliasInfo.CONTAINS_SQL) 215 { 216 switch (operation) 217 { 218 case Authorizer.SQL_WRITE_OP: 219 case Authorizer.PROPERTY_WRITE_OP: 220 case Authorizer.JAR_WRITE_OP: 221 case Authorizer.SQL_DDL_OP: 222 sqlState = SQLState.EXTERNAL_ROUTINE_NO_MODIFIES_SQL; 223 break; 224 default: 225 sqlState = SQLState.EXTERNAL_ROUTINE_NO_READS_SQL; 226 break; 227 } 228 } 229 else 230 sqlState = SQLState.EXTERNAL_ROUTINE_NO_SQL; 231 232 return StandardException.newException(sqlState); 233 } 234 235 236 239 public String getAuthorizationId() 240 { 241 return authorizationId; 242 } 243 244 private void getUserAccessLevel() throws StandardException 245 { 246 userAccessLevel = NO_ACCESS; 247 if (userOnAccessList(Property.FULL_ACCESS_USERS_PROPERTY)) 248 userAccessLevel = FULL_ACCESS; 249 250 if (userAccessLevel == NO_ACCESS && 251 userOnAccessList(Property.READ_ONLY_ACCESS_USERS_PROPERTY)) 252 userAccessLevel = READ_ACCESS; 253 254 if (userAccessLevel == NO_ACCESS) 255 userAccessLevel = getDefaultAccessLevel(); 256 } 257 258 private int getDefaultAccessLevel() throws StandardException 259 { 260 PersistentSet tc = lcc.getTransactionExecute(); 261 262 String modeS = (String ) 263 PropertyUtil.getServiceProperty( 264 tc, 265 Property.DEFAULT_CONNECTION_MODE_PROPERTY); 266 if (modeS == null) 267 return FULL_ACCESS; 268 else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.NO_ACCESS)) 269 return NO_ACCESS; 270 else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.READ_ONLY_ACCESS)) 271 return READ_ACCESS; 272 else if(StringUtil.SQLEqualsIgnoreCase(modeS, Property.FULL_ACCESS)) 273 return FULL_ACCESS; 274 else 275 { 276 if (SanityManager.DEBUG) 277 SanityManager.THROWASSERT("Invalid value for property "+ 278 Property.DEFAULT_CONNECTION_MODE_PROPERTY+ 279 " "+ 280 modeS); 281 return FULL_ACCESS; 282 } 283 } 284 285 private boolean userOnAccessList(String listName) throws StandardException 286 { 287 PersistentSet tc = lcc.getTransactionExecute(); 288 String listS = (String ) 289 PropertyUtil.getServiceProperty(tc, listName); 290 return IdUtil.idOnList(authorizationId,listS); 291 } 292 293 296 public boolean isReadOnlyConnection() 297 { 298 return readOnlyConnection; 299 } 300 301 305 public void setReadOnlyConnection(boolean on, boolean authorize) 306 throws StandardException 307 { 308 if (authorize && !on) { 309 if (connectionMustRemainReadOnly()) 310 throw StandardException.newException(SQLState.AUTH_CANNOT_SET_READ_WRITE); 311 } 312 readOnlyConnection = on; 313 } 314 315 319 public void refresh() throws StandardException 320 { 321 getUserAccessLevel(); 322 if (!readOnlyConnection) 323 readOnlyConnection = connectionMustRemainReadOnly(); 324 325 if (userAccessLevel == NO_ACCESS) 327 throw StandardException.newException(SQLState.AUTH_DATABASE_CONNECTION_REFUSED); 328 } 329 330 } 331 | Popular Tags |