From c1405673acad68e2233b152fec84409b0af36994 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Thu, 12 Jul 2007 08:18:55 +0000
Subject: [PATCH] fix for issue #1217 Privilege checks are done in the JmxClientConnection code. Due to JMX design choice (See chapter 13.4.3,page 210 of the JMX Specification, version 1.4 Final Release - http://jcp.org/en/jsr/detail?id=160) JMX_NOTIFY privilege cannot be checked when a remote client adds a Listener. For this reason, we have chosen to allow JMX connection only if the user has the JMX_READ privilege (at least). The JMX_READ privilege is now also check during connection establishment.
---
opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java | 228 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 222 insertions(+), 6 deletions(-)
diff --git a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
index 67c2fd6..d872b3b 100644
--- a/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
+++ b/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
@@ -44,6 +44,8 @@
import org.opends.server.protocols.internal.InternalSearchListener;
import org.opends.server.types.AbstractOperation;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.CancelRequest;
@@ -54,9 +56,14 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DisconnectReason;
import org.opends.server.types.IntermediateResponse;
+import org.opends.server.types.Modification;
+import org.opends.server.types.ObjectClass;
import org.opends.server.types.Operation;
+import org.opends.server.types.Privilege;
+import org.opends.server.types.RDN;
import org.opends.server.types.RawAttribute;
import org.opends.server.types.RawModification;
+import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.SearchScope;
@@ -64,6 +71,7 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.messages.ProtocolMessages.*;
+import static org.opends.server.messages.MessageHandler.getMessage;
/**
@@ -476,10 +484,95 @@
new AddOperationBasis(this, nextOperationID(), nextMessageID(),
new ArrayList<Control>(0), rawEntryDN, rawAttributes);
- addOperation.run();
+ // Check if we have enough privilege
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_ADD_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ addOperation.setErrorMessage(new StringBuilder(message));
+ addOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ addOperation.run();
+ }
return addOperation;
}
+ /**
+ * Processes an internal add operation with the provided
+ * information.
+ *
+ * @param entryDN The entry DN for the add
+ * operation.
+ * @param objectClasses The set of objectclasses for the
+ * add operation.
+ * @param userAttributes The set of user attributes for the
+ * add operation.
+ * @param operationalAttributes The set of operational attributes
+ * for the add operation.
+ *
+ * @return A reference to the add operation that was processed and
+ * contains information about the result of the processing.
+ */
+ public AddOperation processAdd(DN entryDN,
+ Map<ObjectClass,String> objectClasses,
+ Map<AttributeType,List<Attribute>>
+ userAttributes,
+ Map<AttributeType,List<Attribute>>
+ operationalAttributes)
+ {
+ AddOperationBasis addOperation =
+ new AddOperationBasis(this, nextOperationID(),
+ nextMessageID(),
+ new ArrayList<Control>(0), entryDN,
+ objectClasses, userAttributes,
+ operationalAttributes);
+ // Check if we have enough privilege
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_ADD_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ addOperation.setErrorMessage(new StringBuilder(message));
+ addOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ addOperation.run();
+ }
+ return addOperation;
+ }
+
+ /**
+ * Processes an internal delete operation with the provided
+ * information.
+ *
+ * @param entryDN The entry DN for the delete operation.
+ *
+ * @return A reference to the delete operation that was processed
+ * and contains information about the result of the
+ * processing.
+ */
+ public DeleteOperation processDelete(DN entryDN)
+ {
+ DeleteOperationBasis deleteOperation =
+ new DeleteOperationBasis(this, nextOperationID(),
+ nextMessageID(),
+ new ArrayList<Control>(0), entryDN);
+ // Check if we have enough privilege
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_DELETE_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ deleteOperation.setErrorMessage(new StringBuilder(message));
+ deleteOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ deleteOperation.run();
+ }
+ return deleteOperation;
+ }
/**
@@ -501,7 +594,18 @@
new ArrayList<Control>(0), rawEntryDN,
attributeType, assertionValue);
- compareOperation.run();
+ // Check if we have enough privilege
+ if (! hasPrivilege(Privilege.JMX_READ, null))
+ {
+ int msgID = MSGID_JMX_SEARCH_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ compareOperation.setErrorMessage(new StringBuilder(message));
+ compareOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ compareOperation.run();
+ }
return compareOperation;
}
@@ -521,7 +625,18 @@
new DeleteOperationBasis(this, nextOperationID(), nextMessageID(),
new ArrayList<Control>(0), rawEntryDN);
- deleteOperation.run();
+ // Check if we have enough privilege
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_DELETE_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ deleteOperation.setErrorMessage(new StringBuilder(message));
+ deleteOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ deleteOperation.run();
+ }
return deleteOperation;
}
@@ -569,11 +684,54 @@
new ArrayList<Control>(0), rawEntryDN,
rawModifications);
- modifyOperation.run();
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_MODIFY_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ modifyOperation.setErrorMessage(new StringBuilder(message));
+ modifyOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ modifyOperation.run();
+ }
return modifyOperation;
}
+ /**
+ * Processes an internal modify operation with the provided
+ * information.
+ *
+ * @param entryDN The entry DN for this modify operation.
+ * @param modifications The set of modifications for this modify
+ * operation.
+ *
+ * @return A reference to the modify operation that was processed
+ * and contains information about the result of the
+ * processing.
+ */
+ public ModifyOperation processModify(DN entryDN,
+ List<Modification> modifications)
+ {
+ ModifyOperationBasis modifyOperation =
+ new ModifyOperationBasis(this, nextOperationID(),
+ nextMessageID(),
+ new ArrayList<Control>(0), entryDN,
+ modifications);
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_MODIFY_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ modifyOperation.setErrorMessage(new StringBuilder(message));
+ modifyOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ modifyOperation.run();
+ }
+ return modifyOperation;
+ }
/**
* Processes an Jmx modify DN operation with the provided information.
@@ -619,11 +777,59 @@
new ArrayList<Control>(0), rawEntryDN, rawNewRDN,
deleteOldRDN, rawNewSuperior);
- modifyDNOperation.run();
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_MODDN_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ modifyDNOperation.setErrorMessage(new StringBuilder(message));
+ modifyDNOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ modifyDNOperation.run();
+ }
return modifyDNOperation;
}
+ /**
+ * Processes an internal modify DN operation with the provided
+ * information.
+ *
+ * @param entryDN The current DN of the entry to rename.
+ * @param newRDN The new RDN to use for the entry.
+ * @param deleteOldRDN The flag indicating whether the old RDN
+ * value is to be removed from the entry.
+ * @param newSuperior The new superior for the modify DN
+ * operation, or <CODE>null</CODE> if the
+ * entry will remain below the same parent.
+ *
+ * @return A reference to the modify DN operation that was
+ * processed and contains information about the result of
+ * the processing.
+ */
+ public ModifyDNOperation processModifyDN(DN entryDN, RDN newRDN,
+ boolean deleteOldRDN,
+ DN newSuperior)
+ {
+ ModifyDNOperation modifyDNOperation =
+ new ModifyDNOperation(this, nextOperationID(),
+ nextMessageID(),
+ new ArrayList<Control>(0), entryDN,
+ newRDN, deleteOldRDN, newSuperior);
+ if (! hasPrivilege(Privilege.JMX_WRITE, null))
+ {
+ int msgID = MSGID_JMX_MODDN_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ modifyDNOperation.setErrorMessage(new StringBuilder(message));
+ modifyDNOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ modifyDNOperation.run();
+ }
+ return modifyDNOperation;
+ }
/**
* Processes an Jmx search operation with the provided information.
@@ -677,7 +883,17 @@
scope, derefPolicy, sizeLimit, timeLimit,
typesOnly, filter, attributes, null);
- searchOperation.run();
+ if (! hasPrivilege(Privilege.JMX_READ, null))
+ {
+ int msgID = MSGID_JMX_SEARCH_INSUFFICIENT_PRIVILEGES;
+ String message = getMessage(msgID);
+ searchOperation.setErrorMessage(new StringBuilder(message));
+ searchOperation.setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS) ;
+ }
+ else
+ {
+ searchOperation.run();
+ }
return searchOperation;
}
--
Gitblit v1.10.0