Hi Colm, Thanks for your suggestion.
a) I will fix it soon. b) I will use the KerberosTime.getTime() method to save the Kerberos time column of identity. c) yes, thanks for your remind. P.S. I created a new issue named DIRKRB-686 for these refactor work. Thanks, Frank -----Original Message----- From: Colm O hEigeartaigh [mailto:[email protected]] Sent: Monday, January 15, 2018 5:49 PM To: [email protected] Subject: Re: directory-kerby git commit: DIRKRB-678 Implement MySQL identity backend for KDC server. Hi Frank, I'd like to suggest a few small changes to this commit: a) The mysql-backend uses different versions for junit + Apache Directory as defined in the parent pom. So instead of 2.0.0-M23 for Apache Directory you can use ${apacheds.version}. You can remove the junit version + test scope because it's defined in the root pom under dependencyManagement. b) The Apache Directory API is only used to call on GeneralizedTime, but this pulls in a large number of dependencies in the distribution. Can we replace GeneralizedTime with something else, or just pull GeneralizedTime into our project directly? c) I think the mysql-backend dependency should be commented out in the kerby-dist pom. Colm. On Mon, Jan 15, 2018 at 2:38 AM, <[email protected]> wrote: > Repository: directory-kerby > Updated Branches: > refs/heads/trunk 7b30a96ee -> 11089e869 > > > DIRKRB-678 Implement MySQL identity backend for KDC server. > > > Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo > Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/ > commit/11089e86 > Tree: > http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/11089e86 > Diff: > http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/11089e86 > > Branch: refs/heads/trunk > Commit: 11089e86940723fb2ca5850504b93814b4e794ad > Parents: 7b30a96 > Author: zenglinx <[email protected]> > Authored: Mon Jan 15 10:38:30 2018 +0800 > Committer: zenglinx <[email protected]> > Committed: Mon Jan 15 10:38:30 2018 +0800 > > ---------------------------------------------------------------------- > kerby-backend/mysql-backend/pom.xml | 91 ++++ > .../kdc/identitybackend/MySQLConfKey.java | 52 +++ > .../identitybackend/MySQLIdentityBackend.java | 437 +++++++++++++++++++ > .../identity/backend/MySQLBackendKdcTest.java | 78 ++++ > .../kerb/identity/backend/MySQLBackendTest.java | 57 +++ > kerby-backend/pom.xml | 1 + > kerby-dist/kdc-dist/conf/backend.conf | 4 + > kerby-dist/kdc-dist/pom.xml | 7 + > 8 files changed, 727 insertions(+) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/mysql-backend/pom.xml > ---------------------------------------------------------------------- > diff --git a/kerby-backend/mysql-backend/pom.xml > b/kerby-backend/mysql-backend/pom.xml > new file mode 100644 > index 0000000..d24335a > --- /dev/null > +++ b/kerby-backend/mysql-backend/pom.xml > @@ -0,0 +1,91 @@ > +<?xml version="1.0" encoding="UTF-8"?> > +<!-- > + Licensed 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. See accompanying LICENSE file. > +--> > +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" > http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:// > maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> > + <modelVersion>4.0.0</modelVersion> > + > + <parent> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerby-backend</artifactId> > + <version>1.1.1-SNAPSHOT</version> </parent> > + > + <artifactId>mysql-backend</artifactId> > + <name>MySQL identity backend</name> <description>MySQL identity > + backend</description> > + > + <dependencies> > + <dependency> > + <groupId>org.apache.directory.server</groupId> > + <artifactId>apacheds-core-api</artifactId> > + <version>2.0.0-M23</version> > + </dependency> > + <dependency> > + <groupId>commons-dbutils</groupId> > + <artifactId>commons-dbutils</artifactId> > + <version>1.6</version> > + </dependency> > + <dependency> > + <groupId>org.drizzle.jdbc</groupId> > + <artifactId>drizzle-jdbc</artifactId> > + <version>1.4</version> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerby-config</artifactId> > + <version>${project.version}</version> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerb-core</artifactId> > + <version>${project.version}</version> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerb-identity</artifactId> > + <version>${project.version}</version> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerb-common</artifactId> > + <version>${project.version}</version> > + </dependency> > + <dependency> > + <groupId>junit</groupId> > + <artifactId>junit</artifactId> > + <version>4.11</version> > + <scope>test</scope> > + </dependency> > + <dependency> > + <groupId>com.h2database</groupId> > + <artifactId>h2</artifactId> > + <version>1.4.196</version> > + <scope>test</scope> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerb-identity-test</artifactId> > + <version>${project.version}</version> > + <scope>test</scope> > + </dependency> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>kerb-kdc-test</artifactId> > + <version>${project.version}</version> > + <type>test-jar</type> > + <scope>test</scope> > + </dependency> > + </dependencies> > + > +</project> > \ No newline at end of file > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/mysql-backend/src/main/java/ > org/apache/kerby/kerberos/kdc/identitybackend/MySQLConfKey.java > ---------------------------------------------------------------------- > diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/ > kerby/kerberos/kdc/identitybackend/MySQLConfKey.java > b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/ > kdc/ > identitybackend/MySQLConfKey.java > new file mode 100644 > index 0000000..ce2ead6 > --- /dev/null > +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/ > kerby/kerberos/kdc/identitybackend/MySQLConfKey.java > @@ -0,0 +1,52 @@ > +/** > + * 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.kerby.kerberos.kdc.identitybackend; > + > +import org.apache.kerby.config.ConfigKey; > + > +/** > + * Define all the MySQL backend related configuration items with > +default > values. > + */ > +public enum MySQLConfKey implements ConfigKey { > + MYSQL_DRIVER("org.drizzle.jdbc.DrizzleDriver"), > + MYSQL_URL("jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend"), > + MYSQL_USER("root"), > + MYSQL_PASSWORD("passwd"); > + > + private Object defaultValue; > + > + MySQLConfKey() { > + this.defaultValue = null; > + } > + > + MySQLConfKey(Object defaultValue) { > + this.defaultValue = defaultValue; > + } > + > + @Override > + public String getPropertyKey() { > + return name().toLowerCase(); > + } > + > + @Override > + public Object getDefaultValue() { > + return this.defaultValue; > + } > +} > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/mysql-backend/src/main/java/ > org/apache/kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.jav > a > ---------------------------------------------------------------------- > diff --git a/kerby-backend/mysql-backend/src/main/java/org/apache/ > kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java > b/kerby-backend/mysql-backend/src/main/java/org/apache/kerby/kerberos/ > kdc/ identitybackend/MySQLIdentityBackend.java > new file mode 100644 > index 0000000..32ede90 > --- /dev/null > +++ b/kerby-backend/mysql-backend/src/main/java/org/apache/ > kerby/kerberos/kdc/identitybackend/MySQLIdentityBackend.java > @@ -0,0 +1,437 @@ > +/** > + * 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.kerby.kerberos.kdc.identitybackend; > + > +import org.apache.commons.dbutils.DbUtils; > +import org.apache.directory.api.util.GeneralizedTime; > +import org.apache.kerby.config.Config; import > +org.apache.kerby.kerberos.kerb.KrbException; > +import org.apache.kerby.kerberos.kerb.identity.backend. > AbstractIdentityBackend; > +import org.apache.kerby.kerberos.kerb.request.KrbIdentity; > +import org.apache.kerby.kerberos.kerb.type.KerberosTime; > +import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey; > +import org.apache.kerby.kerberos.kerb.type.base.EncryptionType; > +import org.slf4j.Logger; > +import org.slf4j.LoggerFactory; > + > +import java.sql.Connection; > +import java.sql.DriverManager; > +import java.sql.PreparedStatement; > +import java.sql.ResultSet; > +import java.sql.SQLException; > +import java.text.ParseException; > +import java.util.ArrayList; > +import java.util.List; > +import java.util.Map; > +import javax.sql.rowset.serial.SerialBlob; > + > +/** > + * A MySQL based backend implementation. > + */ > +public class MySQLIdentityBackend extends AbstractIdentityBackend { > + private Connection connection; > + private String driver; > + private String url; > + private String user; > + private String password; > + private static final Logger LOG = LoggerFactory.getLogger( > MySQLIdentityBackend.class); > + private String identityTable; > + private String keyInfoTable; > + > + /** > + * Constructing an instance using specified config that contains > anything > + * to be used to initialize an MySQL Backend. > + * @param config . The config is used to config the backend. > + */ > + public MySQLIdentityBackend(final Config config) { > + setConfig(config); > + } > + > + public MySQLIdentityBackend() { } > + > + /** > + * Start the MySQL connection. > + */ > + private void startConnection() throws KrbException { > + try { > + Class.forName(driver); > + connection = DriverManager.getConnection(url, user, > password); > + if (!connection.isClosed()) { > + LOG.info("Succeeded in connecting to MySQL."); > + } > + } catch (ClassNotFoundException e) { > + throw new KrbException("JDBC Driver Class not found. ", e); > + } catch (SQLException e) { > + throw new KrbException("Failed to connecting to MySQL. ", e); > + } > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected void doInitialize() throws KrbException { > + LOG.info("Initializing the MySQL identity backend."); > + driver = getConfig().getString(MySQLConfKey.MYSQL_DRIVER, true); > + user = getConfig().getString(MySQLConfKey.MYSQL_USER, true); > + password = getConfig().getString(MySQLConfKey.MYSQL_PASSWORD, > true); > + > + String urlString = > + getConfig().getString(MySQLConfKey.MYSQL_URL, > true); > + if (urlString == null || urlString.isEmpty()) { > + urlString = > + getBackendConfig().getString(MySQLConfKey.MYSQL_URL, > true); > + } > + url = urlString; > + > + ResultSet resCheckTable = null; > + PreparedStatement preInitialize = null; > + PreparedStatement preKdcRealm = null; > + ResultSet resKdcRealm = null; > + PreparedStatement preIdentity = null; > + PreparedStatement preKey = null; > + try { > + startConnection(); > + > + resCheckTable = connection.getMetaData().getTables(null, > null, "kdc_config", null); > + if (resCheckTable.next()) { > + // Set initialized for kdc config table if HAS enabled > + String stmInitialize = "UPDATE `kdc_config` SET > initialized = true WHERE id = 1"; > + preInitialize = connection.prepareStatement( > stmInitialize); > + preInitialize.executeUpdate(); > + > + // Get identity table name according to realm of kdc > + String stmKdcRealm = "SELECT realm FROM `kdc_config`"; > + preKdcRealm = connection.prepareStatement(stmKdcRealm); > + resKdcRealm = preKdcRealm.executeQuery(); > + if (resKdcRealm.next()) { > + String realm = resKdcRealm.getString("realm") > .toLowerCase(); > + identityTable = "`" + realm + "_identity" + "`"; > + keyInfoTable = "`" + realm + "_key" + "`"; > + } else { > + throw new KrbException("Failed to get kdc config."); > + } > + } else { > + identityTable = "`" + "kerby_identity" + "`"; > + keyInfoTable = "`" + "kerby_key" + "`"; > + } > + > + // Create identity table > + String stmIdentity = "CREATE TABLE IF NOT EXISTS " + > identityTable > + + " (principal varchar(255) NOT NULL, key_version > + INTEGER > " > + + "DEFAULT 1, kdc_flags INTEGER DEFAULT 0, disabled bool " > + + "DEFAULT NULL, locked bool DEFAULT NULL, created_time " > + + "VARCHAR(255) DEFAULT NULL, expire_time VARCHAR(255) " > + + "DEFAULT NULL, PRIMARY KEY (principal) ) ENGINE=INNODB " > + + "DEFAULT CHARSET=utf8;"; > + preIdentity = connection.prepareStatement(stmIdentity); > + preIdentity.executeUpdate(); > + > + // Create key table > + String stmKey = "CREATE TABLE IF NOT EXISTS " + keyInfoTable > + + " (key_id INTEGER NOT NULL AUTO_INCREMENT, key_type " > + + "VARCHAR(255) DEFAULT NULL, kvno INTEGER DEFAULT -1, " > + + "key_value BLOB DEFAULT NULL, principal > + VARCHAR(255) > NOT NULL," > + + "PRIMARY KEY (key_id), INDEX (principal), FOREIGN KEY " > + + "(principal) REFERENCES " + identityTable + > "(principal) " > + + ") ENGINE=INNODB DEFAULT CHARSET=utf8;"; > + preKey = connection.prepareStatement(stmKey); > + preKey.executeUpdate(); > + > + } catch (SQLException e) { > + LOG.error("Error occurred while initialize MySQL > + backend." + > e.toString()); > + throw new KrbException("Failed to create table in database. > ", e); > + } finally { > + DbUtils.closeQuietly(resCheckTable); > + DbUtils.closeQuietly(preInitialize); > + DbUtils.closeQuietly(preKdcRealm); > + DbUtils.closeQuietly(resKdcRealm); > + DbUtils.closeQuietly(preIdentity); > + DbUtils.closeQuietly(preKey); > + doStop(); > + } > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected void doStop() throws KrbException { > + try { > + closeConnection(); > + if (connection.isClosed()) { > + LOG.info("Succeeded in closing connection with MySQL."); > + } > + } catch (SQLException e) { > + LOG.error("Failed to close connection with MySQL."); > + throw new KrbException("Failed to close connection with > MySQL. ", e); > + } > + } > + > + /** > + * Close the connection for stop(). > + * @throws SQLException if SQLException handled > + */ > + private void closeConnection() throws SQLException { > + if (!connection.isClosed()) { > + connection.close(); > + } > + } > + > + /** > + * Convert a KerberosTime type object to a generalized time form > + of > String. > + * @param kerberosTime The kerberos time to convert > + */ > + private String toGeneralizedTime(final KerberosTime kerberosTime) { > + GeneralizedTime generalizedTime = new > GeneralizedTime(kerberosTime.getValue()); > + return generalizedTime.toString(); > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected KrbIdentity doAddIdentity(KrbIdentity identity) throws > KrbException { > + String principalName = identity.getPrincipalName(); > + int keyVersion = identity.getKeyVersion(); > + int kdcFlags = identity.getKdcFlags(); > + boolean disabled = identity.isDisabled(); > + boolean locked = identity.isLocked(); > + String createdTime = toGeneralizedTime(identity. > getCreatedTime()); > + String expireTime = toGeneralizedTime(identity.getExpireTime()); > + Map<EncryptionType, EncryptionKey> keys = identity.getKeys(); > + > + PreparedStatement preIdentity = null; > + PreparedStatement preKey = null; > + > + KrbIdentity duplicateIdentity = doGetIdentity(principalName); > + if (duplicateIdentity != null) { > + LOG.warn("The identity maybe duplicate."); > + > + return duplicateIdentity; > + } else { > + try { > + startConnection(); > + connection.setAutoCommit(false); > + > + // Insert identity to identity table > + String stmIdentity = "insert into " + identityTable > + + " (principal, key_version, kdc_flags, > + disabled, > locked, created_time, expire_time)" > + + " values(?, ?, ?, ?, ?, ?, ?)"; > + preIdentity = connection.prepareStatement(stmIdentity); > + preIdentity.setString(1, principalName); > + preIdentity.setInt(2, keyVersion); > + preIdentity.setInt(3, kdcFlags); > + preIdentity.setBoolean(4, disabled); > + preIdentity.setBoolean(5, locked); > + preIdentity.setString(6, createdTime); > + preIdentity.setString(7, expireTime); > + preIdentity.executeUpdate(); > + > + // Insert keys to key table > + for (Map.Entry<EncryptionType, EncryptionKey> entry : > keys.entrySet()) { > + String stmKey = "insert into " + keyInfoTable + " > (key_type, kvno, key_value, principal)" > + + " values(?, ?, ?, ?)"; > + preKey = connection.prepareStatement(stmKey); > + preKey.setString(1, entry.getKey().getName()); > + preKey.setInt(2, entry.getValue().getKvno()); > + preKey.setBlob(3, new SerialBlob(entry.getValue(). > getKeyData())); > + preKey.setString(4, principalName); > + preKey.executeUpdate(); > + } > + > + connection.commit(); > + return identity; > + } catch (SQLException e) { > + try { > + LOG.info("Transaction is being rolled back."); > + connection.rollback(); > + } catch (SQLException ex) { > + throw new KrbException("Transaction roll back failed. > ", ex); > + } > + LOG.error("Error occurred while adding identity."); > + throw new KrbException("Failed to add identity. ", e); > + } finally { > + DbUtils.closeQuietly(preIdentity); > + DbUtils.closeQuietly(preKey); > + doStop(); > + } > + } > + } > + > + /** > + * Create kerberos time. > + * @param generalizedTime generalized time > + * @throws ParseException parse exception > + */ > + private KerberosTime createKerberosTime(final String > + generalizedTime) > throws ParseException { > + long time = new GeneralizedTime(generalizedTime).getTime(); > + return new KerberosTime(time); > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected KrbIdentity doGetIdentity(final String principalName) > throws KrbException { > + KrbIdentity krbIdentity = new KrbIdentity(principalName); > + > + PreparedStatement preIdentity = null; > + ResultSet resIdentity = null; > + PreparedStatement preKey = null; > + ResultSet resKey = null; > + try { > + startConnection(); > + > + // Get identity from identity table > + String stmIdentity = "SELECT * FROM " + identityTable + " > where principal = ?"; > + preIdentity = connection.prepareStatement(stmIdentity); > + preIdentity.setString(1, principalName); > + resIdentity = preIdentity.executeQuery(); > + > + if (!resIdentity.isBeforeFirst()) { > + return null; > + } > + > + while (resIdentity.next()) { > + krbIdentity.setKeyVersion(resIdentity.getInt("key_ > version")); > + krbIdentity.setKdcFlags(resIdentity.getInt("kdc_flags")); > + krbIdentity.setDisabled(resIdentity.getBoolean(" > disabled")); > + krbIdentity.setLocked(resIdentity.getBoolean("locked")); > + krbIdentity.setCreatedTime(createKerberosTime( > resIdentity.getString("created_time"))); > + krbIdentity.setExpireTime(createKerberosTime( > resIdentity.getString("expire_time"))); > + } > + > + // Get keys from key table > + List<EncryptionKey> keys = new ArrayList<>(); > + String stmKey = "SELECT * FROM " + keyInfoTable + " where > principal = ?"; > + preKey = connection.prepareStatement(stmKey); > + preKey.setString(1, principalName); > + resKey = preKey.executeQuery(); > + while (resKey.next()) { > + int kvno = resKey.getInt("kvno"); > + String keyType = resKey.getString("key_type"); > + EncryptionType eType = EncryptionType.fromName(keyType); > + byte[] keyValue = resKey.getBytes("key_value"); > + EncryptionKey key = new EncryptionKey(eType, > + keyValue, > kvno); > + keys.add(key); > + } > + > + krbIdentity.addKeys(keys); > + return krbIdentity; > + } catch (SQLException e) { > + LOG.error("Error occurred while getting identity."); > + throw new KrbException("Failed to get identity. ", e); > + } catch (ParseException e) { > + throw new KrbException("Failed to get identity. ", e); > + } finally { > + DbUtils.closeQuietly(preIdentity); > + DbUtils.closeQuietly(resIdentity); > + DbUtils.closeQuietly(preKey); > + DbUtils.closeQuietly(resKey); > + doStop(); > + } > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected KrbIdentity doUpdateIdentity(KrbIdentity identity) > + throws > KrbException { > + String principalName = identity.getPrincipalName(); > + try { > + doDeleteIdentity(principalName); // Delete former identity > + doAddIdentity(identity); // Insert new identity > + } catch (KrbException e) { > + LOG.error("Error occurred while updating identity: " + > principalName); > + throw new KrbException("Failed to update identity. ", e); > + } > + > + return getIdentity(principalName); > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected void doDeleteIdentity(String principalName) throws > KrbException { > + PreparedStatement preKey = null; > + PreparedStatement preIdentity = null; > + try { > + startConnection(); > + connection.setAutoCommit(false); > + > + // Delete keys from key table > + String stmKey = "DELETE FROM " + keyInfoTable + " where > principal = ?"; > + preKey = connection.prepareStatement(stmKey); > + preKey.setString(1, principalName); > + preKey.executeUpdate(); > + > + // Dlete identity from identity table > + String stmIdentity = "DELETE FROM " + identityTable + " > + where > principal = ? "; > + preIdentity = connection.prepareStatement(stmIdentity); > + preIdentity.setString(1, principalName); > + preIdentity.executeUpdate(); > + > + connection.commit(); > + } catch (SQLException e) { > + try { > + LOG.info("Transaction is being rolled back."); > + connection.rollback(); > + } catch (SQLException ex) { > + throw new KrbException("Transaction roll back failed. > + ", > ex); > + } > + LOG.error("Error occurred while deleting identity."); > + throw new KrbException("Failed to delete identity. ", e); > + } finally { > + DbUtils.closeQuietly(preIdentity); > + DbUtils.closeQuietly(preKey); > + doStop(); > + } > + } > + > + /** > + * {@inheritDoc} > + */ > + @Override > + protected Iterable<String> doGetIdentities() throws KrbException { > + List<String> identityNames = new ArrayList<>(); > + PreparedStatement preSmt = null; > + ResultSet result = null; > + try { > + startConnection(); > + String statement = "SELECT * FROM " + identityTable; > + preSmt = connection.prepareStatement(statement); > + result = preSmt.executeQuery(); > + while (result.next()) { > + identityNames.add(result.getString("principal")); > + } > + result.close(); > + preSmt.close(); > + } catch (SQLException e) { > + LOG.error("Error occurred while getting identities."); > + throw new KrbException("Failed to get identities. ", e); > + } finally { > + DbUtils.closeQuietly(preSmt); > + DbUtils.closeQuietly(result); > + doStop(); > + } > + > + return identityNames; > + } > +} > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/mysql-backend/src/test/java/ > org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.ja > va > ---------------------------------------------------------------------- > diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java > b/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java > new file mode 100644 > index 0000000..565a0ee > --- /dev/null > +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendKdcTest.java > @@ -0,0 +1,78 @@ > +/** > + * 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.kerby.kerberos.kerb.identity.backend; > + > +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey; > +import org.apache.kerby.kerberos.kerb.KrbException; > +import org.apache.kerby.kerberos.kerb.server.KdcConfigKey; > +import org.apache.kerby.kerberos.kerb.server.KdcTestBase; > +import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket; > +import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket; > +import org.junit.After; > +import org.junit.Assert; > +import org.junit.Test; > + > +import java.io.File; > + > +import static org.assertj.core.api.Assertions.assertThat; > + > +public class MySQLBackendKdcTest extends KdcTestBase { > + private static File testDir = new > +File(System.getProperty("test.dir", > "target")); > + private static File dbFile = new File(testDir, > + "mysqlbackend.mv.db"); > + > + @After > + public void tearDown() { > + if (dbFile.exists() && !dbFile.delete()) { > + System.err.println("Failed to delete the test database > file."); > + } > + } > + > + @Override > + protected void prepareKdc() throws KrbException { > + BackendConfig backendConfig = > + getKdcServer().getBackendConfig(); > + > + backendConfig.setString(KdcConfigKey.KDC_IDENTITY_BACKEND, > + "org.apache.kerby.kerberos.kdc.identitybackend. > MySQLIdentityBackend"); > + backendConfig.setString(MySQLConfKey.MYSQL_DRIVER, > "org.h2.Driver"); > + backendConfig.setString(MySQLConfKey.MYSQL_URL, > + "jdbc:h2:" + testDir.getAbsolutePath() + > "/mysqlbackend;MODE=MySQL"); > + backendConfig.setString(MySQLConfKey.MYSQL_USER, "root"); > + backendConfig.setString(MySQLConfKey.MYSQL_PASSWORD, > + "123456"); > + > + super.prepareKdc(); > + } > + > + @Test > + public void testKdc() { > + TgtTicket tgt; > + SgtTicket tkt; > + > + try { > + tgt = getKrbClient().requestTgt(getClientPrincipal(), > getClientPassword()); > + assertThat(tgt).isNotNull(); > + > + tkt = getKrbClient().requestSgt(tgt, getServerPrincipal()); > + assertThat(tkt).isNotNull(); > + } catch (Exception e) { > + Assert.fail("Exception occurred with good password. " > + + e.toString()); > + } > + } > +} > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/mysql-backend/src/test/java/ > org/apache/kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java > ---------------------------------------------------------------------- > diff --git a/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java > b/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java > new file mode 100644 > index 0000000..59f3500 > --- /dev/null > +++ b/kerby-backend/mysql-backend/src/test/java/org/apache/ > kerby/kerberos/kerb/identity/backend/MySQLBackendTest.java > @@ -0,0 +1,57 @@ > +/** > + * 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.kerby.kerberos.kerb.identity.backend; > + > +import org.apache.kerby.config.Conf; > +import org.apache.kerby.kerberos.kdc.identitybackend.MySQLConfKey; > +import org.apache.kerby.kerberos.kdc.identitybackend. > MySQLIdentityBackend; > +import org.apache.kerby.kerberos.kerb.KrbException; > +import org.junit.AfterClass; > +import org.junit.BeforeClass; > + > +import java.io.File; > +import java.io.IOException; > + > +public class MySQLBackendTest extends BackendTestBase { > + private static File testDir = new > +File(System.getProperty("test.dir", > "target")); > + private static File dbFile = new File(testDir, > + "mysqlbackend.mv.db"); > + > + @BeforeClass > + public static void setup() throws KrbException, IOException { > + Conf config = new Conf(); > + config.setString(MySQLConfKey.MYSQL_DRIVER, "org.h2.Driver"); > + config.setString(MySQLConfKey.MYSQL_URL, > + "jdbc:h2:" + testDir.getCanonicalPath() + > "/mysqlbackend;MODE=MySQL"); > + config.setString(MySQLConfKey.MYSQL_USER, "root"); > + config.setString(MySQLConfKey.MYSQL_PASSWORD, "123456"); > + backend = new MySQLIdentityBackend(config); > + backend.initialize(); > + } > + > + @AfterClass > + public static void tearDown() throws KrbException { > + if (backend != null) { > + backend.stop(); > + } > + if (dbFile.exists() && !dbFile.delete()) { > + System.err.println("Failed to delete the test database > file."); > + } > + } > +} > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-backend/pom.xml > ---------------------------------------------------------------------- > diff --git a/kerby-backend/pom.xml b/kerby-backend/pom.xml index > ef95b87..6ce432c 100644 > --- a/kerby-backend/pom.xml > +++ b/kerby-backend/pom.xml > @@ -53,6 +53,7 @@ > <module>ldap-backend</module> > <module>mavibot-backend</module> > <module>zookeeper-backend</module> > + <module>mysql-backend</module> > </modules> > </profile> > </profiles> > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-dist/kdc-dist/conf/backend.conf > ---------------------------------------------------------------------- > diff --git a/kerby-dist/kdc-dist/conf/backend.conf > b/kerby-dist/kdc-dist/conf/backend.conf > index 2ead268..20134ef 100644 > --- a/kerby-dist/kdc-dist/conf/backend.conf > +++ b/kerby-dist/kdc-dist/conf/backend.conf > @@ -22,3 +22,7 @@ embedded_zk = false > zk_host = 127.0.0.1 > zk_port = 2181 > data_dir = /tmp/zookeeper/data > +mysql_driver = org.drizzle.jdbc.DrizzleDriver mysql_url = > +jdbc:mysql:thin://127.0.0.1:3306/mysqlbackend?createDB=true > +mysql_user = root > +mysql_password = passwd > > http://git-wip-us.apache.org/repos/asf/directory-kerby/ > blob/11089e86/kerby-dist/kdc-dist/pom.xml > ---------------------------------------------------------------------- > diff --git a/kerby-dist/kdc-dist/pom.xml b/kerby-dist/kdc-dist/pom.xml > index 1766d28..3a5de2d 100644 > --- a/kerby-dist/kdc-dist/pom.xml > +++ b/kerby-dist/kdc-dist/pom.xml > @@ -89,6 +89,13 @@ > <version>${gson.version}</version> > </dependency> > > + <!-- For mysql backend --> > + <dependency> > + <groupId>org.apache.kerby</groupId> > + <artifactId>mysql-backend</artifactId> > + <version>${project.version}</version> > + </dependency> > + > <!-- For common and misc --> > <dependency> > <groupId>org.slf4j</groupId> > > -- Colm O hEigeartaigh Talend Community Coder http://coders.talend.com
