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
26package com.sun.jmx.remote.security;
27
28import com.sun.jmx.mbeanserver.GetPropertyAction;
29import java.io.ObjectInputStream;
30import java.security.AccessController;
31import java.util.Set;
32import javax.management.Attribute;
33import javax.management.AttributeList;
34import javax.management.AttributeNotFoundException;
35import javax.management.InstanceNotFoundException;
36import javax.management.InstanceAlreadyExistsException;
37import javax.management.IntrospectionException;
38import javax.management.InvalidAttributeValueException;
39import javax.management.ListenerNotFoundException;
40import javax.management.MBeanException;
41import javax.management.MBeanInfo;
42import javax.management.MBeanRegistrationException;
43import javax.management.MBeanServer;
44import javax.management.NotCompliantMBeanException;
45import javax.management.NotificationFilter;
46import javax.management.NotificationListener;
47import javax.management.ObjectInstance;
48import javax.management.ObjectName;
49import javax.management.OperationsException;
50import javax.management.QueryExp;
51import javax.management.ReflectionException;
52import javax.management.loading.ClassLoaderRepository;
53import 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 */
86public 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