Skip to content

Commit

Permalink
Fix to avoid endless loop (stack overflow) in baseContext processing.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Feb 15, 2016
1 parent d187161 commit d50fd44
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
Expand Up @@ -528,7 +528,7 @@ private static ResourceObjectPattern convertToPattern(ResourceObjectPatternType
return resourceObjectPattern;
}

static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefinition objectClassDef, ResourceType resourceType,
public static RefinedObjectClassDefinition parseFromSchema(ObjectClassComplexTypeDefinition objectClassDef, ResourceType resourceType,
RefinedResourceSchema rSchema,
PrismContext prismContext, String contextDescription) throws SchemaException {

Expand Down
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2015 Evolveum
* Copyright (c) 2015-2016 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,10 +17,12 @@

import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.common.refinery.RefinedResourceSchema;
import com.evolveum.midpoint.prism.ComplexTypeDefinition;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance;
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.CommunicationException;
Expand Down Expand Up @@ -52,6 +54,7 @@ public class ProvisioningContext extends StateReporter {
private PrismObject<ShadowType> originalShadow;
private ResourceShadowDiscriminator shadowCoordinates;
private Collection<QName> additionalAuxiliaryObjectClassQNames;
private boolean useRefinedDefinition = true;

private RefinedObjectClassDefinition objectClassDefinition;
private Task task;
Expand Down Expand Up @@ -101,6 +104,14 @@ public void setAdditionalAuxiliaryObjectClassQNames(Collection<QName> additional
this.additionalAuxiliaryObjectClassQNames = additionalAuxiliaryObjectClassQNames;
}

public boolean isUseRefinedDefinition() {
return useRefinedDefinition;
}

public void setUseRefinedDefinition(boolean useRefinedDefinition) {
this.useRefinedDefinition = useRefinedDefinition;
}

public ResourceType getResource() throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException {
if (resource == null) {
if (resourceOid == null) {
Expand All @@ -123,10 +134,23 @@ public RefinedResourceSchema getRefinedSchema() throws SchemaException, Configur

public RefinedObjectClassDefinition getObjectClassDefinition() throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException {
if (objectClassDefinition == null) {
if (originalShadow != null) {
objectClassDefinition = getRefinedSchema().determineCompositeObjectClassDefinition(originalShadow, additionalAuxiliaryObjectClassQNames);
} else if (shadowCoordinates != null && !shadowCoordinates.isWildcard()) {
objectClassDefinition = getRefinedSchema().determineCompositeObjectClassDefinition(shadowCoordinates);
if (useRefinedDefinition) {
if (originalShadow != null) {
objectClassDefinition = getRefinedSchema().determineCompositeObjectClassDefinition(originalShadow, additionalAuxiliaryObjectClassQNames);
} else if (shadowCoordinates != null && !shadowCoordinates.isWildcard()) {
objectClassDefinition = getRefinedSchema().determineCompositeObjectClassDefinition(shadowCoordinates);
}
} else {
if (shadowCoordinates.getObjectClass() == null) {
throw new IllegalStateException("No objectclass");
}
ObjectClassComplexTypeDefinition origObjectClassDefinition = getRefinedSchema().getOriginalResourceSchema().findObjectClassDefinition(shadowCoordinates.getObjectClass());
if (origObjectClassDefinition == null) {
throw new SchemaException("No object class definition for "+shadowCoordinates.getObjectClass()+" in original resource schema for "+getResource());
} else {
objectClassDefinition = RefinedObjectClassDefinition.parseFromSchema(origObjectClassDefinition, getResource(), getRefinedSchema(), getResource().asPrismObject().getPrismContext(),
"objectclass "+origObjectClassDefinition+" in "+getResource());
}
}
}
return objectClassDefinition;
Expand Down
Expand Up @@ -98,6 +98,8 @@ PrismObject<ShadowType> resolve(ProvisioningContext ctx, ResourceObjectReference
}
}
ProvisioningContext subctx = ctx.spawn(objectClass);
// Use "raw" definitions from the original schema to avoid endless loops
subctx.setUseRefinedDefinition(false);
subctx.assertDefinition();

ObjectQuery refQuery = QueryJaxbConvertor.createObjectQuery(ShadowType.class, resourceObjectReference.getFilter(), prismContext);
Expand Down
Expand Up @@ -2384,6 +2384,40 @@ public void test458ListSpecialGroupsKindIntent() throws Exception {
assertShadows(23);
}

/**
* List organizationUnits with intent ou-people. There are no sub-ous in People.
* But the definition has objectclass organizationalUnit and it has baseContext that
* is also organizationalUnit. This test therefore makes sure this will not end up
* in endless loop (stack overflow).
*/
@Test
public void test460ListOrganizationalUnitPeopleKindIntent() throws Exception {
final String TEST_NAME = "test460ListOrganizationalUnitPeopleKindIntent";
TestUtil.displayTestTile(TEST_NAME);

Task task = taskManager.createTaskInstance(TestOpenDJ.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();

ObjectQuery query = ObjectQueryUtil.createResourceAndKindIntent(RESOURCE_OPENDJ_OID,
ShadowKindType.GENERIC, "ou-people", prismContext);
display("query", query);

// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> objects = provisioningService.searchObjects(ShadowType.class, query, null, task, result);

// THEN
TestUtil.displayThen(TEST_NAME);
display("found objects", objects);
result.computeStatus();
TestUtil.assertSuccess(result);

// Just the ou=People itself
assertEquals("Wrong number of objects found", 1, objects.size());

assertShadows(24);
}

@Test
public void test701ConfiguredCapabilityNoRead() throws Exception{
final String TEST_NAME = "test701ConfiguredCapabilityNoRead";
Expand Down
Expand Up @@ -194,6 +194,32 @@
<fetchStrategy>minimal</fetchStrategy>
</attribute>
</objectType>

<objectType>
<!-- OrganizationUnit with base context pointing to organizationUnit.
Make sure this won't end up in an endless loop. -->
<kind>generic</kind>
<intent>ou-people</intent>
<displayName>Organizational Unit</displayName>
<objectClass>ri:organizationalUnit</objectClass>
<baseContext>
<objectClass>ri:organizationalUnit</objectClass>
<filter>
<q:equal>
<q:path>attributes/dn</q:path>
<q:value>ou=People,dc=example,dc=com</q:value>
</q:equal>
</filter>
</baseContext>
<attribute>
<ref>ri:entryUUID</ref>
<matchingRule>mr:stringIgnoreCase</matchingRule>
</attribute>
<attribute>
<ref>ri:dn</ref>
<matchingRule>mr:distinguishedName</matchingRule>
</attribute>
</objectType>

</schemaHandling>

Expand Down

0 comments on commit d50fd44

Please sign in to comment.