diff --git a/base/ca/src/main/java/com/netscape/cmscore/dbs/CertificateRepository.java b/base/ca/src/main/java/com/netscape/cmscore/dbs/CertificateRepository.java index 93a8b13def4..538dc9095f7 100644 --- a/base/ca/src/main/java/com/netscape/cmscore/dbs/CertificateRepository.java +++ b/base/ca/src/main/java/com/netscape/cmscore/dbs/CertificateRepository.java @@ -19,10 +19,12 @@ import java.math.BigInteger; import java.security.SecureRandom; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; +import java.util.Iterator; import java.util.Vector; import org.mozilla.jss.netscape.security.x509.CertificateValidity; @@ -1112,6 +1114,35 @@ public Enumeration searchCertificates(String filter, int maxSize, } + /** + * Finds a list of certificate records that satisfies the filter. + * + * The filter should follow RFC1558 LDAP filter syntax. + * For example, + * + * {@Code (&(certRecordId=5)(x509Cert.notBefore=934398398))} + * + * @param filter search filter + * @param timeLimit timeout value + * @param start first entry to return from the list + * @param size max size to return + * @return a list of certificates + * @exception EBaseException failed to search + */ + public Iterator searchCertificates(String filter, int timeLimit, int start, int size) + throws EBaseException { + + ArrayList records = new ArrayList<>(); + logger.debug("searchCertificates filter {filter}, start {start} and size {size}", filter, start, size); + try (DBSSession s = dbSubsystem.createSession()) { + DBSearchResults sr = s.pagedSearch(mBaseDN, filter, start, size, timeLimit); + while (sr.hasMoreElements()) { + records.add((CertRecord) sr.nextElement()); + } + } + return records.iterator(); + } + /** * Finds certificate records. diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/CAServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/CAServlet.java index 6596b49c57e..19ee3e139e4 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/CAServlet.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/CAServlet.java @@ -13,11 +13,19 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +/** + * @author Marco Fargetta + */ public class CAServlet extends HttpServlet { public static final long serialVersionUID = 1L; public void get(HttpServletRequest request, HttpServletResponse response) throws Exception { + response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); + } + + public void post(HttpServletRequest request, HttpServletResponse response) throws Exception { + response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } @Override @@ -33,6 +41,19 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro } } + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { + post(request, response); + + } catch (ServletException | IOException e) { + throw e; + + } catch (Exception e) { + throw new ServletException(e); + } + } + public CAEngine getCAEngine() { ServletContext servletContext = getServletContext(); return (CAEngine) servletContext.getAttribute("engine"); diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CAInfoServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CAInfoServlet.java index b4205c15737..548fbd78761 100644 --- a/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CAInfoServlet.java +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CAInfoServlet.java @@ -1,3 +1,8 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// package org.dogtagpki.server.ca.v2; import java.io.PrintWriter; @@ -13,11 +18,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * @author Marco Fargetta + */ @WebServlet("/v2/info") public class CAInfoServlet extends CAServlet { private static final long serialVersionUID = 1L; private static Logger logger = LoggerFactory.getLogger(CAInfoServlet.class); + @Override public void get(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpSession session = request.getSession(); logger.debug("CAInfoServlet.get(): session: " + session.getId()); diff --git a/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CertServlet.java b/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CertServlet.java new file mode 100644 index 00000000000..54ff2ecf876 --- /dev/null +++ b/base/ca/src/main/java/org/dogtagpki/server/ca/v2/CertServlet.java @@ -0,0 +1,263 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package org.dogtagpki.server.ca.v2; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.security.InvalidKeyException; +import java.security.Principal; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.dogtagpki.server.ca.CAEngine; +import org.dogtagpki.server.ca.CAServlet; +import org.mozilla.jss.netscape.security.pkcs.ContentInfo; +import org.mozilla.jss.netscape.security.pkcs.PKCS7; +import org.mozilla.jss.netscape.security.pkcs.SignerInfo; +import org.mozilla.jss.netscape.security.provider.RSAPublicKey; +import org.mozilla.jss.netscape.security.util.Utils; +import org.mozilla.jss.netscape.security.x509.AlgorithmId; +import org.mozilla.jss.netscape.security.x509.CRLExtensions; +import org.mozilla.jss.netscape.security.x509.CRLReasonExtension; +import org.mozilla.jss.netscape.security.x509.X509CertImpl; +import org.mozilla.jss.netscape.security.x509.X509ExtensionException; +import org.mozilla.jss.netscape.security.x509.X509Key; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.cert.CertData; +import com.netscape.certsrv.cert.CertDataInfo; +import com.netscape.certsrv.cert.CertDataInfos; +import com.netscape.certsrv.cert.CertSearchRequest; +import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.util.JSONSerializer; +import com.netscape.cms.servlet.cert.FilterBuilder; +import com.netscape.cmscore.dbs.CertRecord; +import com.netscape.cmscore.dbs.CertificateRepository; +import com.netscape.cmscore.dbs.RevocationInfo; + +/** + * @author Marco Fargetta + */ +@WebServlet("/v2/certs/*") +public class CertServlet extends CAServlet { + public static final int DEFAULT_MAXTIME = 0; + public static final int DEFAULT_SIZE = 20; + + private static final long serialVersionUID = 1L; + private static Logger logger = LoggerFactory.getLogger(CertServlet.class); + + @Override + public void get(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("CertServlet.get(): session: {}", session.getId()); + + response.setContentType("application/json"); + PrintWriter out = response.getWriter(); + if(request.getPathInfo() != null) { + CertId id = new CertId(request.getPathInfo().substring(1)); + CertData cert; + try { + cert = getCertData(id, request.getLocale()); + out.println(cert.toJSON()); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI()); + } + return; + } + + int maxTime = request.getParameter("maxTime") == null ? + DEFAULT_MAXTIME : Integer.parseInt(request.getParameter("maxTime")); + int size = request.getParameter("size") == null ? + DEFAULT_SIZE : Integer.parseInt(request.getParameter("size")); + int start = request.getParameter("start") == null ? 0 : Integer.parseInt(request.getParameter("start")); + + CertSearchRequest searchElems = CertSearchRequest.fromMap(request.getParameterMap()); + CertDataInfos infos = listCerts(searchElems, maxTime, start, size); + out.println(infos.toJSON()); + } + + @Override + public void post(HttpServletRequest request, HttpServletResponse response) throws Exception { + HttpSession session = request.getSession(); + logger.debug("CertServlet.post(): session: {}", session.getId()); + + if(request.getPathInfo() == null || !request.getPathInfo().equals("/search")) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, request.getRequestURI()); + return; + } + + BufferedReader reader = request.getReader(); + String postMessage = reader.lines().collect(Collectors.joining()); + + CertSearchRequest requestFilter = JSONSerializer.fromJSON(postMessage, CertSearchRequest.class); + int size = request.getParameter("size") == null ? + DEFAULT_SIZE : Integer.parseInt(request.getParameter("size")); + int start = request.getParameter("start") == null ? 0 : Integer.parseInt(request.getParameter("start")); + + CertDataInfos infos = listCerts(requestFilter, start, size); + + response.setContentType("application/json"); + PrintWriter out = response.getWriter(); + out.println(infos.toJSON()); + } + + private CertData getCertData(CertId id, Locale loc) throws Exception { + CAEngine engine = getCAEngine(); + CertificateRepository repo = engine.getCertificateRepository(); + + //find the cert in question + CertRecord certRecord = repo.readCertificateRecord(id.toBigInteger()); + X509CertImpl cert = certRecord.getCertificate(); + + CertData certData = new CertData(); + certData.setSerialNumber(id); + + Principal issuerDN = cert.getIssuerName(); + if (issuerDN != null) certData.setIssuerDN(issuerDN.toString()); + + Principal subjectDN = cert.getSubjectName(); + if (subjectDN != null) certData.setSubjectDN(subjectDN.toString()); + + String base64 = Utils.base64encode(cert.getEncoded(), true); + + certData.setEncoded(base64); + + X509Certificate[] certChain = engine.getCertChain(cert); + + PKCS7 pkcs7 = new PKCS7( + new AlgorithmId[0], + new ContentInfo(new byte[0]), + certChain, + new SignerInfo[0]); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + pkcs7.encodeSignedData(bos, false); + byte[] p7Bytes = bos.toByteArray(); + + String p7Str = Utils.base64encode(p7Bytes, true); + certData.setPkcs7CertChain(p7Str); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + Date notBefore = cert.getNotBefore(); + if (notBefore != null) certData.setNotBefore(sdf.format(notBefore)); + + Date notAfter = cert.getNotAfter(); + if (notAfter != null) certData.setNotAfter(sdf.format(notAfter)); + + certData.setRevokedOn(certRecord.getRevokedOn()); + certData.setRevokedBy(certRecord.getRevokedBy()); + + RevocationInfo revInfo = certRecord.getRevocationInfo(); + if (revInfo != null) { + CRLExtensions revExts = revInfo.getCRLEntryExtensions(); + if (revExts != null) { + try { + CRLReasonExtension ext = (CRLReasonExtension) + revExts.get(CRLReasonExtension.NAME); + certData.setRevocationReason(ext.getReason().getCode()); + } catch (X509ExtensionException e) { + logger.debug("CRL extension error for certificate {}", id.toHexString()); + } + } + } + + certData.setStatus(certRecord.getStatus()); + + return certData; + } + + private CertDataInfos listCerts(CertSearchRequest searchReq, int start, int size) { + return listCerts(searchReq, -1, start, size); + } + + private CertDataInfos listCerts(CertSearchRequest searchReq, int maxTime, int start, int size) { + CAEngine engine = getCAEngine(); + CertificateRepository repo = engine.getCertificateRepository(); + + logger.info("Listing certificates"); + FilterBuilder builder = new FilterBuilder(searchReq); + String filter = builder.buildFilter(); + + logger.info("Search filter: " + filter); + + CertDataInfos infos = new CertDataInfos(); + try { + Iterator e = repo.searchCertificates(filter, maxTime, start, size); + if (e == null) { + throw new EBaseException("search results are null"); + } + + // store non-null results in a list + List results = new ArrayList<>(); + while (e.hasNext()) { + CertRecord rec = e.next(); + if (rec == null) continue; + results.add(createCertDataInfo(rec)); + } + + infos.setTotal(results.size()); + logger.info("Search results: " + results.size()); + infos.setEntries(results); + } catch (Exception e) { + logger.error("Unable to list certificates: " + e.getMessage(), e); + throw new PKIException("Unable to list certificates: " + e.getMessage(), e); + } + + return infos; + } + + private CertDataInfo createCertDataInfo(CertRecord certRecord) throws EBaseException, InvalidKeyException { + CertDataInfo info = new CertDataInfo(); + + CertId id = new CertId(certRecord.getSerialNumber()); + info.setID(id); + + X509Certificate cert = certRecord.getCertificate(); + info.setIssuerDN(cert.getIssuerDN().toString()); + info.setSubjectDN(cert.getSubjectDN().toString()); + info.setStatus(certRecord.getStatus()); + info.setVersion(cert.getVersion()); + info.setType(cert.getType()); + + PublicKey key = cert.getPublicKey(); + if (key instanceof X509Key) { + X509Key x509Key = (X509Key)key; + info.setKeyAlgorithmOID(x509Key.getAlgorithmId().getOID().toString()); + + if (x509Key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) { + RSAPublicKey rsaKey = new RSAPublicKey(x509Key.getEncoded()); + info.setKeyLength(rsaKey.getKeySize()); + } + } + + info.setNotValidBefore(cert.getNotBefore()); + info.setNotValidAfter(cert.getNotAfter()); + + info.setIssuedOn(certRecord.getCreateTime()); + info.setIssuedBy(certRecord.getIssuedBy()); + + info.setRevokedOn(certRecord.getRevokedOn()); + info.setRevokedBy(certRecord.getRevokedBy()); + + return info; + } +} diff --git a/base/common/src/main/java/com/netscape/certsrv/cert/CertDataInfos.java b/base/common/src/main/java/com/netscape/certsrv/cert/CertDataInfos.java index dc0ca8b8668..e373d563c3d 100644 --- a/base/common/src/main/java/com/netscape/certsrv/cert/CertDataInfos.java +++ b/base/common/src/main/java/com/netscape/certsrv/cert/CertDataInfos.java @@ -38,10 +38,11 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.netscape.certsrv.base.DataCollection; +import com.netscape.certsrv.util.JSONSerializer; @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown=true) -public class CertDataInfos extends DataCollection { +public class CertDataInfos extends DataCollection implements JSONSerializer { public Element toDOM(Document document) { diff --git a/base/common/src/main/java/com/netscape/certsrv/cert/CertSearchRequest.java b/base/common/src/main/java/com/netscape/certsrv/cert/CertSearchRequest.java index 67da3c1b61d..1946df9a5b5 100644 --- a/base/common/src/main/java/com/netscape/certsrv/cert/CertSearchRequest.java +++ b/base/common/src/main/java/com/netscape/certsrv/cert/CertSearchRequest.java @@ -22,6 +22,7 @@ import java.io.StringReader; import java.io.StringWriter; +import java.util.Map; import java.util.Objects; import javax.ws.rs.core.MultivaluedMap; @@ -1104,4 +1105,147 @@ public static CertSearchRequest fromXML(String xml) throws Exception { Element rootElement = document.getDocumentElement(); return fromDOM(rootElement); } + + public static CertSearchRequest fromMap(Map elements) { + + CertSearchRequest request = new CertSearchRequest(); + + elements.forEach((key, values) -> { + switch (key) { + case "issuerDN": + request.setIssuerDN(values[0]); + break; + case "serialNumberRangeInUse": + request.setSerialNumberRangeInUse(Boolean.parseBoolean(values[0])); + break; + case "serialTo": + request.setSerialTo(values[0]); + break; + case "serialFrom": + request.setSerialFrom(values[0]); + break; + case "subjectInUse": + request.setSubjectInUse(Boolean.parseBoolean(values[0])); + break; + case "eMail": + request.setEmail(values[0]); + break; + case "commonName": + request.setCommonName(values[0]); + break; + case "userID": + request.setUserID(values[0]); + break; + case "orgUnit": + request.setOrgUnit(values[0]); + break; + case "org": + request.setOrg(values[0]); + break; + case "locality": + request.setLocality(values[0]); + break; + case "state": + request.setState(values[0]); + break; + case "country": + request.setCountry(values[0]); + break; + case "matchExactly": + request.setMatchExactly(Boolean.parseBoolean(values[0])); + break; + case "status": + request.setStatus(values[0]); + break; + case "revokedBy": + request.setRevokedBy(values[0]); + break; + case "revokedOnFrom": + request.setRevokedOnFrom(values[0]); + break; + case "revokedOnTo": + request.setRevokedOnTo(values[0]); + break; + case "revocationReason": + request.setRevocationReason(values[0]); + break; + case "issuedBy": + request.setIssuedBy(values[0]); + break; + case "issuedOnFrom": + request.setIssuedOnFrom(values[0]); + break; + case "issuedOnTo": + request.setIssuedOnTo(values[0]); + break; + case "validNotBeforeFrom": + request.setValidNotBeforeFrom(values[0]); + break; + case "validNotBeforeTo": + request.setValidNotBeforeTo(values[0]); + break; + case "validNotAfterFrom": + request.setValidNotAfterFrom(values[0]); + break; + case "validNotAfterTo": + request.setValidNotAfterTo(values[0]); + break; + case "validityOperation": + request.setValidityOperation(values[0]); + break; + case "validityCount": + request.setValidityCount(Integer.valueOf(values[0])); + break; + case "validityUnit": + request.setValidityUnit(Long.valueOf(values[0])); + break; + case "certTypeSubEmailCA": + request.setCertTypeSubEmailCA(values[0]); + break; + case "certTypeSubSSLCA": + request.setCertTypeSubSSLCA(values[0]); + break; + case "certTypeSecureEmail": + request.setCertTypeSecureEmail(values[0]); + break; + case "certTypeSSLClient": + request.setCertTypeSSLClient(values[0]); + break; + case "certTypeSSLServer": + request.setCertTypeSSLServer(values[0]); + break; + case "revokedByInUse": + request.setRevokedByInUse(Boolean.parseBoolean(values[0])); + break; + case "revokedOnInUse": + request.setRevokedOnInUse(Boolean.parseBoolean(values[0])); + break; + case "revocationReasonInUse": + request.setRevocationReasonInUse(Boolean.parseBoolean(values[0])); + break; + case "issuedByInUse": + request.setIssuedByInUse(Boolean.parseBoolean(values[0])); + break; + case "issuedOnInUse": + request.setIssuedOnInUse(Boolean.parseBoolean(values[0])); + break; + case "validNotBeforeInUse": + request.setValidNotBeforeInUse(Boolean.parseBoolean(values[0])); + break; + case "validNotAfterInUse": + request.setValidNotAfterInUse(Boolean.parseBoolean(values[0])); + break; + case "validityLengthInUse": + request.setValidityLengthInUse(Boolean.parseBoolean(values[0])); + break; + case "certTypeInUse": + request.setCertTypeInUse(Boolean.parseBoolean(values[0])); + break; + default: + } + }); + + return request; + } + } diff --git a/base/server/src/main/java/com/netscape/cmscore/dbs/DBSSession.java b/base/server/src/main/java/com/netscape/cmscore/dbs/DBSSession.java index d6ab1052443..69501234ffe 100644 --- a/base/server/src/main/java/com/netscape/cmscore/dbs/DBSSession.java +++ b/base/server/src/main/java/com/netscape/cmscore/dbs/DBSSession.java @@ -18,9 +18,9 @@ package com.netscape.cmscore.dbs; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.dbs.DBVirtualList; import com.netscape.certsrv.dbs.EDBException; import com.netscape.certsrv.dbs.IDBObj; -import com.netscape.certsrv.dbs.DBVirtualList; import com.netscape.certsrv.dbs.ModificationSet; import netscape.ldap.LDAPSearchResults; @@ -211,6 +211,48 @@ public DBSearchResults search( return null; } + /** + * Retrieves a list of object that satifies the given + * filter. + * + * @param base starting point of the search + * @param filter search filter + * @param start index of the first element + * @param size max number of element in the page + * @return search results + * @exception EBaseException failed to search + */ + public DBSearchResults pagedSearch( + String base, + String filter, + int start, + int size + ) throws EBaseException { + return pagedSearch(base, filter, start, size, -1); + } + + /** + * Retrieves a list of object that satifies the given + * filter. + * + * @param base starting point of the search + * @param filter search filter + * @param start index of the first element + * @param size max number of element in the page + * @param timeLimit timeout limit + * @return search results + * @exception EBaseException failed to search + */ + public DBSearchResults pagedSearch( + String base, + String filter, + int start, + int size, + int timeLimit + ) throws EBaseException { + return null; + } + /** * Sets persistent search to retrieve modified * certificate records. diff --git a/base/server/src/main/java/com/netscape/cmscore/dbs/LDAPSession.java b/base/server/src/main/java/com/netscape/cmscore/dbs/LDAPSession.java index 3624bbb4202..fd5f9a36a68 100644 --- a/base/server/src/main/java/com/netscape/cmscore/dbs/LDAPSession.java +++ b/base/server/src/main/java/com/netscape/cmscore/dbs/LDAPSession.java @@ -32,6 +32,7 @@ import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPAttributeSet; import netscape.ldap.LDAPConnection; +import netscape.ldap.LDAPControl; import netscape.ldap.LDAPEntry; import netscape.ldap.LDAPException; import netscape.ldap.LDAPModification; @@ -40,6 +41,7 @@ import netscape.ldap.LDAPSearchResults; import netscape.ldap.LDAPSortKey; import netscape.ldap.LDAPv3; +import netscape.ldap.controls.LDAPPagedResultsControl; import netscape.ldap.controls.LDAPPersistSearchControl; import netscape.ldap.controls.LDAPSortControl; @@ -474,6 +476,61 @@ public DBSearchResults search(String base, String filter, } } + @Override + public DBSearchResults pagedSearch(String base, String filter, int start, int size, int timeLimit) + throws EBaseException { + try { + String ldapfilter = dbSubsystem.getRegistry().getFilter(filter); + logger.info("LDAPSession.pagedSearch(): Searching {} for {}", base, ldapfilter); + + LDAPSearchConstraints cons = new LDAPSearchConstraints(); + if (timeLimit > 0) { + cons.setServerTimeLimit(timeLimit); + } + LDAPPagedResultsControl pagecon; + LDAPSearchResults res; + int skipped = 0; + int pageSize = start > 0 ? Math.min(start, 500) : Math.min(size, 500); + byte[] cookie = null; + + pagecon = new LDAPPagedResultsControl(false, pageSize); + while (start > 0 && skipped < start) { + cons.setServerControls(pagecon); + res = mConn.search(base, + LDAPv3.SCOPE_ONE, ldapfilter, null, false, cons); + while(res.hasMoreElements()) + res.next(); + skipped += pageSize; + for (LDAPControl c: res.getResponseControls()){ + if(c instanceof LDAPPagedResultsControl resC){ + cookie = resC.getCookie(); + if(cookie!=null){ + pageSize = start - skipped > 0 ? Math.min((start - skipped) , 500) : Math.min(size, 500); + pagecon = new LDAPPagedResultsControl(false, pageSize, cookie); + } else { + res = new LDAPSearchResults(); + return new DBSearchResults(dbSubsystem.getRegistry(), + res); + } + } + } + } + cons.setServerControls(pagecon); + res = mConn.search(base, + LDAPv3.SCOPE_ONE, ldapfilter, null, false, cons); + return new DBSearchResults(dbSubsystem.getRegistry(), + res); + + } catch (LDAPException e) { + if (e.getLDAPResultCode() == LDAPException.UNAVAILABLE) + throw new EDBNotAvailException( + CMS.getUserMessage("CMS_DBS_INTERNAL_DIR_UNAVAILABLE")); + // XXX error handling, should not raise exception if + // entry not found + throw new EDBException("Unable to search LDAP record: " + e.getMessage(), e); + } + } + @Override public LDAPSearchResults persistentSearch(String base, String filter, String attrs[]) throws EBaseException {