1 22 package org.jboss.ejb; 23 24 import java.rmi.RemoteException ; 25 import java.security.Identity ; 26 import java.security.Principal ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.Properties ; 31 import java.util.Set ; 32 import java.util.Stack ; 33 import javax.ejb.EJBContext ; 34 import javax.ejb.EJBException ; 35 import javax.ejb.EJBHome ; 36 import javax.ejb.EJBLocalHome ; 37 import javax.ejb.TimerService ; 38 import javax.security.jacc.PolicyContextException ; 39 import javax.transaction.HeuristicMixedException ; 40 import javax.transaction.HeuristicRollbackException ; 41 import javax.transaction.NotSupportedException ; 42 import javax.transaction.RollbackException ; 43 import javax.transaction.Status ; 44 import javax.transaction.Synchronization ; 45 import javax.transaction.SystemException ; 46 import javax.transaction.Transaction ; 47 import javax.transaction.TransactionManager ; 48 import javax.transaction.UserTransaction ; 49 import javax.naming.InitialContext ; 50 import javax.naming.NamingException ; 51 52 import org.jboss.logging.Logger; 53 import org.jboss.metadata.ApplicationMetaData; 54 import org.jboss.metadata.BeanMetaData; 55 import org.jboss.metadata.SecurityRoleRefMetaData; 56 import org.jboss.security.AuthorizationManager; 57 import org.jboss.security.RealmMapping; 58 import org.jboss.security.RunAsIdentity; 59 import org.jboss.security.SecurityRoleRef; 60 import org.jboss.security.SimplePrincipal; 61 import org.jboss.security.authorization.AuthorizationContext; 62 import org.jboss.security.authorization.EJBResource; 63 import org.jboss.security.authorization.ResourceKeys; 64 import org.jboss.tm.TransactionTimeoutConfiguration; 65 import org.jboss.tm.usertx.client.ServerVMClientUserTransaction; 66 67 69 86 public abstract class EnterpriseContext 87 implements AllowedOperationsFlags 88 { 89 91 93 94 protected static Logger log = Logger.getLogger(EnterpriseContext.class); 95 96 97 Object instance; 98 99 100 Container con; 101 102 106 Synchronization synch; 107 108 109 Transaction transaction; 110 111 112 private Principal principal; 113 114 115 private Principal beanPrincipal; 116 117 118 Object id; 119 120 121 int locked = 0; 122 123 124 Object txLock = new Object (); 125 126 131 private Stack inMethodStack = new Stack (); 132 133 private static ServerVMClientUserTransaction.UserTransactionStartedListener tsl; 137 138 146 public static void setUserTransactionStartedListener(ServerVMClientUserTransaction.UserTransactionStartedListener newTsl) 147 { 148 tsl = newTsl; 149 } 150 151 153 public EnterpriseContext(Object instance, Container con) 154 { 155 this.instance = instance; 156 this.con = con; 157 } 158 159 161 public Object getInstance() 162 { 163 return instance; 164 } 165 166 169 public Container getContainer() 170 { 171 return con; 172 } 173 174 public abstract void discard() 175 throws RemoteException ; 176 177 180 public abstract EJBContext getEJBContext(); 181 182 public void setId(Object id) 183 { 184 this.id = id; 185 } 186 187 public Object getId() 188 { 189 return id; 190 } 191 192 public Object getTxLock() 193 { 194 return txLock; 195 } 196 197 public void setTransaction(Transaction transaction) 198 { 199 this.transaction = transaction; 201 } 202 203 public Transaction getTransaction() 204 { 205 return transaction; 206 } 207 208 public void setPrincipal(Principal principal) 209 { 210 this.principal = principal; 211 214 this.beanPrincipal = null; 215 if( con.getSecurityManager() != null ) 216 this.beanPrincipal = getCallerPrincipal(); 217 } 218 219 public void lock() 220 { 221 locked++; 222 } 225 226 public void unlock() 227 { 228 229 locked--; 231 232 if (locked < 0) 234 { 235 log.error("locked < 0", new Throwable ()); 237 } 238 239 } 241 242 public boolean isLocked() 243 { 244 245 return locked != 0; 247 } 248 249 public Principal getCallerPrincipal() 250 { 251 EJBContextImpl ctxImpl = (EJBContextImpl) getEJBContext(); 252 return ctxImpl.getCallerPrincipalInternal(); 253 } 254 255 259 public void clear() 260 { 261 this.id = null; 262 this.locked = 0; 263 this.principal = null; 264 this.beanPrincipal = null; 265 this.synch = null; 266 this.transaction = null; 267 this.inMethodStack.clear(); 268 } 269 270 272 274 protected boolean isContainerManagedTx() 275 { 276 BeanMetaData md = con.getBeanMetaData(); 277 return md.isContainerManagedTx(); 278 } 279 280 protected boolean isUserManagedTx() 281 { 282 BeanMetaData md = con.getBeanMetaData(); 283 return md.isContainerManagedTx() == false; 284 } 285 286 288 290 protected class EJBContextImpl 291 implements EJBContext 292 { 293 297 private UserTransactionImpl userTransaction = null; 298 299 private InitialContext ctx; 300 301 302 private InitialContext getContext() 303 { 304 if (ctx==null) 305 { 306 try 307 { 308 ctx = new InitialContext (); 309 } 310 catch (NamingException e) 311 { 312 throw new RuntimeException (e); 313 } 314 } 315 316 return ctx; 317 } 318 319 protected EJBContextImpl() 320 { 321 } 322 323 public Object lookup(String name) 324 { 325 try 326 { 327 return getContext().lookup(name); 328 } 329 catch (NamingException ignored) 330 { 331 } 332 return null; 333 } 334 335 338 public Identity getCallerIdentity() 339 { 340 throw new EJBException ("Deprecated"); 341 } 342 343 public TimerService getTimerService() throws IllegalStateException 344 { 345 return getContainer().getTimerService(null); 346 } 347 348 352 public Principal getCallerPrincipal() 353 { 354 return getCallerPrincipalInternal(); 355 } 356 357 361 Principal getCallerPrincipalInternal() 362 { 363 if( beanPrincipal == null ) 364 { 365 368 Principal caller = SecurityActions.getCallerPrincipal(); 369 RealmMapping rm = con.getRealmMapping(); 370 373 if (rm != null) 374 caller = rm.getPrincipal(caller); 375 if( caller == null ) 376 { 377 381 if( principal != null ) 382 { 383 if( rm != null ) 384 caller = rm.getPrincipal(principal); 385 else 386 caller = principal; 387 } 388 else 390 { 391 ApplicationMetaData appMetaData = con.getBeanMetaData().getApplicationMetaData(); 392 String name = appMetaData.getUnauthenticatedPrincipal(); 393 if (name != null) 394 caller = new SimplePrincipal(name); 395 } 396 } 397 398 if( caller == null ) 399 { 400 throw new IllegalStateException ("No valid security context for the caller identity"); 401 } 402 405 beanPrincipal = caller; 406 } 407 return beanPrincipal; 408 } 409 410 public EJBHome getEJBHome() 411 { 412 EJBProxyFactory proxyFactory = con.getProxyFactory(); 413 if (proxyFactory == null) 414 throw new IllegalStateException ("No remote home defined."); 415 416 return (EJBHome ) proxyFactory.getEJBHome(); 417 } 418 419 public EJBLocalHome getEJBLocalHome() 420 { 421 if (con.getLocalHomeClass() == null) 422 throw new IllegalStateException ("No local home defined."); 423 424 if (con instanceof EntityContainer) 425 return ((EntityContainer) con).getLocalProxyFactory().getEJBLocalHome(); 426 else if (con instanceof StatelessSessionContainer) 427 return ((StatelessSessionContainer) con).getLocalProxyFactory().getEJBLocalHome(); 428 else if (con instanceof StatefulSessionContainer) 429 return ((StatefulSessionContainer) con).getLocalProxyFactory().getEJBLocalHome(); 430 431 throw new EJBException ("No EJBLocalHome available (BUG!)"); 433 } 434 435 438 public Properties getEnvironment() 439 { 440 throw new EJBException ("Deprecated"); 441 } 442 443 public boolean getRollbackOnly() 444 { 445 if (con.getBeanMetaData().isBeanManagedTx()) 447 throw new IllegalStateException ("getRollbackOnly() not allowed for BMT beans."); 448 449 try 450 { 451 TransactionManager tm = con.getTransactionManager(); 452 453 if (tm.getTransaction() == null) 456 throw new IllegalStateException ("getRollbackOnly() not allowed without a transaction."); 457 458 return tm.getStatus() == Status.STATUS_MARKED_ROLLBACK; 459 } 460 catch (SystemException e) 461 { 462 log.warn("failed to get tx manager status; ignoring", e); 463 return true; 464 } 465 } 466 467 public void setRollbackOnly() 468 { 469 if (con.getBeanMetaData().isBeanManagedTx()) 471 throw new IllegalStateException ("setRollbackOnly() not allowed for BMT beans."); 472 473 try 474 { 475 TransactionManager tm = con.getTransactionManager(); 476 477 if (tm.getTransaction() == null) 480 throw new IllegalStateException ("setRollbackOnly() not allowed without a transaction."); 481 482 tm.setRollbackOnly(); 483 } 484 catch (SystemException e) 485 { 486 log.warn("failed to set rollback only; ignoring", e); 487 } 488 } 489 490 493 public boolean isCallerInRole(Identity id) 494 { 495 throw new EJBException ("Deprecated"); 496 } 497 498 503 public boolean isCallerInRole(String roleName) 504 { 505 AuthorizationManager authzManager = getContainer().getAuthorizationManager(); 507 if( authzManager == null) 508 { 509 String msg = "isCallerInRole() called with no security context. " 510 + "Check that a security-domain has been set for the application."; 511 throw new IllegalStateException (msg); 512 } 513 RunAsIdentity runAsIdentity = SecurityActions.peekRunAsIdentity(1); 515 if (principal == null && runAsIdentity == null) 516 return false; 517 518 Iterator it = getContainer().getBeanMetaData().getSecurityRoleReferences(); 520 Set securityRoleRefs = new HashSet (); 521 while(it.hasNext()) 522 { 523 SecurityRoleRefMetaData meta = (SecurityRoleRefMetaData) it.next(); 524 securityRoleRefs.add(new SecurityRoleRef(meta.getName(), meta.getLink(),meta.getDescription())); 525 } 526 final HashMap map = new HashMap (); 527 map.put(ResourceKeys.EJB_NAME ,getContainer().getBeanMetaData().getEjbName()); 528 map.put(ResourceKeys.EJB_PRINCIPAL, principal); 529 map.put(ResourceKeys.AUTHORIZATION_MANAGER,authzManager); 530 map.put(ResourceKeys.RUNASIDENTITY, SecurityActions.peekRunAsIdentity(1)); 531 map.put(ResourceKeys.SECURITY_ROLE_REFERENCES, securityRoleRefs); 532 map.put(ResourceKeys.ROLENAME, roleName); 533 map.put(ResourceKeys.ROLEREF_PERM_CHECK, Boolean.TRUE); 534 try 535 { 536 map.put(ResourceKeys.CALLER_SUBJECT, SecurityActions.getContextSubject()); 537 } 538 catch (PolicyContextException pe) 539 { 540 if(log.isTraceEnabled()) 541 log.trace("PolicyContextException in getting caller subject:",pe); 542 } 543 EJBResource ejbResource = new EJBResource(map); 544 boolean isAuthorized = false; 545 try 546 { 547 int check = authzManager.authorize(ejbResource); 548 isAuthorized = (check == AuthorizationContext.PERMIT); 549 } 550 catch (Exception e) 551 { 552 isAuthorized = false; 553 if(log.isTraceEnabled()) 554 log.trace("Error in authorization:",e); 555 else 556 log.error("isCallerInRole check failed:"+e.getLocalizedMessage()); 557 } 558 return isAuthorized; 559 } 560 561 public UserTransaction getUserTransaction() 562 { 563 if (userTransaction == null) 564 { 565 if (isContainerManagedTx()) 566 { 567 throw new IllegalStateException 568 ("CMT beans are not allowed to get a UserTransaction"); 569 } 570 571 userTransaction = new UserTransactionImpl(); 572 } 573 574 return userTransaction; 575 } 576 } 577 578 580 protected class UserTransactionImpl 581 implements UserTransaction 582 { 583 584 private int timeout = 0; 585 586 587 boolean trace; 588 589 public UserTransactionImpl() 590 { 591 trace = log.isTraceEnabled(); 592 if (trace) 593 log.trace("new UserTx: " + this); 594 } 595 596 public void begin() 597 throws NotSupportedException , SystemException 598 { 599 TransactionManager tm = con.getTransactionManager(); 600 601 int oldTimeout = -1; 602 if (tm instanceof TransactionTimeoutConfiguration) 603 oldTimeout = ((TransactionTimeoutConfiguration) tm).getTransactionTimeout(); 604 605 tm.setTransactionTimeout(timeout); 607 608 try 609 { 610 tm.begin(); 612 613 if (tsl != null) 615 tsl.userTransactionStarted(); 616 617 Transaction tx = tm.getTransaction(); 618 if (trace) 619 log.trace("UserTx begin: " + tx); 620 621 setTransaction(tx); 623 } 624 finally 625 { 626 if (oldTimeout != -1) 628 tm.setTransactionTimeout(oldTimeout); 629 } 630 } 631 632 public void commit() 633 throws RollbackException , HeuristicMixedException , HeuristicRollbackException , 634 SecurityException , IllegalStateException , SystemException 635 { 636 TransactionManager tm = con.getTransactionManager(); 637 try 638 { 639 Transaction tx = tm.getTransaction(); 640 if (trace) 641 log.trace("UserTx commit: " + tx); 642 643 int status = tm.getStatus(); 644 tm.commit(); 645 } 646 finally 647 { 648 setTransaction(null); 654 } 655 } 656 657 public void rollback() 658 throws IllegalStateException , SecurityException , SystemException 659 { 660 TransactionManager tm = con.getTransactionManager(); 661 try 662 { 663 Transaction tx = tm.getTransaction(); 664 if (trace) 665 log.trace("UserTx rollback: " + tx); 666 tm.rollback(); 667 } 668 finally 669 { 670 setTransaction(null); 676 } 677 } 678 679 public void setRollbackOnly() 680 throws IllegalStateException , SystemException 681 { 682 TransactionManager tm = con.getTransactionManager(); 683 Transaction tx = tm.getTransaction(); 684 if (trace) 685 log.trace("UserTx setRollbackOnly: " + tx); 686 687 tm.setRollbackOnly(); 688 } 689 690 public int getStatus() 691 throws SystemException 692 { 693 TransactionManager tm = con.getTransactionManager(); 694 return tm.getStatus(); 695 } 696 697 701 public void setTransactionTimeout(int seconds) 702 throws SystemException 703 { 704 timeout = seconds; 705 } 706 } 707 } 708 | Popular Tags |