Skip to content

8290368: Introduce LDAP and RMI protocol-specific object factory filters to JNDI implementation #10578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

AlekseiEfimov
Copy link
Member

@AlekseiEfimov AlekseiEfimov commented Oct 5, 2022

Summary of the change

This change introduces new system and security properties for specifying factory filters for the JNDI/LDAP and the JNDI/RMI JDK provider implementations.

These new properties allow more granular control over the set of object factories allowed to reconstruct Java objects from LDAP and RMI contexts.

The new factory filters are supplementing the existing jdk.jndi.object.factoriesFilter global factories filter to determine if a specific object factory is permitted to instantiate objects for the given protocol.

Links:

List of code changes

  • Implementation for two new system and security properties have been added to the com.sun.naming.internal.ObjectFactoriesFilter class
  • java.security and module-info.java files have been updated with a documentation for the new properties
  • To keep API of javax.naming.spi.NamingManager and javax.naming.spi.DirectoryManager classes unmodified a new internal com.sun.naming.internal.NamingManagerHelper class has been introduced. All getObjectInstance calls have been updated to use the new helper class.

NamingManagerHelper changes

Changes performed to construct the NamingManagerHelper class:

  • DirectoryManager.getObjectInstance -> NamingManagerHelper.getDirObjectInstance. Dependant methods were also moved to the NamingManagerHelper class
  • NamingManager.getObjectInstance -> NamingManagerHelper.getObjectInstance. Methods responsible for setting/getting object factory builder were moved to the NamingManagerHelper class too.

Test changes

New tests have been added for checking that new factory filters can be used to restrict reconstruction of Java objects from LDAP and RMI contexts:

  • LDAP protocol specific test: test/jdk/com/sun/jndi/ldap/objects/factory/LdapFactoriesFilterTest.java
  • RMI protocol specific test: test/jdk/com/sun/jndi/rmi/registry/objects/RmiFactoriesFilterTest.java
    Existing test/jdk/javax/naming/module/RunBasic.java test has been updated to allow test-specific factories filter used to reconstruct objects from the test LDAP server.

Testing

tier1-tier3 and JNDI regression/JCK tests not showing any failures related to this change.
No failures observed for the modified regression tests.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires a CSR request to be approved

Issues

  • JDK-8290368: Introduce LDAP and RMI protocol-specific object factory filters to JNDI implementation
  • JDK-8291556: Introduce LDAP and RMI protocol-specific object factory filters to JNDI implementation (CSR)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/10578/head:pull/10578
$ git checkout pull/10578

Update a local copy of the PR:
$ git checkout pull/10578
$ git pull https://git.openjdk.org/jdk pull/10578/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 10578

View PR using the GUI difftool:
$ git pr show -t 10578

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/10578.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 5, 2022

👋 Welcome back aefimov! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added csr Pull request needs approved CSR before integration rfr Pull request is ready for review labels Oct 5, 2022
@openjdk
Copy link

openjdk bot commented Oct 5, 2022

@AlekseiEfimov The following labels will be automatically applied to this pull request:

  • core-libs
  • security

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added security security-dev@openjdk.org core-libs core-libs-dev@openjdk.org labels Oct 5, 2022
@mlbridge
Copy link

mlbridge bot commented Oct 5, 2022

@dfuch
Copy link
Member

dfuch commented Oct 6, 2022

I am glad to see this RFE. It looks like a big change but most of it is actually reorganisation of internal code, so thanks for explaining its making off :-) It helps a lot for the review. I have looked at the code and I believe it looks good. I don't see any alternative to the reorganisation that could make the changes smaller - so I'm OK with the proposed solution. Thanks for documenting the new properties in their respective module info, as well as in the security properties file.

I had only a cursory look at the tests but they seem comprehensive. Good work.

@dfuch
Copy link
Member

dfuch commented Oct 6, 2022

I am approving on the condition to make sure that all JNDI tests (as well as tier1, tier2, tier3) are run before integrating.

@dfuch
Copy link
Member

dfuch commented Oct 6, 2022

Also please get an approval from a security-libs maintainer for the changes to the security properties file before integrating.

Copy link
Contributor

@RogerRiggs RogerRiggs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, but a few comments.

return checkInput("rmi", () -> clz);
}

private static boolean checkInput(String scheme, FactoryInfo factoryInfo) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This construct in which the supplied lambda fills in the serialClass is pretty obscure.
Perhaps the variable name can be "serialClass" to match the only non-default method in ObjectInputFilter would give a better hint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - serialClass name reads better.

Copy link
Contributor

@RogerRiggs RogerRiggs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

* @return true - if the factory is allowed to be instantiated; false - otherwise
*/
public static boolean canInstantiateObjectsFactory(Class<?> factoryClass) {
return checkInput(() -> factoryClass);
public static boolean checkGlobalFilter(Class<?> serialClass) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the serialClass param should be renamed to factoryClass or something like that, since I think the serialClass reference comes from serialization/deserialization usage.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name comes from ObjectInputFilter.FilterInfo - it's been renamed from factoryClassto make it clear that the supplied lambda fills-in the non-default ObjectInputFilter.FilterInfo.serialClass() method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for that clarification, Aleksei. This sounds fine to me then.

# set of object factory classes which will be allowed to instantiate objects from object
# references bound to LDAP contexts. The factory class named by the reference instance will
# be matched against this filter. The filter property supports pattern-based filter syntax
# with the same format as jdk.serialFilter.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Aleksei, as far as I can see the jdk.serialFilter allows for additional details like limits (example: maxdepth=value). Should we note here that this JNDI specific property will ignore those configurations?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, worth noting, but I would say they are "unused", not ignored.

# "java.naming/com.sun.jndi.ldap.**;!*".
#
# The default pattern value allows any object factory class defined in the java.naming module
# to be specified by the reference instance, but rejects any other.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this instead say:

The default pattern value allows any object factory class belonging to the com.sun.jndi.ldap and its sub-packages of the java.naming module to be specified by the reference instance...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep a filter default value explanation sentences simpler since exact default values are listed just one line after.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you have here is OK with me then.

@@ -113,108 +108,14 @@ public class NamingManager {
*/
public static synchronized void setObjectFactoryBuilder(
Copy link
Member

@jaikiran jaikiran Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps remove the synchronized from this method and the getter, now that the synchronization has moved to the NamingManagerHelper class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - I think it is safe to remove synchronized. I doubt that there is a code that relies on synchronized (javax.naming.spi.NamingManager.class) to prevent other code setting the factory builder (also it can be set only once), therefore it should be ok to remove synchronized.

#
# Each pattern is matched against the factory class name to allow or disallow it's
# Each class name pattern is matched against the factory class name to allow or disallow its
Copy link
Member

@dfuch dfuch Oct 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that for those protocols for which there is no specific filter, a factory class will be accepted only if the global filter returns ALLOWED - which contradicts what is written here (where it says that the class is allowed if it's not REJECTED). Is this something that has changed with this fix - or was the documentation wrong before?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good catch Daniel! It is with this fix and I believe the code needs to be change to match what is written for the global filter here:
What we've had before in checkInput:

    private static boolean checkInput(FactoryInfo factoryInfo) {
        Status result = GLOBAL.checkInput(factoryInfo);
        return result != Status.REJECTED;

What we have now:

        if (filter == GLOBAL_FILTER) {
            return globalResult == Status.ALLOWED;
        }

I think it needs to be changed to (to match the description for global filter):

        if (filter == GLOBAL_FILTER) {
            return globalResult != Status.REJECTED;
        }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the general composition of filters, it is preferable that UNDECIDED is treated as REJECTED.
That keeps unintentional holes in a filter from being permissive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the general composition of filters, it is preferable that UNDECIDED is treated as REJECTED.
That keeps unintentional holes in a filter from being permissive.

That is a good point Roger. The "java.security" file was updated (4449dda) to match the ObjectFactoriesFilter implementation, ie the global filter treats UNDECIDED as REJECTED. Also, the CSR has been updated to highlight that.

Copy link
Member

@jaikiran jaikiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest state of this PR in 4449dda looks good to me. Thank you Aleksei.

@openjdk openjdk bot removed the csr Pull request needs approved CSR before integration label Oct 18, 2022
@openjdk
Copy link

openjdk bot commented Oct 18, 2022

@AlekseiEfimov This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8290368: Introduce LDAP and RMI protocol-specific object factory filters to JNDI implementation

Reviewed-by: dfuchs, rriggs, jpai

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been no new commits pushed to the master branch. If another commit should be pushed before you perform the /integrate command, your PR will be automatically rebased. If you prefer to avoid any potential automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Oct 18, 2022
@AlekseiEfimov
Copy link
Member Author

/integrate

@openjdk
Copy link

openjdk bot commented Oct 19, 2022

Going to push as commit d37ce4c.
Since your change was applied there have been 2 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Oct 19, 2022
@openjdk openjdk bot closed this Oct 19, 2022
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Oct 19, 2022
@openjdk
Copy link

openjdk bot commented Oct 19, 2022

@AlekseiEfimov Pushed as commit d37ce4c.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@AlekseiEfimov AlekseiEfimov deleted the JDK-8290368_protocol_specific_factory_filters branch March 21, 2023 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core-libs core-libs-dev@openjdk.org integrated Pull request has been integrated security security-dev@openjdk.org
Development

Successfully merging this pull request may close these issues.

4 participants