001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.engine;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.constant.ErrorCode;
011: import org.h2.message.Message;
012: import org.h2.message.Trace;
013: import org.h2.schema.Schema;
014: import org.h2.security.SHA256;
015: import org.h2.table.MetaTable;
016: import org.h2.table.RangeTable;
017: import org.h2.table.Table;
018: import org.h2.table.TableView;
019: import org.h2.util.ByteUtils;
020: import org.h2.util.ObjectArray;
021: import org.h2.util.RandomUtils;
022: import org.h2.util.StringUtils;
023:
024: /**
025: * Represents a user object.
026: */
027: public class User extends RightOwner {
028:
029: private final boolean systemUser;
030: private byte[] salt;
031: private byte[] passwordHash;
032: private boolean admin;
033:
034: public User(Database database, int id, String userName,
035: boolean systemUser) {
036: super (database, id, userName, Trace.USER);
037: this .systemUser = systemUser;
038: }
039:
040: public void setAdmin(boolean admin) {
041: this .admin = admin;
042: }
043:
044: public boolean getAdmin() {
045: return admin;
046: }
047:
048: public void setSaltAndHash(byte[] salt, byte[] hash) {
049: this .salt = salt;
050: this .passwordHash = hash;
051: }
052:
053: public void setUserPasswordHash(byte[] userPasswordHash) {
054: if (userPasswordHash != null) {
055: salt = RandomUtils.getSecureBytes(Constants.SALT_LEN);
056: SHA256 sha = new SHA256();
057: this .passwordHash = sha.getHashWithSalt(userPasswordHash,
058: salt);
059: }
060: }
061:
062: public String getCreateSQLForCopy(Table table, String quotedName) {
063: throw Message.getInternalError();
064: }
065:
066: public String getCreateSQL() {
067: return getCreateSQL(true, false);
068: }
069:
070: public String getDropSQL() {
071: return null;
072: }
073:
074: public void checkRight(Table table, int rightMask)
075: throws SQLException {
076: if (rightMask != Right.SELECT && !systemUser) {
077: database.checkWritingAllowed();
078: }
079: if (admin) {
080: return;
081: }
082: Role publicRole = database.getPublicRole();
083: if (publicRole.isRightGrantedRecursive(table, rightMask)) {
084: return;
085: }
086: if (table instanceof MetaTable || table instanceof RangeTable) {
087: // everybody has access to the metadata information
088: return;
089: }
090: if (Table.VIEW.equals(table.getTableType())) {
091: TableView v = (TableView) table;
092: if (v.getOwner() == this ) {
093: // the owner of a view has access:
094: // SELECT * FROM (SELECT * FROM ...)
095: return;
096: }
097: }
098: if (!isRightGrantedRecursive(table, rightMask)) {
099: if (table.getTemporary() && !table.getGlobalTemporary()) {
100: // the owner has all rights on local temporary tables
101: return;
102: }
103: throw Message.getSQLException(
104: ErrorCode.NOT_ENOUGH_RIGHTS_FOR_1, table.getSQL());
105: }
106: }
107:
108: public String getCreateSQL(boolean password, boolean ifNotExists) {
109: StringBuffer buff = new StringBuffer();
110: buff.append("CREATE USER ");
111: if (ifNotExists) {
112: buff.append("IF NOT EXISTS ");
113: }
114: buff.append(getSQL());
115: if (comment != null) {
116: buff.append(" COMMENT ");
117: buff.append(StringUtils.quoteStringSQL(comment));
118: }
119: if (password) {
120: buff.append(" SALT '");
121: buff.append(ByteUtils.convertBytesToString(salt));
122: buff.append("' HASH '");
123: buff.append(ByteUtils.convertBytesToString(passwordHash));
124: buff.append("'");
125: } else {
126: buff.append(" PASSWORD ''");
127: }
128: if (admin) {
129: buff.append(" ADMIN");
130: }
131: return buff.toString();
132: }
133:
134: public void checkUserPasswordHash(byte[] buff, SQLException onError)
135: throws SQLException {
136: SHA256 sha = new SHA256();
137: byte[] hash = sha.getHashWithSalt(buff, salt);
138: if (!ByteUtils.compareSecure(hash, passwordHash)) {
139: try {
140: Thread.sleep(Constants.DELAY_WRONG_PASSWORD);
141: } catch (InterruptedException e) {
142: // ignore
143: }
144: throw onError;
145: }
146: }
147:
148: public void checkAdmin() throws SQLException {
149: if (!admin) {
150: throw Message
151: .getSQLException(ErrorCode.ADMIN_RIGHTS_REQUIRED);
152: }
153: }
154:
155: public int getType() {
156: return DbObject.USER;
157: }
158:
159: public ObjectArray getChildren() {
160: ObjectArray all = database.getAllRights();
161: ObjectArray children = new ObjectArray();
162: for (int i = 0; i < all.size(); i++) {
163: Right right = (Right) all.get(i);
164: if (right.getGrantee() == this ) {
165: children.add(right);
166: }
167: }
168: all = database.getAllSchemas();
169: for (int i = 0; i < all.size(); i++) {
170: Schema schema = (Schema) all.get(i);
171: if (schema.getOwner() == this ) {
172: children.add(schema);
173: }
174: }
175: return children;
176: }
177:
178: public void removeChildrenAndResources(Session session)
179: throws SQLException {
180: ObjectArray rights = database.getAllRights();
181: for (int i = 0; i < rights.size(); i++) {
182: Right right = (Right) rights.get(i);
183: if (right.getGrantee() == this ) {
184: database.removeDatabaseObject(session, right);
185: }
186: }
187: database.removeMeta(session, getId());
188: salt = null;
189: ByteUtils.clear(passwordHash);
190: passwordHash = null;
191: invalidate();
192: }
193:
194: public void checkRename() {
195: // ok
196: }
197:
198: public void checkNoSchemas() throws SQLException {
199: ObjectArray schemas = database.getAllSchemas();
200: for (int i = 0; i < schemas.size(); i++) {
201: Schema s = (Schema) schemas.get(i);
202: if (this == s.getOwner()) {
203: throw Message.getSQLException(ErrorCode.CANNOT_DROP_2,
204: new String[] { getName(), s.getName() });
205: }
206: }
207: }
208:
209: }
|