Search in sources :

Example 21 with KerberosPrincipalId

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;
}
Also used : KerberosName(org.apache.hadoop.security.authentication.util.KerberosName) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId)

Example 22 with KerberosPrincipalId

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;
}
Also used : HashMap(java.util.HashMap) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId)

Example 23 with KerberosPrincipalId

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();
}
Also used : KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) Nullable(javax.annotation.Nullable)

Example 24 with KerberosPrincipalId

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);
    }
}
Also used : NamespaceConfig(io.cdap.cdap.proto.NamespaceConfig) IOException(java.io.IOException) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) Nullable(javax.annotation.Nullable)

Example 25 with KerberosPrincipalId

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;
    }
}
Also used : DatasetProperties(io.cdap.cdap.api.dataset.DatasetProperties) DatasetSpecification(io.cdap.cdap.api.dataset.DatasetSpecification) DatasetTypeMeta(io.cdap.cdap.proto.DatasetTypeMeta) DatasetCreationResponse(io.cdap.cdap.data2.datafabric.dataset.service.executor.DatasetCreationResponse) HandlerException(io.cdap.cdap.common.HandlerException) NotFoundException(io.cdap.cdap.common.NotFoundException) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) DatasetTypeNotFoundException(io.cdap.cdap.common.DatasetTypeNotFoundException) NamespaceNotFoundException(io.cdap.cdap.common.NamespaceNotFoundException) IOException(java.io.IOException) DatasetAlreadyExistsException(io.cdap.cdap.common.DatasetAlreadyExistsException) ExecutionException(java.util.concurrent.ExecutionException) DatasetNotFoundException(io.cdap.cdap.common.DatasetNotFoundException) DatasetId(io.cdap.cdap.proto.id.DatasetId) SystemMetadata(io.cdap.cdap.data2.metadata.system.SystemMetadata) DatasetAlreadyExistsException(io.cdap.cdap.common.DatasetAlreadyExistsException) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) DatasetTypeNotFoundException(io.cdap.cdap.common.DatasetTypeNotFoundException) KerberosPrincipalId(io.cdap.cdap.proto.id.KerberosPrincipalId) Principal(io.cdap.cdap.proto.security.Principal)

Aggregations

KerberosPrincipalId (io.cdap.cdap.proto.id.KerberosPrincipalId)50 UnauthorizedException (io.cdap.cdap.security.spi.authorization.UnauthorizedException)14 IOException (java.io.IOException)14 NotFoundException (io.cdap.cdap.common.NotFoundException)12 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)12 ExecutionException (java.util.concurrent.ExecutionException)12 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)10 InvalidArtifactException (io.cdap.cdap.common.InvalidArtifactException)10 ArtifactSummary (io.cdap.cdap.api.artifact.ArtifactSummary)8 ApplicationNotFoundException (io.cdap.cdap.common.ApplicationNotFoundException)8 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)8 DatasetId (io.cdap.cdap.proto.id.DatasetId)8 Principal (io.cdap.cdap.proto.security.Principal)8 AccessException (io.cdap.cdap.api.security.AccessException)6 ArtifactAlreadyExistsException (io.cdap.cdap.common.ArtifactAlreadyExistsException)6 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)6 BadRequestException (io.cdap.cdap.common.BadRequestException)6 NamespaceNotFoundException (io.cdap.cdap.common.NamespaceNotFoundException)6 Nullable (javax.annotation.Nullable)6 Test (org.junit.Test)6