From 62480488056fa0a7e1508c0d9104bf2c1a090c7a Mon Sep 17 00:00:00 2001 From: Honghua Zhu Date: Wed, 25 Jan 2017 12:04:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E6=96=B0=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=97=B6=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA?= =?UTF-8?q?root=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/lealone/db/Database.java | 44 ++++++++++++------- .../java/org/lealone/db/DatabaseEngine.java | 25 ++++++----- .../java/org/lealone/db/LealoneDatabase.java | 10 ++++- .../main/java/org/lealone/db/MetaRecord.java | 3 ++ .../test/java/org/lealone/test/TestBase.java | 16 ++++--- 5 files changed, 64 insertions(+), 34 deletions(-) diff --git a/lealone-db/src/main/java/org/lealone/db/Database.java b/lealone-db/src/main/java/org/lealone/db/Database.java index 959663b7f..56afbac43 100644 --- a/lealone-db/src/main/java/org/lealone/db/Database.java +++ b/lealone-db/src/main/java/org/lealone/db/Database.java @@ -425,10 +425,10 @@ private void openDatabase() { systemSession = new ServerSession(this, systemUser, ++nextSessionId); - long t1 = System.currentTimeMillis(); + // long t1 = System.currentTimeMillis(); openMetaTable(); - System.out.println(getShortName() + ": openMetaTable total time: " + (System.currentTimeMillis() - t1) - + " ms"); + // System.out.println(getShortName() + ": openMetaTable total time: " + (System.currentTimeMillis() - t1) + // + " ms"); if (!readOnly) { // set CREATE_BUILD in a new database @@ -1165,12 +1165,6 @@ public void addDatabaseObject(ServerSession session, DbObject obj) { DbObjectType type = obj.getType(); synchronized (getLock(type)) { Map map = getMap(type); - if (obj.getType() == DbObjectType.USER) { - User user = (User) obj; - if (user.isAdmin() && systemUser.getName().equals(SYSTEM_USER_NAME)) { - systemUser.rename(user.getName()); - } - } String name = obj.getName(); if (SysProperties.CHECK && map.get(name) != null) { DbException.throwInternalError("object already exists"); @@ -1919,12 +1913,6 @@ public byte[] getFileEncryptionKey() { return fileEncryptionKey; } - public synchronized void setMasterUser(User user) { - lockMeta(systemSession); - addDatabaseObject(systemSession, user); - systemSession.commit(true); - } - public Role getPublicRole() { return publicRole; } @@ -2808,4 +2796,30 @@ public synchronized int getVersion(int id) { } return version; } + + private static final String ROOT_USER = "ROOT"; + + boolean isRootUser(String userName) { + return ROOT_USER.equalsIgnoreCase(userName); + } + + synchronized User alterRootUserPassword(byte[] userPasswordHash) { + User rootUser = users.get(ROOT_USER); + if (!rootUser.validateUserPasswordHash(userPasswordHash)) { + rootUser.setUserPasswordHash(userPasswordHash); + updateMeta(systemSession, rootUser); + systemSession.commit(true); + } + return rootUser; + } + + synchronized User createAdminUser(String userName, byte[] userPasswordHash) { + User user = new User(this, allocateObjectId(), userName, false); + user.setAdmin(true); + user.setUserPasswordHash(userPasswordHash); + lockMeta(systemSession); + addDatabaseObject(systemSession, user); + systemSession.commit(true); + return user; + } } diff --git a/lealone-db/src/main/java/org/lealone/db/DatabaseEngine.java b/lealone-db/src/main/java/org/lealone/db/DatabaseEngine.java index 41aef11b6..6052d0472 100644 --- a/lealone-db/src/main/java/org/lealone/db/DatabaseEngine.java +++ b/lealone-db/src/main/java/org/lealone/db/DatabaseEngine.java @@ -99,26 +99,27 @@ public synchronized ServerSession createSession(ConnectionInfo ci) { } private ServerSession createSession(String dbName, ConnectionInfo ci, boolean ifExists) { - // 不允许Client访问LealoneDatabase - if (ci.isRemote() && LealoneDatabase.NAME.equalsIgnoreCase(dbName)) - throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, dbName); - boolean opened = false; User user = null; Database database = LealoneDatabase.getInstance().findDatabase(dbName); if (database == null) { if (ifExists) throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, dbName); + // *********************************************************** + // **************以下代码是不安全的**************************** + // *********************************************************** + // 最安全的做法是先连到LealoneDatabase,然后执行CREATE DATABASE语句创建新的数据库 + // 为了方便测试(不安全的做法),如果数据库不存在,按ConnectionInfo中指定的数据库名和用户名自动创建数据库 database = LealoneDatabase.getInstance().createDatabase(dbName, ci); - database.init(ci); opened = true; - if (database.getAllUsers().isEmpty()) { - // users is the last thing we add, so if no user is around, - // the database is new (or not initialized correctly) - user = new User(database, database.allocateObjectId(), ci.getUserName(), false); - user.setAdmin(true); - user.setUserPasswordHash(ci.getUserPasswordHash()); - database.setMasterUser(user); + + String userName = ci.getUserName(); + byte[] userPasswordHash = ci.getUserPasswordHash(); + if (database.isRootUser(userName)) { + user = database.alterRootUserPassword(userPasswordHash); + } else { + // 把当前连接进来的用户当成Admin + user = database.createAdminUser(userName, userPasswordHash); } } else { if (!database.isInitialized()) diff --git a/lealone-db/src/main/java/org/lealone/db/LealoneDatabase.java b/lealone-db/src/main/java/org/lealone/db/LealoneDatabase.java index 30518f095..72b7a7ea1 100644 --- a/lealone-db/src/main/java/org/lealone/db/LealoneDatabase.java +++ b/lealone-db/src/main/java/org/lealone/db/LealoneDatabase.java @@ -56,6 +56,7 @@ private LealoneDatabase() { ConnectionInfo ci = new ConnectionInfo(url, (Properties) null); ci.setBaseDir(SysProperties.getBaseDir()); init(ci); + createRootUser(this); } Database createDatabase(String dbName, ConnectionInfo ci) { @@ -63,7 +64,14 @@ Database createDatabase(String dbName, ConnectionInfo ci) { getSystemSession().prepareStatementLocal(sql).executeUpdate(); // 执行完CREATE DATABASE后会加到databases字段中 // CreateDatabase.update -> Database.addDatabaseObject -> Database.getMap -> this.getDatabasesMap - return databases.get(dbName); + Database db = databases.get(dbName); + db.init(ci); + createRootUser(db); + return db; + } + + private static void createRootUser(Database db) { + db.getSystemSession().prepareStatementLocal("CREATE USER IF NOT EXISTS root PASSWORD '' ADMIN").executeUpdate(); } void closeDatabase(String dbName) { diff --git a/lealone-db/src/main/java/org/lealone/db/MetaRecord.java b/lealone-db/src/main/java/org/lealone/db/MetaRecord.java index 018f0562f..2065c280d 100644 --- a/lealone-db/src/main/java/org/lealone/db/MetaRecord.java +++ b/lealone-db/src/main/java/org/lealone/db/MetaRecord.java @@ -18,6 +18,9 @@ /** * A record in the system table of the database. * It contains the SQL statement to create the database object. + * + * @author H2 Group + * @author zhh */ public class MetaRecord implements Comparable { diff --git a/lealone-test/src/test/java/org/lealone/test/TestBase.java b/lealone-test/src/test/java/org/lealone/test/TestBase.java index af029d954..2def06ea7 100644 --- a/lealone-test/src/test/java/org/lealone/test/TestBase.java +++ b/lealone-test/src/test/java/org/lealone/test/TestBase.java @@ -17,8 +17,6 @@ */ package org.lealone.test; -import io.vertx.core.impl.FileResolver; - import java.io.File; import java.sql.Connection; import java.sql.DriverManager; @@ -34,11 +32,17 @@ import org.lealone.transaction.TransactionEngine; import org.lealone.transaction.TransactionEngineManager; +import io.vertx.core.impl.FileResolver; + public class TestBase extends Assert { public static String url; public static final String DEFAULT_STORAGE_ENGINE_NAME = getDefaultStorageEngineName(); public static final String TEST_DIR = "." + File.separatorChar + "lealone-test-data" + File.separatorChar + "test"; - public static final String DB_NAME = "test"; + public static final String TEST = "test"; + public static final String LEALONE = " lealone"; + public static final String DB_NAME = TEST; + public static final String USER = "root"; + public static final String PASSWORD = ""; public static TransactionEngine te; @@ -174,13 +178,13 @@ public synchronized String getURL(String user, String password) { public synchronized String getURL(String dbName) { if (url != null) return url; - addConnectionParameter("DATABASE_TO_UPPER", "false"); + // addConnectionParameter("DATABASE_TO_UPPER", "false"); // addConnectionParameter("ALIAS_COLUMN_NAME", "true"); // addConnectionParameter("IGNORE_UNKNOWN_SETTINGS", "true"); if (!connectionParameters.containsKey("user")) { - addConnectionParameter("user", "sa"); - addConnectionParameter("password", ""); + addConnectionParameter("user", USER); + addConnectionParameter("password", PASSWORD); } StringBuilder url = new StringBuilder(100);