blob: 80fc10b2e54e86ef21b27434fff02f01011bea28 [file] [log] [blame]
/**
* 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.admin.kadmin.local;
import org.apache.kerby.KOptions;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
import org.apache.kerby.kerberos.kerb.keytab.Keytab;
import org.apache.kerby.kerberos.kerb.server.KdcConfig;
import org.apache.kerby.kerberos.kerb.server.KdcSetting;
import org.apache.kerby.kerberos.kerb.server.KdcUtil;
import org.apache.kerby.kerberos.kerb.server.ServerSetting;
import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
import org.apache.kerby.kerberos.kerb.common.KrbUtil;
import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The implementation of admin side admin facilities for local mode.
*/
public class LocalKadminImpl implements LocalKadmin {
private static final Logger LOG = LoggerFactory.getLogger(LocalKadminImpl.class);
private final ServerSetting serverSetting;
private final IdentityBackend backend;
/**
* Construct with prepared AdminServerConfig and BackendConfig.
*
* @param kdcConfig The kdc config
* @param backendConfig The backend config
* @throws KrbException e
*/
public LocalKadminImpl(KdcConfig kdcConfig,
BackendConfig backendConfig) throws KrbException {
this.backend = KdcUtil.getBackend(backendConfig);
this.serverSetting = new KdcSetting(kdcConfig, backendConfig);
}
//
public LocalKadminImpl(ServerSetting serverSetting) throws KrbException {
this.backend = KdcUtil.getBackend(serverSetting.getBackendConfig());
this.serverSetting = serverSetting;
}
/**
* Construct with prepared conf dir.
*
* @param confDir The path of conf dir
* @throws KrbException e
*/
public LocalKadminImpl(File confDir) throws KrbException {
KdcConfig tmpKdcConfig = KdcUtil.getKdcConfig(confDir);
if (tmpKdcConfig == null) {
tmpKdcConfig = new KdcConfig();
}
BackendConfig tmpBackendConfig = KdcUtil.getBackendConfig(confDir);
if (tmpBackendConfig == null) {
tmpBackendConfig = new BackendConfig();
}
this.serverSetting = new KdcSetting(tmpKdcConfig, tmpBackendConfig);
backend = KdcUtil.getBackend(tmpBackendConfig);
}
/**
* Construct with prepared AdminServerSetting and Backend.
*
* @param kdcSetting The kdc setting
* @param backend The identity backend
*/
public LocalKadminImpl(KdcSetting kdcSetting, IdentityBackend backend) {
this.serverSetting = kdcSetting;
this.backend = backend;
}
/**
* Get the tgs principal name.
*/
private String getTgsPrincipal() {
return KrbUtil.makeTgsPrincipal(serverSetting.getKdcRealm()).getName();
}
@Override
public String getKadminPrincipal() {
return KrbUtil.makeKadminPrincipal(serverSetting.getKdcRealm()).getName();
}
@Override
public void checkBuiltinPrincipals() throws KrbException {
String tgsPrincipal = getTgsPrincipal();
String kadminPrincipal = getKadminPrincipal();
if (backend.getIdentity(tgsPrincipal) == null
|| backend.getIdentity(kadminPrincipal) == null) {
String errorMsg = "The built-in principals do not exist in backend,"
+ " please run the kdcinit tool.";
LOG.error(errorMsg);
throw new KrbException(errorMsg);
}
}
@Override
public void createBuiltinPrincipals() throws KrbException {
String tgsPrincipal = getTgsPrincipal();
if (backend.getIdentity(tgsPrincipal) == null) {
addPrincipal(tgsPrincipal);
} else {
String errorMsg = "The tgs principal already exists in backend.";
LOG.error(errorMsg);
throw new KrbException(errorMsg);
}
String kadminPrincipal = getKadminPrincipal();
if (backend.getIdentity(kadminPrincipal) == null) {
addPrincipal(kadminPrincipal);
} else {
String errorMsg = "The kadmin principal already exists in backend.";
LOG.error(errorMsg);
throw new KrbException(errorMsg);
}
}
@Override
public void deleteBuiltinPrincipals() throws KrbException {
deletePrincipal(getTgsPrincipal());
deletePrincipal(getKadminPrincipal());
}
@Override
public KdcConfig getKdcConfig() {
return serverSetting.getKdcConfig();
}
@Override
public BackendConfig getBackendConfig() {
return serverSetting.getBackendConfig();
}
@Override
public IdentityBackend getIdentityBackend() {
return backend;
}
@Override
public void addPrincipal(String principal) throws KrbException {
principal = fixPrincipal(principal);
addPrincipal(principal, new KOptions());
}
@Override
public void addPrincipal(String principal, KOptions kOptions)
throws KrbException {
principal = fixPrincipal(principal);
KrbIdentity identity = AdminHelper.createIdentity(principal, kOptions);
List<EncryptionKey> keys = EncryptionUtil.generateKeys(
getKdcConfig().getEncryptionTypes());
identity.addKeys(keys);
backend.addIdentity(identity);
}
@Override
public void addPrincipal(String principal, String password)
throws KrbException {
principal = fixPrincipal(principal);
addPrincipal(principal, password, new KOptions());
}
@Override
public void addPrincipal(String principal, String password, KOptions kOptions)
throws KrbException {
principal = fixPrincipal(principal);
KrbIdentity identity = AdminHelper.createIdentity(principal, kOptions);
List<EncryptionKey> keys = EncryptionUtil.generateKeys(principal, password,
getKdcConfig().getEncryptionTypes());
identity.addKeys(keys);
backend.addIdentity(identity);
}
@Override
public void exportKeytab(File keytabFile, String principal)
throws KrbException {
principal = fixPrincipal(principal);
List<String> principals = new ArrayList<>(1);
principals.add(principal);
exportKeytab(keytabFile, principals);
}
@Override
public void exportKeytab(File keytabFile, List<String> principals)
throws KrbException {
//Get Identity
List<KrbIdentity> identities = new LinkedList<>();
for (String principal : principals) {
KrbIdentity identity = backend.getIdentity(principal);
if (identity == null) {
throw new KrbException("Can not find the identity for pincipal "
+ principal);
}
identities.add(identity);
}
AdminHelper.exportKeytab(keytabFile, identities);
}
@Override
public void exportKeytab(File keytabFile) throws KrbException {
Keytab keytab = AdminHelper.createOrLoadKeytab(keytabFile);
Iterable<String> principals = backend.getIdentities();
for (String principal : principals) {
KrbIdentity identity = backend.getIdentity(principal);
if (identity != null) {
AdminHelper.exportToKeytab(keytab, identity);
}
}
AdminHelper.storeKeytab(keytab, keytabFile);
}
@Override
public void removeKeytabEntriesOf(File keytabFile, String principal)
throws KrbException {
principal = fixPrincipal(principal);
AdminHelper.removeKeytabEntriesOf(keytabFile, principal);
}
@Override
public void removeKeytabEntriesOf(File keytabFile, String principal, int kvno)
throws KrbException {
principal = fixPrincipal(principal);
AdminHelper.removeKeytabEntriesOf(keytabFile, principal, kvno);
}
@Override
public void removeOldKeytabEntriesOf(File keytabFile, String principal)
throws KrbException {
principal = fixPrincipal(principal);
AdminHelper.removeOldKeytabEntriesOf(keytabFile, principal);
}
@Override
public void deletePrincipal(String principal) throws KrbException {
principal = fixPrincipal(principal);
backend.deleteIdentity(principal);
}
@Override
public void modifyPrincipal(String principal, KOptions kOptions)
throws KrbException {
principal = fixPrincipal(principal);
KrbIdentity identity = backend.getIdentity(principal);
if (identity == null) {
throw new KrbException("Principal \""
+ principal + "\" does not exist.");
}
AdminHelper.updateIdentity(identity, kOptions);
backend.updateIdentity(identity);
}
@Override
public void renamePrincipal(String oldPrincipalName, String newPrincipalName)
throws KrbException {
oldPrincipalName = fixPrincipal(oldPrincipalName);
newPrincipalName = fixPrincipal(newPrincipalName);
KrbIdentity oldIdentity = backend.getIdentity(newPrincipalName);
if (oldIdentity != null) {
throw new KrbException("Principal \""
+ oldIdentity.getPrincipalName() + "\" is already exist.");
}
KrbIdentity identity = backend.getIdentity(oldPrincipalName);
if (identity == null) {
throw new KrbException("Principal \""
+ oldPrincipalName + "\" does not exist.");
}
backend.deleteIdentity(oldPrincipalName);
identity.setPrincipalName(newPrincipalName);
identity.setPrincipal(new PrincipalName(newPrincipalName));
backend.addIdentity(identity);
}
@Override
public KrbIdentity getPrincipal(String principalName) throws KrbException {
KrbIdentity identity = backend.getIdentity(principalName);
return identity;
}
@Override
public List<String> getPrincipals() throws KrbException {
Iterable<String> principalNames = backend.getIdentities();
List<String> principalList = new LinkedList<>();
Iterator<String> iterator = principalNames.iterator();
while (iterator.hasNext()) {
principalList.add(iterator.next());
}
return principalList;
}
@Override
public List<String> getPrincipals(String globString) throws KrbException {
Pattern pt = AdminHelper.getPatternFromGlobPatternString(globString);
if (pt == null) {
return getPrincipals();
}
Boolean containsAt = pt.pattern().indexOf('@') != -1;
List<String> result = new LinkedList<>();
List<String> principalNames = getPrincipals();
for (String principal: principalNames) {
String toMatch = containsAt ? principal : principal.split("@")[0];
Matcher m = pt.matcher(toMatch);
if (m.matches()) {
result.add(principal);
}
}
return result;
}
@Override
public void changePassword(String principal,
String newPassword) throws KrbException {
principal = fixPrincipal(principal);
KrbIdentity identity = backend.getIdentity(principal);
if (identity == null) {
throw new KrbException("Principal " + principal
+ "was not found. Please check the input and try again");
}
List<EncryptionKey> keys = EncryptionUtil.generateKeys(principal, newPassword,
getKdcConfig().getEncryptionTypes());
identity.addKeys(keys);
backend.updateIdentity(identity);
}
@Override
public void updateKeys(String principal) throws KrbException {
principal = fixPrincipal(principal);
KrbIdentity identity = backend.getIdentity(principal);
if (identity == null) {
throw new KrbException("Principal " + principal
+ "was not found. Please check the input and try again");
}
List<EncryptionKey> keys = EncryptionUtil.generateKeys(
getKdcConfig().getEncryptionTypes());
identity.addKeys(keys);
backend.updateIdentity(identity);
}
@Override
public void release() throws KrbException {
if (backend != null) {
backend.stop();
}
}
/**
* get size of principal
*/
@Override
public int size() throws KrbException {
return this.getPrincipals().size();
}
/**
* Fix principal name, making it complete.
*
* @param principal The principal name
*/
private String fixPrincipal(String principal) {
if (!principal.contains("@")) {
principal += "@" + serverSetting.getKdcRealm();
}
return principal;
}
}