History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/jmx/remote/security/MBeanServerAccessController.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/jmx/remote/security/MBeanServerAccessController.java+665−0
@@ -0,0 +1,665 @@
1+/*
2+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.jmx.remote.security;
27+
28+import com.sun.jmx.mbeanserver.GetPropertyAction;
29+import java.io.ObjectInputStream;
30+import java.security.AccessController;
31+import java.util.Set;
32+import javax.management.Attribute;
33+import javax.management.AttributeList;
34+import javax.management.AttributeNotFoundException;
35+import javax.management.InstanceNotFoundException;
36+import javax.management.InstanceAlreadyExistsException;
37+import javax.management.IntrospectionException;
38+import javax.management.InvalidAttributeValueException;
39+import javax.management.ListenerNotFoundException;
40+import javax.management.MBeanException;
41+import javax.management.MBeanInfo;
42+import javax.management.MBeanRegistrationException;
43+import javax.management.MBeanServer;
44+import javax.management.NotCompliantMBeanException;
45+import javax.management.NotificationFilter;
46+import javax.management.NotificationListener;
47+import javax.management.ObjectInstance;
48+import javax.management.ObjectName;
49+import javax.management.OperationsException;
50+import javax.management.QueryExp;
51+import javax.management.ReflectionException;
52+import javax.management.loading.ClassLoaderRepository;
53+import javax.management.remote.MBeanServerForwarder;
54+
55+/**
56+ * <p>An object of this class implements the MBeanServer interface
57+ * and, for each of its methods, calls an appropriate checking method
58+ * and then forwards the request to a wrapped MBeanServer object. The
59+ * checking method may throw a RuntimeException if the operation is
60+ * not allowed; in this case the request is not forwarded to the
61+ * wrapped object.</p>
62+ *
63+ * <p>A typical use of this class is to insert it between a connector server
64+ * such as the RMI connector and the MBeanServer with which the connector
65+ * is associated. Requests from the connector client can then be filtered
66+ * and those operations that are not allowed, or not allowed in a particular
67+ * context, can be rejected by throwing a <code>SecurityException</code>
68+ * in the corresponding <code>check*</code> method.</p>
69+ *
70+ * <p>This is an abstract class, because in its implementation none of
71+ * the checking methods does anything. To be useful, it must be
72+ * subclassed and at least one of the checking methods overridden to
73+ * do some checking. Some or all of the MBeanServer methods may also
74+ * be overridden, for instance if the default checking behavior is
75+ * inappropriate.</p>
76+ *
77+ * <p>If there is no SecurityManager, then the access controller will refuse
78+ * to create an MBean that is a ClassLoader, which includes MLets, or to
79+ * execute the method addURL on an MBean that is an MLet. This prevents
80+ * people from opening security holes unintentionally. Otherwise, it
81+ * would not be obvious that granting write access grants the ability to
82+ * download and execute arbitrary code in the target MBean server. Advanced
83+ * users who do want the ability to use MLets are presumably advanced enough
84+ * to handle policy files and security managers.</p>
85+ */
86+public abstract class MBeanServerAccessController
87+ implements MBeanServerForwarder {
88+
89+ public MBeanServer getMBeanServer() {
90+ return mbs;
91+ }
92+
93+ public void setMBeanServer(MBeanServer mbs) {
94+ if (mbs == null)
95+ throw new IllegalArgumentException("Null MBeanServer");
96+ if (this.mbs != null)
97+ throw new IllegalArgumentException("MBeanServer object already " +
98+ "initialized");
99+ this.mbs = mbs;
100+ }
101+
102+ /**
103+ * Check if the caller can do read operations. This method does
104+ * nothing if so, otherwise throws SecurityException.
105+ */
106+ protected abstract void checkRead();
107+
108+ /**
109+ * Check if the caller can do write operations. This method does
110+ * nothing if so, otherwise throws SecurityException.
111+ */
112+ protected abstract void checkWrite();
113+
114+ /**
115+ * Check if the caller can create the named class. The default
116+ * implementation of this method calls {@link #checkWrite()}.
117+ */
118+ protected void checkCreate(String className) {
119+ checkWrite();
120+ }
121+
122+ /**
123+ * Check if the caller can unregister the named MBean. The default
124+ * implementation of this method calls {@link #checkWrite()}.
125+ */
126+ protected void checkUnregister(ObjectName name) {
127+ checkWrite();
128+ }
129+
130+ //--------------------------------------------
131+ //--------------------------------------------
132+ //
133+ // Implementation of the MBeanServer interface
134+ //
135+ //--------------------------------------------
136+ //--------------------------------------------
137+
138+ /**
139+ * Call <code>checkRead()</code>, then forward this method to the
140+ * wrapped object.
141+ */
142+ public void addNotificationListener(ObjectName name,
143+ NotificationListener listener,
144+ NotificationFilter filter,
145+ Object handback)
146+ throws InstanceNotFoundException {
147+ checkRead();
148+ getMBeanServer().addNotificationListener(name, listener,
149+ filter, handback);
150+ }
151+
152+ /**
153+ * Call <code>checkRead()</code>, then forward this method to the
154+ * wrapped object.
155+ */
156+ public void addNotificationListener(ObjectName name,
157+ ObjectName listener,
158+ NotificationFilter filter,
159+ Object handback)
160+ throws InstanceNotFoundException {
161+ checkRead();
162+ getMBeanServer().addNotificationListener(name, listener,
163+ filter, handback);
164+ }
165+
166+ /**
167+ * Call <code>checkCreate(className)</code>, then forward this method to the
168+ * wrapped object.
169+ */
170+ public ObjectInstance createMBean(String className, ObjectName name)
171+ throws
172+ ReflectionException,
173+ InstanceAlreadyExistsException,
174+ MBeanRegistrationException,
175+ MBeanException,
176+ NotCompliantMBeanException {
177+ checkCreate(className);
178+ SecurityManager sm = System.getSecurityManager();
179+ if (sm == null) {
180+ Object object = getMBeanServer().instantiate(className);
181+ checkClassLoader(object);
182+ return getMBeanServer().registerMBean(object, name);
183+ } else {
184+ return getMBeanServer().createMBean(className, name);
185+ }
186+ }
187+
188+ /**
189+ * Call <code>checkCreate(className)</code>, then forward this method to the
190+ * wrapped object.
191+ */
192+ public ObjectInstance createMBean(String className, ObjectName name,
193+ Object params[], String signature[])
194+ throws
195+ ReflectionException,
196+ InstanceAlreadyExistsException,
197+ MBeanRegistrationException,
198+ MBeanException,
199+ NotCompliantMBeanException {
200+ checkCreate(className);
201+ SecurityManager sm = System.getSecurityManager();
202+ if (sm == null) {
203+ Object object = getMBeanServer().instantiate(className,
204+ params,
205+ signature);
206+ checkClassLoader(object);
207+ return getMBeanServer().registerMBean(object, name);
208+ } else {
209+ return getMBeanServer().createMBean(className, name,
210+ params, signature);
211+ }
212+ }
213+
214+ /**
215+ * Call <code>checkCreate(className)</code>, then forward this method to the
216+ * wrapped object.
217+ */
218+ public ObjectInstance createMBean(String className,
219+ ObjectName name,
220+ ObjectName loaderName)
221+ throws
222+ ReflectionException,
223+ InstanceAlreadyExistsException,
224+ MBeanRegistrationException,
225+ MBeanException,
226+ NotCompliantMBeanException,
227+ InstanceNotFoundException {
228+ checkCreate(className);
229+ SecurityManager sm = System.getSecurityManager();
230+ if (sm == null) {
231+ Object object = getMBeanServer().instantiate(className,
232+ loaderName);
233+ checkClassLoader(object);
234+ return getMBeanServer().registerMBean(object, name);
235+ } else {
236+ return getMBeanServer().createMBean(className, name, loaderName);
237+ }
238+ }
239+
240+ /**
241+ * Call <code>checkCreate(className)</code>, then forward this method to the
242+ * wrapped object.
243+ */
244+ public ObjectInstance createMBean(String className,
245+ ObjectName name,
246+ ObjectName loaderName,
247+ Object params[],
248+ String signature[])
249+ throws
250+ ReflectionException,
251+ InstanceAlreadyExistsException,
252+ MBeanRegistrationException,
253+ MBeanException,
254+ NotCompliantMBeanException,
255+ InstanceNotFoundException {
256+ checkCreate(className);
257+ SecurityManager sm = System.getSecurityManager();
258+ if (sm == null) {
259+ Object object = getMBeanServer().instantiate(className,
260+ loaderName,
261+ params,
262+ signature);
263+ checkClassLoader(object);
264+ return getMBeanServer().registerMBean(object, name);
265+ } else {
266+ return getMBeanServer().createMBean(className, name, loaderName,
267+ params, signature);
268+ }
269+ }
270+
271+ /**
272+ * Call <code>checkRead()</code>, then forward this method to the
273+ * wrapped object.
274+ */
275+ @Deprecated
276+ public ObjectInputStream deserialize(ObjectName name, byte[] data)
277+ throws InstanceNotFoundException, OperationsException {
278+ checkRead();
279+ return getMBeanServer().deserialize(name, data);
280+ }
281+
282+ /**
283+ * Call <code>checkRead()</code>, then forward this method to the
284+ * wrapped object.
285+ */
286+ @Deprecated
287+ public ObjectInputStream deserialize(String className, byte[] data)
288+ throws OperationsException, ReflectionException {
289+ checkRead();
290+ return getMBeanServer().deserialize(className, data);
291+ }
292+
293+ /**
294+ * Call <code>checkRead()</code>, then forward this method to the
295+ * wrapped object.
296+ */
297+ @Deprecated
298+ public ObjectInputStream deserialize(String className,
299+ ObjectName loaderName,
300+ byte[] data)
301+ throws
302+ InstanceNotFoundException,
303+ OperationsException,
304+ ReflectionException {
305+ checkRead();
306+ return getMBeanServer().deserialize(className, loaderName, data);
307+ }
308+
309+ /**
310+ * Call <code>checkRead()</code>, then forward this method to the
311+ * wrapped object.
312+ */
313+ public Object getAttribute(ObjectName name, String attribute)
314+ throws
315+ MBeanException,
316+ AttributeNotFoundException,
317+ InstanceNotFoundException,
318+ ReflectionException {
319+ checkRead();
320+ return getMBeanServer().getAttribute(name, attribute);
321+ }
322+
323+ /**
324+ * Call <code>checkRead()</code>, then forward this method to the
325+ * wrapped object.
326+ */
327+ public AttributeList getAttributes(ObjectName name, String[] attributes)
328+ throws InstanceNotFoundException, ReflectionException {
329+ checkRead();
330+ return getMBeanServer().getAttributes(name, attributes);
331+ }
332+
333+ /**
334+ * Call <code>checkRead()</code>, then forward this method to the
335+ * wrapped object.
336+ */
337+ public ClassLoader getClassLoader(ObjectName loaderName)
338+ throws InstanceNotFoundException {
339+ checkRead();
340+ return getMBeanServer().getClassLoader(loaderName);
341+ }
342+
343+ /**
344+ * Call <code>checkRead()</code>, then forward this method to the
345+ * wrapped object.
346+ */
347+ public ClassLoader getClassLoaderFor(ObjectName mbeanName)
348+ throws InstanceNotFoundException {
349+ checkRead();
350+ return getMBeanServer().getClassLoaderFor(mbeanName);
351+ }
352+
353+ /**
354+ * Call <code>checkRead()</code>, then forward this method to the
355+ * wrapped object.
356+ */
357+ public ClassLoaderRepository getClassLoaderRepository() {
358+ checkRead();
359+ return getMBeanServer().getClassLoaderRepository();
360+ }
361+
362+ /**
363+ * Call <code>checkRead()</code>, then forward this method to the
364+ * wrapped object.
365+ */
366+ public String getDefaultDomain() {
367+ checkRead();
368+ return getMBeanServer().getDefaultDomain();
369+ }
370+
371+ /**
372+ * Call <code>checkRead()</code>, then forward this method to the
373+ * wrapped object.
374+ */
375+ public String[] getDomains() {
376+ checkRead();
377+ return getMBeanServer().getDomains();
378+ }
379+
380+ /**
381+ * Call <code>checkRead()</code>, then forward this method to the
382+ * wrapped object.
383+ */
384+ public Integer getMBeanCount() {
385+ checkRead();
386+ return getMBeanServer().getMBeanCount();
387+ }
388+
389+ /**
390+ * Call <code>checkRead()</code>, then forward this method to the
391+ * wrapped object.
392+ */
393+ public MBeanInfo getMBeanInfo(ObjectName name)
394+ throws
395+ InstanceNotFoundException,
396+ IntrospectionException,
397+ ReflectionException {
398+ checkRead();
399+ return getMBeanServer().getMBeanInfo(name);
400+ }
401+
402+ /**
403+ * Call <code>checkRead()</code>, then forward this method to the
404+ * wrapped object.
405+ */
406+ public ObjectInstance getObjectInstance(ObjectName name)
407+ throws InstanceNotFoundException {
408+ checkRead();
409+ return getMBeanServer().getObjectInstance(name);
410+ }
411+
412+ /**
413+ * Call <code>checkCreate(className)</code>, then forward this method to the
414+ * wrapped object.
415+ */
416+ public Object instantiate(String className)
417+ throws ReflectionException, MBeanException {
418+ checkCreate(className);
419+ return getMBeanServer().instantiate(className);
420+ }
421+
422+ /**
423+ * Call <code>checkCreate(className)</code>, then forward this method to the
424+ * wrapped object.
425+ */
426+ public Object instantiate(String className,
427+ Object params[],
428+ String signature[])
429+ throws ReflectionException, MBeanException {
430+ checkCreate(className);
431+ return getMBeanServer().instantiate(className, params, signature);
432+ }
433+
434+ /**
435+ * Call <code>checkCreate(className)</code>, then forward this method to the
436+ * wrapped object.
437+ */
438+ public Object instantiate(String className, ObjectName loaderName)
439+ throws ReflectionException, MBeanException, InstanceNotFoundException {
440+ checkCreate(className);
441+ return getMBeanServer().instantiate(className, loaderName);
442+ }
443+
444+ /**
445+ * Call <code>checkCreate(className)</code>, then forward this method to the
446+ * wrapped object.
447+ */
448+ public Object instantiate(String className, ObjectName loaderName,
449+ Object params[], String signature[])
450+ throws ReflectionException, MBeanException, InstanceNotFoundException {
451+ checkCreate(className);
452+ return getMBeanServer().instantiate(className, loaderName,
453+ params, signature);
454+ }
455+
456+ /**
457+ * Call <code>checkWrite()</code>, then forward this method to the
458+ * wrapped object.
459+ */
460+ public Object invoke(ObjectName name, String operationName,
461+ Object params[], String signature[])
462+ throws
463+ InstanceNotFoundException,
464+ MBeanException,
465+ ReflectionException {
466+ checkWrite();
467+ checkMLetMethods(name, operationName);
468+ return getMBeanServer().invoke(name, operationName, params, signature);
469+ }
470+
471+ /**
472+ * Call <code>checkRead()</code>, then forward this method to the
473+ * wrapped object.
474+ */
475+ public boolean isInstanceOf(ObjectName name, String className)
476+ throws InstanceNotFoundException {
477+ checkRead();
478+ return getMBeanServer().isInstanceOf(name, className);
479+ }
480+
481+ /**
482+ * Call <code>checkRead()</code>, then forward this method to the
483+ * wrapped object.
484+ */
485+ public boolean isRegistered(ObjectName name) {
486+ checkRead();
487+ return getMBeanServer().isRegistered(name);
488+ }
489+
490+ /**
491+ * Call <code>checkRead()</code>, then forward this method to the
492+ * wrapped object.
493+ */
494+ public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
495+ checkRead();
496+ return getMBeanServer().queryMBeans(name, query);
497+ }
498+
499+ /**
500+ * Call <code>checkRead()</code>, then forward this method to the
501+ * wrapped object.
502+ */
503+ public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
504+ checkRead();
505+ return getMBeanServer().queryNames(name, query);
506+ }
507+
508+ /**
509+ * Call <code>checkWrite()</code>, then forward this method to the
510+ * wrapped object.
511+ */
512+ public ObjectInstance registerMBean(Object object, ObjectName name)
513+ throws
514+ InstanceAlreadyExistsException,
515+ MBeanRegistrationException,
516+ NotCompliantMBeanException {
517+ checkWrite();
518+ return getMBeanServer().registerMBean(object, name);
519+ }
520+
521+ /**
522+ * Call <code>checkRead()</code>, then forward this method to the
523+ * wrapped object.
524+ */
525+ public void removeNotificationListener(ObjectName name,
526+ NotificationListener listener)
527+ throws InstanceNotFoundException, ListenerNotFoundException {
528+ checkRead();
529+ getMBeanServer().removeNotificationListener(name, listener);
530+ }
531+
532+ /**
533+ * Call <code>checkRead()</code>, then forward this method to the
534+ * wrapped object.
535+ */
536+ public void removeNotificationListener(ObjectName name,
537+ NotificationListener listener,
538+ NotificationFilter filter,
539+ Object handback)
540+ throws InstanceNotFoundException, ListenerNotFoundException {
541+ checkRead();
542+ getMBeanServer().removeNotificationListener(name, listener,
543+ filter, handback);
544+ }
545+
546+ /**
547+ * Call <code>checkRead()</code>, then forward this method to the
548+ * wrapped object.
549+ */
550+ public void removeNotificationListener(ObjectName name,
551+ ObjectName listener)
552+ throws InstanceNotFoundException, ListenerNotFoundException {
553+ checkRead();
554+ getMBeanServer().removeNotificationListener(name, listener);
555+ }
556+
557+ /**
558+ * Call <code>checkRead()</code>, then forward this method to the
559+ * wrapped object.
560+ */
561+ public void removeNotificationListener(ObjectName name,
562+ ObjectName listener,
563+ NotificationFilter filter,
564+ Object handback)
565+ throws InstanceNotFoundException, ListenerNotFoundException {
566+ checkRead();
567+ getMBeanServer().removeNotificationListener(name, listener,
568+ filter, handback);
569+ }
570+
571+ /**
572+ * Call <code>checkWrite()</code>, then forward this method to the
573+ * wrapped object.
574+ */
575+ public void setAttribute(ObjectName name, Attribute attribute)
576+ throws
577+ InstanceNotFoundException,
578+ AttributeNotFoundException,
579+ InvalidAttributeValueException,
580+ MBeanException,
581+ ReflectionException {
582+ checkWrite();
583+ getMBeanServer().setAttribute(name, attribute);
584+ }
585+
586+ /**
587+ * Call <code>checkWrite()</code>, then forward this method to the
588+ * wrapped object.
589+ */
590+ public AttributeList setAttributes(ObjectName name,
591+ AttributeList attributes)
592+ throws InstanceNotFoundException, ReflectionException {
593+ checkWrite();
594+ return getMBeanServer().setAttributes(name, attributes);
595+ }
596+
597+ /**
598+ * Call <code>checkUnregister()</code>, then forward this method to the
599+ * wrapped object.
600+ */
601+ public void unregisterMBean(ObjectName name)
602+ throws InstanceNotFoundException, MBeanRegistrationException {
603+ checkUnregister(name);
604+ getMBeanServer().unregisterMBean(name);
605+ }
606+
607+ //----------------
608+ // PRIVATE METHODS
609+ //----------------
610+
611+ private void checkClassLoader(Object object) {
612+ if (object instanceof ClassLoader)
613+ throw new SecurityException("Access denied! Creating an " +
614+ "MBean that is a ClassLoader " +
615+ "is forbidden unless a security " +
616+ "manager is installed.");
617+ }
618+
619+ private void checkMLetMethods(ObjectName name, String operation)
620+ throws InstanceNotFoundException {
621+ // Check if security manager installed
622+ SecurityManager sm = System.getSecurityManager();
623+ if (sm != null) {
624+ return;
625+ }
626+ // Check for addURL and getMBeansFromURL methods
627+ if (!operation.equals("addURL") &&
628+ !operation.equals("getMBeansFromURL")) {
629+ return;
630+ }
631+ // Check if MBean is instance of MLet
632+ if (!getMBeanServer().isInstanceOf(name,
633+ "javax.management.loading.MLet")) {
634+ return;
635+ }
636+ // Throw security exception
637+ if (operation.equals("addURL")) { // addURL
638+ throw new SecurityException("Access denied! MLet method addURL " +
639+ "cannot be invoked unless a security manager is installed.");
640+ } else { // getMBeansFromURL
641+ // Whether or not calling getMBeansFromURL is allowed is controlled
642+ // by the value of the "jmx.remote.x.mlet.allow.getMBeansFromURL"
643+ // system property. If the value of this property is true, calling
644+ // the MLet's getMBeansFromURL method is allowed. The default value
645+ // for this property is false.
646+ final String propName = "jmx.remote.x.mlet.allow.getMBeansFromURL";
647+ GetPropertyAction propAction = new GetPropertyAction(propName);
648+ String propValue = AccessController.doPrivileged(propAction);
649+ boolean allowGetMBeansFromURL = "true".equalsIgnoreCase(propValue);
650+ if (!allowGetMBeansFromURL) {
651+ throw new SecurityException("Access denied! MLet method " +
652+ "getMBeansFromURL cannot be invoked unless a " +
653+ "security manager is installed or the system property " +
654+ "-Djmx.remote.x.mlet.allow.getMBeansFromURL=true " +
655+ "is specified.");
656+ }
657+ }
658+ }
659+
660+ //------------------
661+ // PRIVATE VARIABLES
662+ //------------------
663+
664+ private MBeanServer mbs;
665+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t