1 24 25 package com.mckoi.database; 26 27 import java.sql.*; 28 import com.mckoi.util.IntegerVector; 29 import com.mckoi.util.BigNumber; 30 import com.mckoi.util.Cache; 31 32 38 39 public class GrantManager { 40 41 43 46 public final static int TABLE = 1; 47 48 51 public final static int DOMAIN = 2; 52 53 68 71 public final static int SCHEMA = 65; 72 73 76 public final static int CATALOG = 66; 77 78 79 82 public final static String PUBLIC_USERNAME_STR = "@PUBLIC"; 83 84 88 public final static TObject PUBLIC_USERNAME = 89 TObject.stringVal(PUBLIC_USERNAME_STR); 90 91 93 96 private DatabaseConnection connection; 97 98 101 private QueryContext context; 102 103 107 private Cache priv_cache; 108 109 112 private boolean grant_table_changed; 113 114 115 119 GrantManager(DatabaseConnection connection) { 120 this.connection = connection; 121 this.context = new DatabaseQueryContext(connection); 122 this.priv_cache = new Cache(129, 129, 20); 123 124 this.grant_table_changed = false; 125 126 connection.attachTableBackedCache(new TableBackedCache(Database.SYS_GRANTS) { 129 public void purgeCacheOfInvalidatedEntries( 130 IntegerVector added_rows, IntegerVector removed_rows) { 131 if (grant_table_changed) { 133 invalidateGrantCache(); 134 grant_table_changed = false; 135 } 136 else if ((added_rows != null && added_rows.size() > 0) || 139 (removed_rows != null && removed_rows.size() > 0)) { 140 invalidateGrantCache(); 141 } 142 } 143 }); 144 } 145 146 148 151 private void invalidateGrantCache() { 152 priv_cache.removeAll(); 153 } 154 155 161 private static class GrantQuery { 162 private int object; 163 private String param; 164 private String username; 165 private int flags; 166 167 GrantQuery(int object, String param, String username, 168 boolean flag1, boolean flag2) { 169 this.object = object; 170 this.param = param; 171 this.username = username; 172 this.flags = flag1 ? 1 : 0; 173 this.flags = this.flags | (flag2 ? 2 : 0); 174 } 175 176 public boolean equals(Object ob) { 177 GrantQuery dest = (GrantQuery) ob; 178 return (object == dest.object && 179 param.equals(dest.param) && 180 username.equals(dest.username) && 181 flags == dest.flags); 182 } 183 184 public int hashCode() { 185 return object + param.hashCode() + username.hashCode() + flags; 186 } 187 188 } 189 190 191 192 private Privileges getPrivs(int object, String param, String username, 193 boolean only_grant_options, 194 String granter, boolean include_public_privs) 195 throws DatabaseException { 196 197 GrantQuery key = new GrantQuery(object, param, username, 199 only_grant_options, include_public_privs); 200 201 Privileges privs = (Privileges) priv_cache.get(key); 203 if (privs == null) { 204 206 236 DataTable grant_table = connection.getTable(Database.SYS_GRANTS); 238 239 Variable object_col = grant_table.getResolvedVariable(1); 240 Variable param_col = grant_table.getResolvedVariable(2); 241 Variable grantee_col = grant_table.getResolvedVariable(3); 242 Variable grant_option_col = grant_table.getResolvedVariable(4); 243 Variable granter_col = grant_table.getResolvedVariable(5); 244 Operator EQUALS = Operator.get("="); 245 246 Table t1 = grant_table; 247 248 t1 = t1.simpleSelect(context, param_col, EQUALS, 252 new Expression(TObject.stringVal(param))); 253 254 258 Expression user_check = 260 Expression.simple(grantee_col, EQUALS, TObject.stringVal(username)); 261 if (include_public_privs) { 262 user_check = new Expression( 263 user_check, Operator.get("or"), 264 Expression.simple(grantee_col, EQUALS, PUBLIC_USERNAME) 265 ); 266 } 267 Expression expr = new Expression( 271 Expression.simple(object_col, EQUALS, TObject.intVal(object)), 272 Operator.get("and"), 273 user_check); 274 275 if (only_grant_options) { 277 Expression grant_option_check = 278 Expression.simple(grant_option_col, EQUALS, 279 TObject.stringVal("true")); 280 expr = new Expression(expr, Operator.get("and"), grant_option_check); 281 } 282 283 if (granter != null) { 285 Expression granter_check = 286 Expression.simple(granter_col, EQUALS, TObject.stringVal(granter)); 287 expr = new Expression(expr, Operator.get("and"), granter_check); 288 } 289 290 t1 = t1.exhaustiveSelect(context, expr); 291 292 privs = Privileges.EMPTY_PRIVS; 294 RowEnumeration e = t1.rowEnumeration(); 295 while (e.hasMoreRows()) { 296 int row_index = e.nextRowIndex(); 297 BigNumber priv_bit = 298 (BigNumber) t1.getCellContents(0, row_index).getObject(); 299 privs = privs.add(priv_bit.intValue()); 300 } 301 302 priv_cache.put(key, privs); 304 305 } 306 307 return privs; 308 } 309 310 315 private void internalSetPrivs(Privileges new_privs, int object, String param, 316 String grantee, boolean grant_option, String granter) 317 throws DatabaseException { 318 319 revokeAllGrantsOnObject(object, param, grantee, grant_option, granter); 321 322 if (!new_privs.isEmpty()) { 323 324 DataTable grant_table = connection.getTable(Database.SYS_GRANTS); 326 327 RowData rdat = new RowData(grant_table); 329 rdat.setColumnDataFromObject(0, BigNumber.fromInt(new_privs.toInt())); 330 rdat.setColumnDataFromObject(1, BigNumber.fromInt(object)); 331 rdat.setColumnDataFromObject(2, param); 332 rdat.setColumnDataFromObject(3, grantee); 333 rdat.setColumnDataFromObject(4, grant_option ? "true" : "false"); 334 rdat.setColumnDataFromObject(5, granter); 335 grant_table.add(rdat); 336 337 invalidateGrantCache(); 339 340 grant_table_changed = true; 342 343 } 344 345 } 346 347 349 360 public void addGrant(Privileges privs, int object, String param, 361 String grantee, boolean grant_option, String granter) 362 throws DatabaseException { 363 364 if (object == TABLE) { 365 if (!connection.tableExists(TableName.resolve(param))) { 367 throw new DatabaseException("Table: " + param + " does not exist."); 368 } 369 } 370 else if (object == SCHEMA) { 371 if (!connection.schemaExists(param)) { 373 throw new DatabaseException("Schema: " + param + " does not exist."); 374 } 375 } 376 377 Privileges existing_privs = 379 getPrivs(object, param, grantee, grant_option, granter, false); 380 Privileges new_privs = privs.merge(existing_privs); 382 383 if (!new_privs.equals(existing_privs)) { 386 internalSetPrivs(new_privs, object, param, grantee, 387 grant_option, granter); 388 } 389 390 } 391 392 396 public void addGrantToAllTablesInSchema(String schema, Privileges privs, 397 String grantee, boolean grant_option, 398 String granter) throws DatabaseException { 399 TableName[] list = connection.getTableList(); 401 for (int i = 0; i < list.length; ++i) { 402 TableName tname = list[i]; 403 if (tname.getSchema().equals(schema)) { 405 addGrant(privs, TABLE, tname.toString(), grantee, 406 grant_option, granter); 407 } 408 } 409 } 410 411 415 public void removeGrant(Privileges privs, int object, String param, 416 String grantee, boolean grant_option, String granter) 417 throws DatabaseException { 418 419 Privileges existing_privs = 421 getPrivs(object, param, grantee, grant_option, granter, false); 422 Privileges new_privs = existing_privs.remove(privs); 424 425 if (!new_privs.equals(existing_privs)) { 428 internalSetPrivs(new_privs, object, param, grantee, 429 grant_option, granter); 430 } 431 432 } 433 434 438 public void revokeAllGrantsOnObject(int object, String param, 439 String grantee, boolean grant_option, String granter) 440 throws DatabaseException { 441 DataTable grant_table = connection.getTable(Database.SYS_GRANTS); 443 444 Variable object_col = grant_table.getResolvedVariable(1); 445 Variable param_col = grant_table.getResolvedVariable(2); 446 Variable grantee_col = grant_table.getResolvedVariable(3); 447 Variable grant_option_col = grant_table.getResolvedVariable(4); 448 Variable granter_col = grant_table.getResolvedVariable(5); 449 Operator EQUALS = Operator.get("="); 450 451 Table t1 = grant_table; 452 453 t1 = t1.simpleSelect(context, param_col, EQUALS, 457 new Expression(TObject.stringVal(param))); 458 459 463 Expression user_check = 465 Expression.simple(grantee_col, EQUALS, TObject.stringVal(grantee)); 466 Expression expr = new Expression( 470 Expression.simple(object_col, EQUALS, TObject.intVal(object)), 471 Operator.get("and"), 472 user_check); 473 474 Expression grant_option_check = 476 Expression.simple(grant_option_col, EQUALS, 477 TObject.stringVal(grant_option ? "true" : "false")); 478 expr = new Expression(expr, Operator.get("and"), grant_option_check); 479 480 Expression granter_check = 482 Expression.simple(granter_col, EQUALS, TObject.stringVal(granter)); 483 expr = new Expression(expr, Operator.get("and"), granter_check); 484 485 t1 = t1.exhaustiveSelect(context, expr); 486 487 grant_table.delete(t1); 489 490 invalidateGrantCache(); 492 493 grant_table_changed = true; 495 496 } 497 498 502 public void revokeAllGrantsOnObject(int object, String param) 503 throws DatabaseException { 504 DataTable grant_table = connection.getTable(Database.SYS_GRANTS); 506 507 Variable object_col = grant_table.getResolvedVariable(1); 508 Variable param_col = grant_table.getResolvedVariable(2); 509 Table t1 = grant_table.simpleSelect(context, object_col, 511 Operator.get("="), new Expression(TObject.intVal(object))); 512 t1 = t1.simpleSelect(context, 514 param_col, Operator.get("="), 515 new Expression(TObject.stringVal(param))); 516 517 grant_table.delete(t1); 519 520 invalidateGrantCache(); 522 523 grant_table_changed = true; 525 526 } 527 528 540 public Privileges userGrants(int object, String param, String username) 541 throws DatabaseException { 542 return getPrivs(object, param, username, false, null, true); 543 } 544 545 556 public Privileges userGrantOptions(int object, String param, String username) 557 throws DatabaseException { 558 return getPrivs(object, param, username, true, null, true); 559 } 560 561 } 562 | Popular Tags |