Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java
41161 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jndi.ldap;2627import java.security.AccessControlContext;28import java.security.AccessController;29import java.security.PrivilegedActionException;30import java.security.PrivilegedExceptionAction;31import java.util.Vector;32import javax.naming.*;33import javax.naming.directory.*;34import javax.naming.spi.*;35import javax.naming.ldap.*;36import javax.naming.ldap.LdapName;3738import com.sun.jndi.toolkit.ctx.Continuation;3940final class LdapSearchEnumeration41extends AbstractLdapNamingEnumeration<SearchResult> {4243private Name startName; // prefix of names of search results44private LdapCtx.SearchArgs searchArgs = null;4546@SuppressWarnings("removal")47private final AccessControlContext acc = AccessController.getContext();4849LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results,50String starter, LdapCtx.SearchArgs args, Continuation cont)51throws NamingException {5253super(homeCtx, search_results,54args.name, /* listArg */55cont);5657// fully qualified name of starting context of search58startName = new LdapName(starter);59searchArgs = args;60}6162@SuppressWarnings("removal")63@Override64protected SearchResult createItem(String dn, Attributes attrs,65Vector<Control> respCtls)66throws NamingException {6768Object obj = null;6970String relStart; // name relative to starting search context71String relHome; // name relative to homeCtx.currentDN72boolean relative = true; // whether relative to currentDN7374// need to strip off all but lowest component of dn75// so that is relative to current context (currentDN)7677try {78Name parsed = new LdapName(dn);79// System.err.println("dn string: " + dn);80// System.err.println("dn name: " + parsed);8182if (startName != null && parsed.startsWith(startName)) {83relStart = parsed.getSuffix(startName.size()).toString();84relHome = parsed.getSuffix(homeCtx.currentParsedDN.size()).toString();85} else {86relative = false;87relHome = relStart =88LdapURL.toUrlString(homeCtx.hostname, homeCtx.port_number,89dn, homeCtx.hasLdapsScheme);90}91} catch (NamingException e) {92// could not parse name93relative = false;94relHome = relStart =95LdapURL.toUrlString(homeCtx.hostname, homeCtx.port_number,96dn, homeCtx.hasLdapsScheme);97}9899// Name relative to search context100CompositeName cn = new CompositeName();101if (!relStart.isEmpty()) {102cn.add(relStart);103}104105// Name relative to homeCtx106CompositeName rcn = new CompositeName();107if (!relHome.isEmpty()) {108rcn.add(relHome);109}110//System.err.println("relStart: " + cn);111//System.err.println("relHome: " + rcn);112113// Fix attributes to be able to get schema114homeCtx.setParents(attrs, rcn);115116// only generate object when requested117if (searchArgs.cons.getReturningObjFlag()) {118119if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) {120// Entry contains Java-object attributes (ser/ref object)121// serialized object or object reference122try {123PrivilegedExceptionAction<Object> pea = () -> Obj.decodeObject(attrs);124obj = AccessController.doPrivileged(pea, acc);125} catch (PrivilegedActionException e) {126throw (NamingException)e.getException();127}128}129if (obj == null) {130obj = new LdapCtx(homeCtx, dn);131}132133// Call getObjectInstance before removing unrequested attributes134try {135// rcn is either relative to homeCtx or a fully qualified DN136obj = DirectoryManager.getObjectInstance(137obj, rcn, (relative ? homeCtx : null),138homeCtx.envprops, attrs);139} catch (NamingException e) {140throw e;141} catch (Exception e) {142NamingException ne =143new NamingException(144"problem generating object using object factory");145ne.setRootCause(e);146throw ne;147}148149// remove Java attributes from result, if necessary150// Even if CLASSNAME attr not there, there might be some151// residual attributes152153String[] reqAttrs;154if ((reqAttrs = searchArgs.reqAttrs) != null) {155// create an attribute set for those requested156Attributes rattrs = new BasicAttributes(true); // ignore case157for (int i = 0; i < reqAttrs.length; i++) {158rattrs.put(reqAttrs[i], null);159}160for (int i = 0; i < Obj.JAVA_ATTRIBUTES.length; i++) {161// Remove Java-object attributes if not requested162if (rattrs.get(Obj.JAVA_ATTRIBUTES[i]) == null) {163attrs.remove(Obj.JAVA_ATTRIBUTES[i]);164}165}166}167168}169170/*171* name in search result is either the stringified composite name172* relative to the search context that can be passed directly to173* methods of the search context, or the fully qualified DN174* which can be used with the initial context.175*/176SearchResult sr;177if (respCtls != null) {178sr = new SearchResultWithControls(179(relative ? cn.toString() : relStart), obj, attrs,180relative, homeCtx.convertControls(respCtls));181} else {182sr = new SearchResult(183(relative ? cn.toString() : relStart),184obj, attrs, relative);185}186sr.setNameInNamespace(dn);187return sr;188}189190@Override191public void appendUnprocessedReferrals(LdapReferralException ex) {192193// a referral has been followed so do not create relative names194startName = null;195super.appendUnprocessedReferrals(ex);196}197198@Override199protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(200LdapReferralContext refCtx) throws NamingException {201// repeat the original operation at the new context202return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.search(203searchArgs.name, searchArgs.filter, searchArgs.cons);204}205206@Override207protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {208super.update(ne);209210// Update search-specific variables211LdapSearchEnumeration se = (LdapSearchEnumeration)ne;212startName = se.startName;213}214215void setStartName(Name nm) {216startName = nm;217}218}219220221