use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class AuthorizationUtil method getAppAuthorizingUser.
/**
* Helper function to get the authorizing user for app deployment, the authorzing user will be the app owner if it
* is present. If not, it will be the namespace owner. If that is also not present, it will be the user who is making
* the request
*/
public static String getAppAuthorizingUser(OwnerAdmin ownerAdmin, AuthenticationContext authenticationContext, ApplicationId applicationId, @Nullable KerberosPrincipalId appOwner) throws IOException {
KerberosPrincipalId effectiveOwner = SecurityUtil.getEffectiveOwner(ownerAdmin, applicationId.getNamespaceId(), appOwner == null ? null : appOwner.getPrincipal());
// CDAP-13154 If impersonation is configured for either the application or namespace the effective owner will be
// a kerberos principal which can have different form
// (refer: https://docs.oracle.com/cd/E21455_01/common/tutorials/kerberos_principal.html). For example it can be
// a complete principal name (alice/somehost.net@someREALM). For authorization we need the enforcement to happen
// on the username and not the complete principal. The user name is the shortname of the principal so return the
// shortname as authorizing user.
String appAuthorizingUser = effectiveOwner != null ? new KerberosName(effectiveOwner.getPrincipal()).getShortName() : authenticationContext.getPrincipal().getName();
LOG.trace("Returning {} as authorizing app user for {}", appAuthorizingUser, applicationId);
return appAuthorizingUser;
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class InMemoryOwnerStore method getOwners.
@Override
public synchronized <T extends NamespacedEntityId> Map<T, KerberosPrincipalId> getOwners(Set<T> ids) {
ids.forEach(this::validate);
Map<T, KerberosPrincipalId> result = new HashMap<>();
for (T id : ids) {
KerberosPrincipalId principalId = ownerInfo.get(id);
if (principalId != null) {
result.put(id, principalId);
}
}
return result;
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class DefaultOwnerAdmin method getImpersonationPrincipal.
@Nullable
@Override
public String getImpersonationPrincipal(NamespacedEntityId entityId) throws IOException {
entityId = getEffectiveEntity(entityId);
KerberosPrincipalId effectiveOwner = null;
if (!entityId.getEntityType().equals(EntityType.NAMESPACE)) {
effectiveOwner = ownerStore.getOwner(entityId);
}
// (CDAP-8176) Since no owner was found for the entity return namespace principal if present.
return effectiveOwner != null ? effectiveOwner.getPrincipal() : getNamespaceConfig(entityId).getPrincipal();
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class DefaultOwnerAdmin method getImpersonationInfo.
@Nullable
@Override
public ImpersonationInfo getImpersonationInfo(NamespacedEntityId entityId) throws AccessException {
try {
entityId = getEffectiveEntity(entityId);
if (!entityId.getEntityType().equals(EntityType.NAMESPACE)) {
KerberosPrincipalId effectiveOwner = ownerStore.getOwner(entityId);
if (effectiveOwner != null) {
return new ImpersonationInfo(effectiveOwner.getPrincipal(), SecurityUtil.getKeytabURIforPrincipal(effectiveOwner.getPrincipal(), cConf));
}
}
// (CDAP-8176) Since no owner was found for the entity return namespace principal if present.
NamespaceConfig nsConfig = getNamespaceConfig(entityId.getNamespaceId());
return nsConfig.getPrincipal() == null ? null : new ImpersonationInfo(nsConfig.getPrincipal(), nsConfig.getKeytabURI());
} catch (IOException e) {
throw AuthEnforceUtil.propagateAccessException(e);
}
}
use of io.cdap.cdap.proto.id.KerberosPrincipalId in project cdap by caskdata.
the class DatasetInstanceService method create.
/**
* Creates a dataset instance.
*
* @param namespaceId the namespace to create the dataset instance in
* @param name the name of the new dataset instance
* @param props the properties for the new dataset instance
* @throws NamespaceNotFoundException if the specified namespace was not found
* @throws DatasetAlreadyExistsException if a dataset with the same name already exists
* @throws DatasetTypeNotFoundException if the dataset type was not found
* @throws UnauthorizedException if perimeter security and authorization are enabled, and the current user does not
* have {@link StandardPermission#UPDATE} privilege on the #instance's namespace
*/
void create(String namespaceId, String name, DatasetInstanceConfiguration props) throws Exception {
NamespaceId namespace = ConversionHelpers.toNamespaceId(namespaceId);
DatasetId datasetId = ConversionHelpers.toDatasetInstanceId(namespaceId, name);
Principal requestingUser = authenticationContext.getPrincipal();
String ownerPrincipal = props.getOwnerPrincipal();
// need to enforce on the principal id if impersonation is involved
KerberosPrincipalId effectiveOwner = SecurityUtil.getEffectiveOwner(ownerAdmin, namespace, ownerPrincipal);
if (DatasetsUtil.isUserDataset(datasetId)) {
LOG.trace("Authorizing impersonation for dataset {}", name);
if (effectiveOwner != null) {
accessEnforcer.enforce(effectiveOwner, requestingUser, AccessPermission.SET_OWNER);
}
accessEnforcer.enforce(datasetId, requestingUser, StandardPermission.CREATE);
LOG.trace("Authorized impersonation for dataset {}", name);
}
LOG.trace("Ensuring existence of namespace {} for dataset {}", namespace, name);
ensureNamespaceExists(namespace);
LOG.trace("Ensured existence of namespace {} for dataset {}", namespace, name);
LOG.trace("Retrieving instance metadata from MDS for dataset {}", name);
DatasetSpecification existing = instanceManager.get(datasetId);
if (existing != null) {
throw new DatasetAlreadyExistsException(datasetId);
}
LOG.trace("Retrieved instance metadata from MDS for dataset {}", name);
// for creation, we need enforcement for dataset type for user dataset, but bypass for system datasets
DatasetTypeMeta typeMeta = getTypeInfo(namespace, props.getTypeName(), !DatasetsUtil.isUserDataset(datasetId));
if (typeMeta == null) {
// Type not found in the instance's namespace and the system namespace. Bail out.
throw new DatasetTypeNotFoundException(ConversionHelpers.toDatasetTypeId(namespace, props.getTypeName()));
}
LOG.info("Creating dataset {}.{}, type name: {}, properties: {}", namespaceId, name, props.getTypeName(), props.getProperties());
// exists or not
if (ownerPrincipal != null) {
LOG.trace("Adding owner for dataset {}", name);
KerberosPrincipalId owner = new KerberosPrincipalId(ownerPrincipal);
ownerAdmin.add(datasetId, owner);
LOG.trace("Added owner {} for dataset {}", owner, name);
}
try {
DatasetProperties datasetProperties = DatasetProperties.builder().addAll(props.getProperties()).setDescription(props.getDescription()).build();
LOG.trace("Calling op executor service to configure dataset {}", name);
DatasetCreationResponse response = opExecutorClient.create(datasetId, typeMeta, datasetProperties);
LOG.trace("Received spec and metadata from op executor service for dataset {}: {}", name, response);
LOG.trace("Adding instance metadata for dataset {}", name);
DatasetSpecification spec = response.getSpec();
instanceManager.add(namespace, spec);
LOG.trace("Added instance metadata for dataset {}", name);
metaCache.invalidate(datasetId);
LOG.trace("Publishing audit for creation of dataset {}", name);
publishAudit(datasetId, AuditType.CREATE);
LOG.trace("Published audit for creation of dataset {}", name);
SystemMetadata metadata = response.getMetadata();
LOG.trace("Publishing system metadata for creation of dataset {}: {}", name, metadata);
publishMetadata(datasetId, metadata);
LOG.trace("Published system metadata for creation of dataset {}", name);
// Enable explore
enableExplore(datasetId, spec, props);
} catch (Exception e) {
// there was a problem in creating the dataset instance so delete the owner if it got added earlier
// safe to call for entities which does not have an owner too
ownerAdmin.delete(datasetId);
throw e;
}
}
Aggregations