Patch descriptions .. in reverse order.

Note that the CA setup for authz is further documented at 
pki.fedoraproject.org/wiki/Kra_authz_realm , where I have added a
section on 'CA Configuration".

Thanks, 
Ade

****************************************************************
commit ad1fcecc2f36cc1ebc1f13efe3df9d1e138224b7
Author: Ade Lee <a...@redhat.com>
Date:   Mon May 9 15:00:20 2016 -0400

    Add authz realm check for cert enrollment
    
    Ticket 2041

commit b5232ce101083409ed9a86e9057620cca7288f62
Author: Ade Lee <a...@redhat.com>
Date:   Sat May 7 00:06:08 2016 -0400

    Fix error output when request is rejected
    
    With this fix, error messages are returned to the user when
    a request is rejected - either in the UI or from the pki CLI.
    
    Trac Ticket 1247 (amongst others)

commit 82d18a99103de1fa749b077cfccec5ff65ceb4a5
Author: Ade Lee <a...@redhat.com>
Date:   Wed May 4 18:25:51 2016 -0400

    Add realm to requests coming in from CA
    
    Requests to the KRA through the CA-KRA connector use the Enrollment
    Service.  This has been modified to read and store any realm passed in.
    The realm can be added to the request by havibg the admin add
    a AuthzRealmDefault and AuthzRealmConstraint in a profile.
    
    At this point, all the constraint does is verify that the realm is
    one of a specified list of realms.  More verification will be added
    in a subsequent patch.
    
    No attempt is made yet to allow users to specify the realm.  This
    would need to be added as a ProfileInput.
    
    Part of Ticket 2041
From 82d18a99103de1fa749b077cfccec5ff65ceb4a5 Mon Sep 17 00:00:00 2001
From: Ade Lee <a...@redhat.com>
Date: Wed, 4 May 2016 18:25:51 -0400
Subject: [PATCH 299/301] Add realm to requests coming in from CA

Requests to the KRA through the CA-KRA connector use the Enrollment
Service.  This has been modified to read and store any realm passed in.
The realm can be added to the request by havibg the admin add
a AuthzRealmDefault and AuthzRealmConstraint in a profile.

At this point, all the constraint does is verify that the realm is
one of a specified list of realms.  More verification will be added
in a subsequent patch.

No attempt is made yet to allow users to specify the realm.  This
would need to be added as a ProfileInput.

Part of Ticket 2041
---
 base/ca/shared/conf/registry.cfg                   |   6 ++
 base/ca/src/com/netscape/ca/CAService.java         |  64 ++++++------
 .../netscape/certsrv/connector/IPKIMessage.java    |   6 ++
 .../src/com/netscape/kra/EnrollmentService.java    |  29 +++---
 base/kra/src/com/netscape/kra/KRAService.java      |   3 +-
 .../profile/constraint/AuthzRealmConstraint.java   | 109 +++++++++++++++++++++
 .../cms/profile/def/AuthzRealmDefault.java         |  93 ++++++++++++++++++
 .../cms/servlet/connector/ConnectorServlet.java    |  30 +++---
 base/server/cmsbundle/src/UserMessages.properties  |   6 ++
 .../netscape/cmscore/connector/HttpPKIMessage.java |  13 +++
 10 files changed, 303 insertions(+), 56 deletions(-)
 create mode 100644 base/server/cms/src/com/netscape/cms/profile/constraint/AuthzRealmConstraint.java
 create mode 100644 base/server/cms/src/com/netscape/cms/profile/def/AuthzRealmDefault.java

diff --git a/base/ca/shared/conf/registry.cfg b/base/ca/shared/conf/registry.cfg
index 9cd4e6d5c89b6e9bd0323fd3fd272b4af1de9568..8e62939725e380ae247fab83d602970dc65bdebb 100644
--- a/base/ca/shared/conf/registry.cfg
+++ b/base/ca/shared/conf/registry.cfg
@@ -3,6 +3,9 @@ constraintPolicy.ids=noConstraintImpl,subjectNameConstraintImpl,uniqueSubjectNam
 constraintPolicy.signingAlgConstraintImpl.class=com.netscape.cms.profile.constraint.SigningAlgConstraint
 constraintPolicy.signingAlgConstraintImpl.desc=Signing Algorithm Constraint
 constraintPolicy.signingAlgConstraintImpl.name=Signing Algorithm Constraint
+constraintPolicy.authzRealmConstraintImpl.class=com.netscape.cms.profile.constraint.AuthzRealmConstraint
+constraintPolicy.authzRealmConstraintImpl.desc=Authz Realm Constraint
+constraintPolicy.authzRealmConstraintImpl.name=Authz Realm Constraint
 constraintPolicy.extensionConstraintImpl.class=com.netscape.cms.profile.constraint.ExtensionConstraint
 constraintPolicy.extensionConstraintImpl.desc=Extension Constraint
 constraintPolicy.extensionConstraintImpl.name=Extension Constraint
@@ -76,6 +79,9 @@ defaultPolicy.userSigningAlgDefaultImpl.name=User Supplied Signing Alg Default
 defaultPolicy.signingAlgDefaultImpl.class=com.netscape.cms.profile.def.SigningAlgDefault
 defaultPolicy.signingAlgDefaultImpl.desc=Signing Algorithm Default
 defaultPolicy.signingAlgDefaultImpl.name=Signing Algorithm Default
+defaultPolicy.authzRealmDefaultImpl.class=com.netscape.cms.profile.def.AuthzRealmDefault
+defaultPolicy.authzRealmDefaultImpl.desc=Authz Realm Default
+defaultPolicy.authzRealmDefaultImpl.name=Authz Realm Default
 defaultPolicy.authorityKeyIdentifierExtDefaultImpl.class=com.netscape.cms.profile.def.AuthorityKeyIdentifierExtDefault
 defaultPolicy.authorityKeyIdentifierExtDefaultImpl.desc=Authority Key Identifier Extension Default
 defaultPolicy.authorityKeyIdentifierExtDefaultImpl.name=Authority Key Identifier Extension Default
diff --git a/base/ca/src/com/netscape/ca/CAService.java b/base/ca/src/com/netscape/ca/CAService.java
index db692e3d0ddc10358880fdfb8bb0e14ebf5bd8bd..2b5d5f732b36f5cf6e1e5aa54552a5e4dcc5afaa 100644
--- a/base/ca/src/com/netscape/ca/CAService.java
+++ b/base/ca/src/com/netscape/ca/CAService.java
@@ -31,33 +31,6 @@ import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Vector;
 
-import netscape.security.extensions.CertInfo;
-import netscape.security.util.BigInt;
-import netscape.security.util.DerValue;
-import netscape.security.x509.AlgorithmId;
-import netscape.security.x509.BasicConstraintsExtension;
-import netscape.security.x509.CRLExtensions;
-import netscape.security.x509.CRLReasonExtension;
-import netscape.security.x509.CertificateAlgorithmId;
-import netscape.security.x509.CertificateChain;
-import netscape.security.x509.CertificateExtensions;
-import netscape.security.x509.CertificateIssuerName;
-import netscape.security.x509.CertificateSerialNumber;
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateValidity;
-import netscape.security.x509.Extension;
-import netscape.security.x509.LdapV3DNStrConverter;
-import netscape.security.x509.PKIXExtensions;
-import netscape.security.x509.RevocationReason;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.SerialNumber;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X500NameAttrMap;
-import netscape.security.x509.X509CRLImpl;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509CertInfo;
-import netscape.security.x509.X509ExtensionException;
-
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authority.IAuthority;
 import com.netscape.certsrv.authority.ICertAuthority;
@@ -66,8 +39,8 @@ import com.netscape.certsrv.base.IConfigStore;
 import com.netscape.certsrv.base.MetaInfo;
 import com.netscape.certsrv.base.SessionContext;
 import com.netscape.certsrv.ca.AuthorityID;
-import com.netscape.certsrv.ca.ECAException;
 import com.netscape.certsrv.ca.CANotFoundException;
+import com.netscape.certsrv.ca.ECAException;
 import com.netscape.certsrv.ca.ICAService;
 import com.netscape.certsrv.ca.ICRLIssuingPoint;
 import com.netscape.certsrv.ca.ICertificateAuthority;
@@ -95,6 +68,33 @@ import com.netscape.cmscore.dbs.RevocationInfo;
 import com.netscape.cmscore.util.Debug;
 import com.netscape.cmsutil.util.Utils;
 
+import netscape.security.extensions.CertInfo;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerValue;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateIssuerName;
+import netscape.security.x509.CertificateSerialNumber;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.Extension;
+import netscape.security.x509.LdapV3DNStrConverter;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.SerialNumber;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X500NameAttrMap;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509ExtensionException;
+
 /**
  * Request Service for CertificateAuthority.
  */
@@ -377,11 +377,11 @@ public class CAService implements ICAService, IService {
         // short cut profile-based request
         if (isProfileRequest(request)) {
             try {
-                CMS.debug("CAServic: x0 requestStatus="
+                CMS.debug("CAService: x0 requestStatus="
                         + request.getRequestStatus().toString() + " instance=" + request);
                 serviceProfileRequest(request);
                 request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
-                CMS.debug("CAServic: x1 requestStatus=" + request.getRequestStatus().toString());
+                CMS.debug("CAService: x1 requestStatus=" + request.getRequestStatus().toString());
                 // store a message in the signed audit log file
                 auditMessage = CMS.getLogMessage(
                             LOGGING_SIGNED_AUDIT_PRIVATE_KEY_ARCHIVE_REQUEST,
@@ -394,7 +394,7 @@ public class CAService implements ICAService, IService {
 
                 return true;
             } catch (EBaseException e) {
-                CMS.debug("CAServic: x2 requestStatus=" + request.getRequestStatus().toString());
+                CMS.debug("CAService: x2 requestStatus=" + request.getRequestStatus().toString());
                 // need to put error into the request
                 CMS.debug("CAService: serviceRequest " + e.toString());
                 request.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
@@ -435,6 +435,8 @@ public class CAService implements ICAService, IService {
             return true;
         }
 
+        // NOTE to alee: The request must include the realm by this point.
+
         try {
             // send request to KRA first
             if (type.equals(IRequest.ENROLLMENT_REQUEST) &&
diff --git a/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java b/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
index ca352aa82095e415324785f30b48ffe45145f902..b91af01a1a0a3e95b847c154ed5d7caa21191371 100644
--- a/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
+++ b/base/common/src/com/netscape/certsrv/connector/IPKIMessage.java
@@ -68,4 +68,10 @@ public interface IPKIMessage extends Serializable {
      */
     public void toRequest(IRequest r);
 
+    /**
+     * Retrieves the request realm
+     *
+     * @return String of authz realm
+     */
+    public String getReqRealm();
 }
diff --git a/base/kra/src/com/netscape/kra/EnrollmentService.java b/base/kra/src/com/netscape/kra/EnrollmentService.java
index d1b716cf87072142dde0022c2b6f21ecf2840a49..50e58a3777e60a96553762f4bf8c77f00c287431 100644
--- a/base/kra/src/com/netscape/kra/EnrollmentService.java
+++ b/base/kra/src/com/netscape/kra/EnrollmentService.java
@@ -27,16 +27,6 @@ import java.util.Arrays;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
-import netscape.security.provider.RSAPublicKey;
-import netscape.security.util.BigInt;
-import netscape.security.util.DerInputStream;
-import netscape.security.util.DerOutputStream;
-import netscape.security.util.DerValue;
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateX509Key;
-import netscape.security.x509.X509CertInfo;
-import netscape.security.x509.X509Key;
-
 import org.mozilla.jss.asn1.ASN1Util;
 import org.mozilla.jss.asn1.ASN1Value;
 import org.mozilla.jss.asn1.InvalidBERException;
@@ -72,6 +62,16 @@ import com.netscape.cmscore.crmf.PKIArchiveOptionsContainer;
 import com.netscape.cmscore.dbs.KeyRecord;
 import com.netscape.cmsutil.util.Utils;
 
+import netscape.security.provider.RSAPublicKey;
+import netscape.security.util.BigInt;
+import netscape.security.util.DerInputStream;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
 /**
  * A class represents archival request processor. It
  * passes the request to the policy processor, and
@@ -424,7 +424,7 @@ public class EnrollmentService implements IService {
                     audit(auditMessage);
                     throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_KEYRECORD"));
                 }
-           } else if (keyAlg.equals("EC")) {
+            } else if (keyAlg.equals("EC")) {
 
                 String oidDescription = "UNDETERMINED";
                 // for KeyRecordParser
@@ -474,6 +474,13 @@ public class EnrollmentService implements IService {
                 audit(auditMessage);
                 throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
             }
+
+            // set authz realm if available
+            String realm = request.getRealm();
+            if (realm != null) {
+                rec.set(KeyRecord.ATTR_REALM, realm);
+            }
+
             IKeyRepository storage = mKRA.getKeyRepository();
             BigInteger serialNo = storage.getNextSerialNumber();
 
diff --git a/base/kra/src/com/netscape/kra/KRAService.java b/base/kra/src/com/netscape/kra/KRAService.java
index 06c8ce1d5297309e49ef9ee657e928c1c29b0e33..f57b293b676db1427b34d03a6401d843519175fc 100644
--- a/base/kra/src/com/netscape/kra/KRAService.java
+++ b/base/kra/src/com/netscape/kra/KRAService.java
@@ -42,8 +42,7 @@ import com.netscape.cmscore.util.Debug;
  */
 public class KRAService implements IService {
 
-    public final static String ENROLLMENT =
-            IRequest.ENROLLMENT_REQUEST;
+    public final static String ENROLLMENT = IRequest.ENROLLMENT_REQUEST;
     public final static String RECOVERY = IRequest.KEYRECOVERY_REQUEST;
     public final static String NETKEY_KEYGEN = IRequest.NETKEY_KEYGEN_REQUEST;
     public final static String NETKEY_KEYRECOVERY = IRequest.NETKEY_KEYRECOVERY_REQUEST;
diff --git a/base/server/cms/src/com/netscape/cms/profile/constraint/AuthzRealmConstraint.java b/base/server/cms/src/com/netscape/cms/profile/constraint/AuthzRealmConstraint.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2932a52f29e5411e528f18198b5321798276831
--- /dev/null
+++ b/base/server/cms/src/com/netscape/cms/profile/constraint/AuthzRealmConstraint.java
@@ -0,0 +1,109 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2016 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.constraint;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.profile.def.AuthzRealmDefault;
+import com.netscape.cms.profile.def.NoDefault;
+
+import netscape.security.x509.X509CertInfo;
+
+/**
+ * This class implements the authz realm constraint.
+ * It checks if the authz realm in the certificate
+ * template satisfies the criteria.
+ *
+ * @version $Revision$, $Date$
+ */
+public class AuthzRealmConstraint extends EnrollConstraint {
+
+    public static final String CONFIG_REALMS_ALLOWED = "realmsAllowed";
+
+    public AuthzRealmConstraint() {
+        super();
+        addConfigName(CONFIG_REALMS_ALLOWED);
+    }
+
+    public void init(IProfile profile, IConfigStore config)
+            throws EProfileException {
+        super.init(profile, config);
+    }
+
+    public void setConfig(String name, String value)
+            throws EPropertyException {
+
+        if (mConfig.getSubStore("params") == null) {
+            CMS.debug("AuthzRealmConstraint: mConfig.getSubStore is null");
+            return;
+        }
+
+        CMS.debug("AuthzRealmConstraint: setConfig name=" + name +
+                " value=" + value);
+
+        mConfig.getSubStore("params").putString(name, value);
+    }
+
+    public IDescriptor getConfigDescriptor(Locale locale, String name) {
+        if (name.equals(CONFIG_REALMS_ALLOWED)) {
+            return new Descriptor(IDescriptor.STRING, null, null,
+                    CMS.getUserMessage(locale, "CMS_PROFILE_AUTHZ_REALMS_ALLOWED"));
+        }
+        return null;
+    }
+
+    public String getText(Locale locale) {
+        return CMS.getUserMessage(locale, "CMS_PROFILE_CONSTRAINT_REALM_TEXT",
+                getConfig(CONFIG_REALMS_ALLOWED));
+    }
+
+    public boolean isApplicable(IPolicyDefault def) {
+        if (def instanceof NoDefault)
+            return true;
+        if (def instanceof AuthzRealmDefault)
+            return true;
+        return false;
+    }
+
+    @Override
+    public void validate(IRequest request, X509CertInfo info) throws ERejectException {
+        String realm = request.getRealm();
+        List<String> allowedRealms = Arrays.asList(getConfig(CONFIG_REALMS_ALLOWED).split("\\s*,\\s*"));
+        if (! allowedRealms.contains(realm)) {
+            throw new ERejectException(CMS.getUserMessage(
+                    getLocale(request),
+                    "CMS_PROFILE_AUTHZ_REALM_NOT_MATCHED", realm));
+        }
+
+        // TODO: code here to check authz based on identity
+
+    }
+
+}
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/AuthzRealmDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/AuthzRealmDefault.java
new file mode 100644
index 0000000000000000000000000000000000000000..40fe678e6005ef18084f099f178c68e1996daa8e
--- /dev/null
+++ b/base/server/cms/src/com/netscape/cms/profile/def/AuthzRealmDefault.java
@@ -0,0 +1,93 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2016 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.profile.def;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.property.Descriptor;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.property.IDescriptor;
+import com.netscape.certsrv.request.IRequest;
+
+import netscape.security.x509.X509CertInfo;
+
+public class AuthzRealmDefault extends EnrollDefault {
+
+    public static final String CONFIG_REALM = "realm";
+    public static final String VAL_REALM = "realm";
+
+    public AuthzRealmDefault() {
+        super();
+        addConfigName(CONFIG_REALM);
+        addValueName(VAL_REALM);
+    }
+
+    public void init(IProfile profile, IConfigStore config)
+            throws EProfileException {
+        super.init(profile, config);
+    }
+
+    public IDescriptor getConfigDescriptor(Locale locale, String name) {
+        if (name.equals(CONFIG_REALM)) {
+            return new Descriptor(IDescriptor.STRING, null, null,
+                    CMS.getUserMessage(locale, "CMS_PROFILE_AUTHZ_REALM"));
+        }
+        return null;
+    }
+
+    @Override
+    public IDescriptor getValueDescriptor(Locale locale, String name) {
+        if (name.equals(VAL_REALM)) {
+            return new Descriptor(IDescriptor.STRING, null, null,
+                    CMS.getUserMessage(locale, "CMS_PROFILE_AUTHZ_REALM"));
+        }
+        return null;
+    }
+
+    @Override
+    public String getText(Locale locale) {
+        return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_AUTHZ_REALM",
+                getConfig(CONFIG_REALM));
+    }
+
+    @Override
+    public void populate(IRequest request, X509CertInfo info) throws EProfileException {
+        try {
+            request.setRealm(mapPattern(request, getConfig(CONFIG_REALM)));
+        } catch (IOException e) {
+            CMS.debug("authzRealmDefault: failed to populate request" + e);
+        }
+    }
+
+    @Override
+    public void setValue(String name, Locale locale, X509CertInfo info, String value)
+            throws EPropertyException {
+    }
+
+    @Override
+    public String getValue(String name, Locale locale, X509CertInfo info)
+            throws EPropertyException {
+        return null;
+    }
+
+}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
index 5f1fc4805865920563974b4d09e9ac71371d79d0..eceab03d159bf264ca8d3a2196404083eac7dd08 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -35,18 +35,7 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import netscape.security.x509.CRLExtensions;
-import netscape.security.x509.CRLReasonExtension;
-import netscape.security.x509.CertificateAlgorithmId;
-import netscape.security.x509.CertificateExtensions;
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateValidity;
-import netscape.security.x509.CertificateX509Key;
-import netscape.security.x509.Extension;
-import netscape.security.x509.RevocationReason;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509CertInfo;
+import org.apache.commons.lang.StringUtils;
 
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.AuthToken;
@@ -73,6 +62,19 @@ import com.netscape.cms.servlet.base.CMSServlet;
 import com.netscape.cms.servlet.common.CMSRequest;
 import com.netscape.cmsutil.util.Utils;
 
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CertificateAlgorithmId;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+
 /**
  * Connector servlet
  * process requests from remote authority -
@@ -594,6 +596,10 @@ public class ConnectorServlet extends CMSServlet {
 
             thisreq.setExtData(IRequest.AUTH_TOKEN, token);
 
+            if (StringUtils.isNotEmpty(msg.getReqRealm())) {
+                thisreq.setRealm(msg.getReqRealm());
+            }
+
             // setting requestor type must come after copy contents. because
             // requestor is a regular attribute.
             thisreq.setExtData(IRequest.REQUESTOR_TYPE,
diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties
index 57c85c03d6d2caf82b81f232dbbe6064a6626c2d..ff7a4767a7f2feed7dbded43ec18f79e0b1251dd 100644
--- a/base/server/cmsbundle/src/UserMessages.properties
+++ b/base/server/cmsbundle/src/UserMessages.properties
@@ -867,6 +867,9 @@ CMS_PROFILE_SUBJECT_NAME_NOT_UNIQUE=Subject Name Not Unique {0}
 CMS_PROFILE_SIGNING_ALGORITHMS_ALLOWED=Allowed Signing Algorithms
 CMS_PROFILE_SIGNING_ALGORITHM_NOT_MATCHED=Signing Algorithm Not Matched {0}
 CMS_PROFILE_SIGNING_ALGORITHM_NOT_FOUND=Signing Algorithm Not Found
+CMS_PROFILE_AUTHZ_REALM=Authz realm
+CMS_PROFILE_AUTHZ_REALM_NOT_MATCHED=Authz realm not matched {0}
+CMS_PROFILE_AUTHZ_REALMS_ALLOWED=Allowed Authz realms
 CMS_PROFILE_OIDS=Comma-Separated list of Object Identifiers
 CMS_PROFILE_SSL_CLIENT=SSL Client
 CMS_PROFILE_SSL_SERVER=SSL Server
@@ -948,6 +951,8 @@ CMS_PROFILE_CONSTRAINT_USER_SUBJECT_NAME_TEXT=This constraint accepts user subje
 CMS_PROFILE_CONSTRAINT_VALIDITY_TEXT=This constraint rejects the validity that is not between {0} days.
 CMS_PROFILE_CONSTRAINT_RENEWAL_GRACE_PERIOD_TEXT=This constraint rejects the renewal requests that are outside of the grace period {0}
 CMS_PROFILE_CONSTRAINT_VALIDITY_RENEWAL_TEXT=This constraint rejects the validity that is not between {0} days. If renewal, grace period is {1} days before and {2} days after the expiration date of the original certificate.
+CMS_PROFILE_CONSTRAINT_REALM_TEXT=This constraint accepts only specified authorization realms.
+
 CMS_PROFILE_DEF_SIA_TEXT=This default populates a Subject Info Access Extension (1.3.6.1.5.5.7.1.11) to the request. The default values are Criticality={0}, {1}
 CMS_PROFILE_DEF_AIA_TEXT=This default populates a Authority Info Access Extension (1.3.6.1.5.5.7.1.1) to the request. The default values are Criticality={0}, {1}
 CMS_PROFILE_DEF_IMAGE=This default populates the image from the user.
@@ -984,6 +989,7 @@ CMS_PROFILE_INHIBIT_ANY_POLICY_WRONG_SKIP_CERTS=The value for skipped certificat
 CMS_PROFILE_DEF_USER_EXT=This default populates a User-Supplied Extension ({0}) to the request.
 CMS_PROFILE_DEF_USER_KEY=This default populates a User-Supplied Certificate Key to the request.
 CMS_PROFILE_DEF_USER_SIGNING_ALGORITHM=This default populates a User-Supplied Certificate Signing Algorithm to the request.
+CMS_PROFILE_DEF_AUTHZ_REALM=This default populates an authorization realm.
 CMS_PROFILE_DEF_USER_SUBJECT_NAME=This default populates a User-Supplied Certificate Subject Name to the request.
 CMS_PROFILE_DEF_USER_VALIDITY=This default populates a User-Supplied Certificate Validity to the request.
 CMS_PROFILE_DEF_VALIDITY=This default populates a Certificate Validity to the request. The default values are Range={0} in days
diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
index 4b35662fa063178b1d1eadff17bfc3b421a0af19..8d05ee53ce8f807712738a9b57b6243ca27466fb 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
@@ -43,6 +43,7 @@ public class HttpPKIMessage implements IHttpPKIMessage {
     public String reqType = "";
     public String reqId = "";
     protected String reqStatus = "";
+    protected String reqRealm = "";
     protected Vector<Object> mNameVals = new Vector<Object>(); // sequence of name/vals.
 
     public HttpPKIMessage() {
@@ -60,6 +61,10 @@ public class HttpPKIMessage implements IHttpPKIMessage {
         return reqId;
     }
 
+    public String getReqRealm() {
+        return reqRealm;
+    }
+
     /**
      * copy contents of request to make a simple name/value message.
      */
@@ -69,6 +74,10 @@ public class HttpPKIMessage implements IHttpPKIMessage {
         reqId = r.getRequestId().toString();
         reqStatus = r.getRequestStatus().toString();
 
+        if (r.getRealm() != null) {
+            reqRealm = r.getRealm();
+        }
+
         CMS.debug("HttpPKIMessage.fromRequest: requestId="
                 + r.getRequestId().toString() + " requestStatus=" + reqStatus + " instance=" + r);
 
@@ -136,6 +145,9 @@ public class HttpPKIMessage implements IHttpPKIMessage {
         out.writeObject(reqStatus);
         if (Debug.ON)
             Debug.trace("read object req source status " + reqStatus);
+        out.writeObject(reqRealm);
+        if (Debug.ON)
+            Debug.trace("read object req realm " + reqRealm);
         Enumeration<Object> enum1 = mNameVals.elements();
 
         while (enum1.hasMoreElements()) {
@@ -174,6 +186,7 @@ public class HttpPKIMessage implements IHttpPKIMessage {
         reqType = (String) in.readObject();
         reqId = (String) in.readObject();
         reqStatus = (String) in.readObject();
+        reqRealm = (String) in.readObject();
         mNameVals = new Vector<Object>();
         Object keyorval = null;
 
-- 
2.4.3

From b5232ce101083409ed9a86e9057620cca7288f62 Mon Sep 17 00:00:00 2001
From: Ade Lee <a...@redhat.com>
Date: Sat, 7 May 2016 00:06:08 -0400
Subject: [PATCH 300/301] Fix error output when request is rejected

With this fix, error messages are returned to the user when
a request is rejected - either in the UI or from the pki CLI.

Trac Ticket 1247 (amongst others)
---
 .../src/com/netscape/certsrv/request/IRequest.java | 10 +++++++++
 .../netscape/cms/servlet/cert/CertProcessor.java   | 24 ++++++++++++++--------
 .../cms/servlet/cert/CertRequestInfoFactory.java   |  9 +++++---
 .../cms/servlet/cert/EnrollmentProcessor.java      | 18 +++++++++++++++-
 .../cms/servlet/cert/RenewalProcessor.java         | 16 ++++++++++++++-
 base/server/cmsbundle/src/UserMessages.properties  |  3 ++-
 .../netscape/cmscore/request/ARequestQueue.java    |  4 ++++
 .../cmscore/request/RequestDefaultStub.java        |  4 ++++
 8 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/request/IRequest.java b/base/common/src/com/netscape/certsrv/request/IRequest.java
index 8a002ab134f18cbff7e933f6d66652a2b79f0815..c892dbb1dc5d75d4b44e4e26b584f94717b2457c 100644
--- a/base/common/src/com/netscape/certsrv/request/IRequest.java
+++ b/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -305,6 +305,9 @@ public interface IRequest extends Serializable {
     // String error messages
     public static final String ERROR = "Error";
 
+    // Request Error code
+    public static final String ERROR_CODE = "errorCode";
+
     // authentication realm
     public static final String REALM = "realm";
 
@@ -352,6 +355,13 @@ public interface IRequest extends Serializable {
      */
     public String getError(Locale locale);
 
+    /**
+     * Get error code
+     * @param locale request locale
+     * @return error code
+     */
+    public String getErrorCode(Locale locale);
+
     /**************************************************************
      * ExtData data methods:
      *
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
index e5daf78fd6e006c6f559a6fc3bf9cad6485b64e9..4395a63edba5ca882c8401cfe55ada93b56af8bd 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
@@ -41,6 +41,7 @@ import com.netscape.certsrv.profile.ProfileAttribute;
 import com.netscape.certsrv.profile.ProfileInput;
 import com.netscape.certsrv.request.INotify;
 import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.request.RequestStatus;
 import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.processors.CAProcessor;
@@ -152,14 +153,15 @@ public class CertProcessor extends CAProcessor {
 
     }
 
-    protected String codeToReason(Locale locale, String errorCode) {
-        if (errorCode == null) return null;
+    protected String codeToReason(Locale locale, String errorCode, String errorString, RequestId requestId) {
+        if (errorCode == null)
+            return null;
         if (errorCode.equals("1")) {
-            return CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR");
+            return CMS.getUserMessage(locale, "CMS_PROFILE_INTERNAL_ERROR", requestId.toString());
         } else if (errorCode.equals("2")) {
-            return CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED");
+            return CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED", errorString);
         } else if (errorCode.equals("3")) {
-            return CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED");
+            return CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED", requestId.toString(), errorString);
         }
         return null;
     }
@@ -222,7 +224,7 @@ public class CertProcessor extends CAProcessor {
 
                 CMS.debug("CertProcessor: submit " + e);
                 errorCode = "2";
-                errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED", e.toString());
+                req.setExtData(IRequest.ERROR_CODE, errorCode);
 
                 // do NOT store a message in the signed audit log file
                 // as this errorCode indicates that a process has been
@@ -232,7 +234,8 @@ public class CertProcessor extends CAProcessor {
                 req.setRequestStatus(RequestStatus.REJECTED);
                 CMS.debug("CertProcessor: submit " + e);
                 errorCode = "3";
-                errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED", e.toString());
+                req.setExtData(IRequest.ERROR, e.toString());
+                req.setExtData(IRequest.ERROR_CODE, errorCode);
 
                 // store a message in the signed audit log file
                 auditMessage = CMS.getLogMessage(
@@ -241,7 +244,7 @@ public class CertProcessor extends CAProcessor {
                         ILogger.FAILURE,
                         auditRequesterID,
                         ILogger.SIGNED_AUDIT_REJECTION,
-                        errorReason);
+                        codeToReason(locale, errorCode, e.toString(), req.getRequestId()));
 
                 audit(auditMessage);
             } catch (Throwable e) {
@@ -249,7 +252,10 @@ public class CertProcessor extends CAProcessor {
                 CMS.debug(e);
                 CMS.debug("CertProcessor: submit " + e);
                 errorCode = "1";
-                errorReason = CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR");
+                errorReason = codeToReason(locale, errorCode, null, req.getRequestId());
+                req.setExtData(IRequest.ERROR, errorReason);
+                req.setExtData(IRequest.ERROR_CODE, errorCode);
+
                 auditMessage = CMS.getLogMessage(
                         LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
                         auditSubjectID,
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestInfoFactory.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestInfoFactory.java
index 64e045d0d444934e2184b9603647d7a34de004ae..eeeca4d7c56854d35e37fe534359cac27fe4af76 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestInfoFactory.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestInfoFactory.java
@@ -24,8 +24,6 @@ import javax.ws.rs.Path;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
 
-import netscape.security.x509.X509CertImpl;
-
 import com.netscape.certsrv.cert.CertRequestInfo;
 import com.netscape.certsrv.cert.CertRequestResource;
 import com.netscape.certsrv.cert.CertResource;
@@ -35,6 +33,8 @@ import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.request.RequestStatus;
 
+import netscape.security.x509.X509CertImpl;
+
 public class CertRequestInfoFactory {
 
     public static CertRequestInfo create(IRequest request, UriInfo uriInfo) {
@@ -61,7 +61,10 @@ public class CertRequestInfoFactory {
             info.setOperationResult(CertRequestInfo.RES_SUCCESS);
         } else {
             info.setOperationResult(CertRequestInfo.RES_ERROR);
-            String error = request.getExtDataInString(IRequest.ERROR);
+        }
+
+        String error = request.getExtDataInString(IRequest.ERROR);
+        if (error != null) {
             info.setErrorMessage(error);
         }
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
index 3e92d5948a236fd153414d5faa556b2f805a99b5..02f5c3d1f5fede5b37b1bd554d3d6fd973401453 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
@@ -17,12 +17,16 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cms.servlet.cert;
 
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 
 import javax.servlet.http.HttpServletRequest;
 
+import org.apache.commons.lang.StringUtils;
+
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.IAuthToken;
 import com.netscape.certsrv.base.BadRequestDataException;
@@ -182,7 +186,19 @@ public class EnrollmentProcessor extends CertProcessor {
             // submit request
             ///////////////////////////////////////////////
             String errorCode = submitRequests(locale, profile, authToken, reqs);
-            String errorReason = codeToReason(locale, errorCode);
+            String errorReason = null;
+
+            List<String> errors = new ArrayList<String>();
+            if (errorCode != null) {
+                for (IRequest req: reqs) {
+                    String error = req.getError(locale);
+                    if (error != null) {
+                        String code = req.getErrorCode(locale);
+                        errors.add(codeToReason(locale, code, error, req.getRequestId()));
+                    }
+                }
+                errorReason = StringUtils.join(errors, '\n');
+            }
 
             HashMap<String, Object> ret = new HashMap<String, Object>();
             ret.put(ARG_REQUESTS, reqs);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
index 7e34e4d5eb89b1287bf27ff410eb02bed4afdc1a..87291a08bf915838c0347287f962bd4a6f591e96 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
@@ -19,9 +19,11 @@ package com.netscape.cms.servlet.cert;
 
 import java.math.BigInteger;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 
 import javax.servlet.http.HttpServletRequest;
@@ -219,7 +221,19 @@ public class RenewalProcessor extends CertProcessor {
             // submit request
             ///////////////////////////////////////////////
             String errorCode = submitRequests(locale, profile, authToken, reqs);
-            String errorReason = codeToReason(locale, errorCode);
+            String errorReason = null;
+
+            List<String> errors = new ArrayList<String>();
+            if (errorCode != null) {
+                for (IRequest req: reqs) {
+                    String error = req.getError(locale);
+                    if (error != null) {
+                        String code = req.getErrorCode(locale);
+                        errors.add(codeToReason(locale, code, error, req.getRequestId()));
+                    }
+                }
+                errorReason = StringUtils.join(errors, '\n');
+            }
 
             HashMap<String, Object> ret = new HashMap<String, Object>();
             ret.put(ARG_REQUESTS, reqs);
diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties
index ff7a4767a7f2feed7dbded43ec18f79e0b1251dd..7ad81ce47aaa35bbfda748238aaf0ebb230827ad 100644
--- a/base/server/cmsbundle/src/UserMessages.properties
+++ b/base/server/cmsbundle/src/UserMessages.properties
@@ -797,8 +797,9 @@ CMS_PROFILE_SUBJDIR_ATTRS=Subject Directory Attributes
 CMS_PROFILE_SUBJDIR_EMPTY_ATTRNAME=Attribute name should not be empty
 CMS_PROFILE_SUBJDIR_EMPTY_ATTRVAL=Attribute value should not be empty
 CMS_PROFILE_CRL_DISTRIBUTION_POINTS=CRL Distribution Points
-CMS_PROFILE_REJECTED=Request Rejected - {0}
+CMS_PROFILE_REJECTED=Request {0} Rejected - {1}
 CMS_PROFILE_DEFERRED=Request Deferred - {0}
+CMS_PROFILE_INTERNAL_ERROR=Request {0} - Server Internal Error
 CMS_PROFILE_KEY_ID=Key ID
 CMS_PROFILE_NOT_OWNER=Not Profile Owner
 CMS_PROFILE_NOT_FOUND=Profile {0} Not Found
diff --git a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
index fc0a4149b39c5fa28c1761d9988f491623f5bfd9..fae48f2f7fd275f107fa0c10407ec0c9b9dd1b8b 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
@@ -789,6 +789,10 @@ class Request implements IRequest {
         return getExtDataInString(IRequest.ERROR);
     }
 
+    public String getErrorCode(Locale locale) {
+        return getExtDataInString(IRequest.ERROR_CODE);
+    }
+
     // IRequest.getSourceId
     public String getSourceId() {
         return mSourceId;
diff --git a/base/server/test/com/netscape/cmscore/request/RequestDefaultStub.java b/base/server/test/com/netscape/cmscore/request/RequestDefaultStub.java
index b55238de5501f53ac82d53721043bfafe7513b16..885097ac004c96277f4511f5da07a84130b67a69 100644
--- a/base/server/test/com/netscape/cmscore/request/RequestDefaultStub.java
+++ b/base/server/test/com/netscape/cmscore/request/RequestDefaultStub.java
@@ -101,6 +101,10 @@ public class RequestDefaultStub implements IRequest {
         return null;
     }
 
+    public String getErrorCode(Locale locale) {
+        return null;
+    }
+
     public boolean setExtData(String key, String value) {
         return false;
     }
-- 
2.4.3

From ad1fcecc2f36cc1ebc1f13efe3df9d1e138224b7 Mon Sep 17 00:00:00 2001
From: Ade Lee <a...@redhat.com>
Date: Mon, 9 May 2016 15:00:20 -0400
Subject: [PATCH 301/301] Add authz realm check for cert enrollment

Ticket 2041
---
 .../src/com/netscape/cms/evaluators/UserAccessEvaluator.java  |  3 +++
 .../com/netscape/cms/servlet/cert/EnrollmentProcessor.java    | 11 +++++++++++
 2 files changed, 14 insertions(+)

diff --git a/base/server/cms/src/com/netscape/cms/evaluators/UserAccessEvaluator.java b/base/server/cms/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
index c343b110a5208b10109151c90cf9cfbf791009aa..93730be4b1b3e948de9c5cfb68fa5fdcd85b3465 100644
--- a/base/server/cms/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
+++ b/base/server/cms/src/com/netscape/cms/evaluators/UserAccessEvaluator.java
@@ -95,6 +95,9 @@ public class UserAccessEvaluator implements IAccessEvaluator {
             if ((s.equals(ANYBODY) || s.equals(EVERYBODY)) && op.equals("="))
                 return true;
 
+            // user should be authenticated at this point.
+            if (authToken == null) return false;
+
             // should define "uid" at a common place
             String uid = null;
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
index 02f5c3d1f5fede5b37b1bd554d3d6fd973401453..d394fd30c84a0fb7a0f19b31ba4b6973902ea931 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
@@ -183,6 +183,17 @@ public class EnrollmentProcessor extends CertProcessor {
             endTiming("request_population");
 
             ///////////////////////////////////////////////
+            // validate realm (if present)
+            ///////////////////////////////////////////////
+            for (IRequest req : reqs) {
+                String realm = req.getRealm();
+                if (StringUtils.isNotBlank(realm)) {
+                    authz.checkRealm(realm, authToken, null,
+                            "certServer.ca.request.enrollment", "submit");
+                }
+            }
+
+            ///////////////////////////////////////////////
             // submit request
             ///////////////////////////////////////////////
             String errorCode = submitRequests(locale, profile, authToken, reqs);
-- 
2.4.3

_______________________________________________
Pki-devel mailing list
Pki-devel@redhat.com
https://www.redhat.com/mailman/listinfo/pki-devel

Reply via email to