1 16 17 package org.jahia.services.acl; 18 19 import org.apache.log4j.Logger; 20 import org.jahia.exceptions.JahiaException; 21 import org.jahia.exceptions.database.JahiaDatabaseException; 22 import org.jahia.registries.ServicesRegistry; 23 import org.jahia.services.usermanager.JahiaGroup; 24 import org.jahia.services.usermanager.JahiaGroupManagerService; 25 import org.jahia.services.usermanager.JahiaUser; 26 27 import java.io.Serializable ; 28 import java.security.Principal ; 29 import java.security.acl.Group ; 30 import java.util.Enumeration ; 31 import java.util.HashMap ; 32 import java.util.Hashtable ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Vector ; 36 import org.jahia.params.ParamBean; 37 import org.jahia.bin.Jahia; 38 39 40 51 class JahiaACL implements ACLInfo, Serializable , ParentACLFinder, ACLResourceInterface { 52 private static final long serialVersionUID = 1L; 53 54 private static Logger logger = Logger.getLogger (JahiaACL.class); 55 56 57 public static final int TERMINATION_ACL_ID = 0; 58 59 60 private int mID; 61 62 63 private int mParentID = 0; 65 66 private int mInheritance; 67 68 73 private Hashtable mUserEntries; 74 75 80 private Hashtable mGroupEntries; 81 82 90 protected JahiaACL (int id, int parentID, int inheritance) { 91 mID = id; 92 mInheritance = inheritance; 93 mParentID = parentID; 94 mUserEntries = new Hashtable (); 95 mGroupEntries = new Hashtable (); 96 } 97 98 103 public final int getID () { 104 return mID; 105 } 106 107 112 public final int getParentID () { 113 return mParentID; 114 } 115 116 121 public final int getInheritance () { 122 return mInheritance; 123 } 124 125 132 public final boolean setInheritance (int inheritance) { 133 mInheritance = inheritance; 134 try { 135 return AclDBUtils.getInstance ().updateACL (this); 136 } catch (JahiaDatabaseException ex) { 137 return false; 138 } 139 } 140 141 151 public ACLResourceInterface getParent(ACLResourceInterface aclResource) { 152 JahiaACL acl = getInternalACL(aclResource); 153 JahiaACL mParentACL; 154 if (acl.getParentID() <= 0) { 157 return null; 160 } 161 162 if (acl.getParentID() == getID()) { 163 logger.warn("Parent ID of ACL is the same as the current ID (" + 165 getID() + ")! Probable recursive loop"); 166 return this; 167 } 168 169 try { 170 mParentACL = 171 ServicesRegistry.getInstance().getJahiaACLManagerService(). 172 lookupACL( 173 acl.getParentID()); 174 return mParentACL; 175 } catch (JahiaException je) { 176 logger.debug("Parent ACL not found in persistant storage", je); 177 mParentACL = null; 178 return mParentACL; 179 } 180 } 181 182 190 public JahiaACLEntry getUserEntry (JahiaUser user) { 191 if (user != null) { 192 return (JahiaACLEntry) mUserEntries.get (user.getName ()); 193 } 194 return null; 195 } 196 197 207 public synchronized boolean setUserEntry (JahiaUser user, JahiaACLEntry entry) { 208 if ((user == null) || (entry == null)) { 209 return false; 210 } 211 212 boolean result; 213 JahiaACLEntry currentEntry = 214 (JahiaACLEntry) mUserEntries.get (user.getName ()); 215 216 try { 217 if (currentEntry == null) { 218 result = AclDBUtils.getInstance ().addACLEntry (mID, USER_TYPE_ENTRY, 219 user.getName (), entry.getState (), entry.getTriState ()); 220 } else { 221 result = AclDBUtils.getInstance ().updateACLEntry (mID, USER_TYPE_ENTRY, 222 user.getName (), entry.getState (), entry.getTriState ()); 223 } 224 } catch (JahiaDatabaseException ex) { 225 return false; 226 } 227 228 if (result) { 229 mUserEntries.put (user.getName (), entry); 230 } 231 return result; 232 } 233 234 239 public void setUserEntries (Hashtable userEntries) { 240 mUserEntries = userEntries; 241 } 242 243 251 public synchronized boolean removeUserEntry (JahiaUser user) { 252 boolean result = false; 253 if (user != null) { 254 try { 255 result = AclDBUtils.getInstance ().removeACLEntry (mID, USER_TYPE_ENTRY, 256 user.getName ()); 257 if (result) { 258 mUserEntries.remove (user.getName ()); 259 return true; 260 } 261 } catch (JahiaDatabaseException ex) { 262 } 263 } 264 return result; 265 } 266 267 275 protected synchronized boolean clearEntries (int type) { 276 boolean result = false; 277 try { 278 result = AclDBUtils.getInstance ().removeACLEntries (mID, type); 279 if (result) { 280 if (type == USER_TYPE_ENTRY) { 281 mUserEntries.clear(); 282 } else if (type == GROUP_TYPE_ENTRY) { 283 mGroupEntries.clear(); 284 } 285 } 286 } catch (JahiaDatabaseException ex) { 287 } 288 289 return result; 290 } 291 292 308 public Vector getUsernameList (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaACLEntry entry) { 309 Map map = new HashMap (mUserEntries.size()); 310 recursePermissions (parentACLFinder, aclResource, map, null); 311 return getNameList (map, entry); 312 } 313 314 326 public Vector getUsernameList (JahiaACLEntry entry) { 327 return getUsernameList(this, this, entry); 328 } 329 330 348 public Vector getUsernameListAlsoGroupUsers (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaACLEntry entry) { 349 Hashtable userTable = new Hashtable (mUserEntries.size()); 350 Hashtable groupTable = new Hashtable (mGroupEntries.size()); 351 recursePermissions (parentACLFinder, aclResource, userTable, groupTable); 352 353 Vector result = getNameList (userTable, entry); 354 for (int k = 0; k < result.size (); k++) { 355 logger.debug ("Name=" + (String ) result.get (k)); 356 ACLResourceInterface parent = getParent(aclResource); 357 if (parent != null && parent.getACL() != null) { 358 JahiaUser user = ServicesRegistry 359 .getInstance () 360 .getJahiaUserManagerService () 361 .lookupUser ((String ) result.get (k)); 362 JahiaACLEntry parentEntry = getInternalACL(parent).getUserEntry (user); 363 if (parentEntry != null) { 364 logger.debug ("parentAclEntry=" + parentEntry.toString ()); 365 } 366 } 367 368 } 369 Vector groupList = getNameList (groupTable, entry); 370 371 userTable = null; 372 groupTable = null; 373 374 for (int i = 0; i < groupList.size (); i++) { 377 String groupname = (String ) groupList.elementAt (i); 378 JahiaGroup group = ServicesRegistry.getInstance (). 379 getJahiaGroupManagerService ().lookupGroup (groupname); 380 if (group == null) { 381 logger.warn("Group " + groupname + " not found in manager service but present in ACL " + getID()); 382 continue; 383 } 384 Enumeration membersEnum = group.members (); 385 386 if (membersEnum != null) { 387 388 Principal p = null; 389 390 while (membersEnum.hasMoreElements ()) { 391 392 p = (Principal ) membersEnum.nextElement (); 393 if (!(p instanceof Group)) { 394 395 JahiaUser user = (JahiaUser) p; 396 if ((user != null) && (!result.contains (user.getName ()))) { 397 398 400 401 if (entry == null) { 402 result.add (user.getName ()); 403 } else { 404 409 410 int permBit = -1; 412 for (int j = 0; j < 3; j++) { 413 if (entry.getPermission (j) == 414 JahiaACLEntry.ACL_YES) { 415 permBit = j; 416 } 417 } 418 if ((permBit != -1) && 419 (this.getPermission (parentACLFinder, aclResource, user, permBit))) { 420 result.add (user.getName ()); 421 } 422 } 423 } 424 user = null; 425 } 426 } 427 p = null; 428 } 429 groupname = null; 430 group = null; 431 membersEnum = null; 432 } 433 return result; 434 } 435 436 449 public Vector getUsernameListAlsoGroupUsers (JahiaACLEntry entry) { 450 return getUsernameListAlsoGroupUsers(this, this, entry); 451 } 452 453 461 public JahiaACLEntry getGroupEntry (JahiaGroup group) { 462 if (group != null) { 463 return (JahiaACLEntry) mGroupEntries.get (group.getName ()); 464 } 465 return null; 466 } 467 468 478 public synchronized boolean setGroupEntry (JahiaGroup group, JahiaACLEntry entry) { 479 if ((group == null) || (entry == null)) { 480 return false; 481 } 482 483 boolean result; 484 JahiaACLEntry tmp = (JahiaACLEntry) mGroupEntries.get (group.getName ()); 485 486 try { 487 if (tmp == null) { 488 result = AclDBUtils.getInstance ().addACLEntry (mID, GROUP_TYPE_ENTRY, 489 group.getName (), entry.getState (), entry.getTriState ()); 490 } else { 491 result = AclDBUtils.getInstance ().updateACLEntry (mID, GROUP_TYPE_ENTRY, 492 group.getName (), entry.getState (), entry.getTriState ()); 493 } 494 } catch (JahiaDatabaseException ex) { 495 logger.error("Error while setting ACL entry for group " + group.getGroupKey(), ex); 496 result = false; 497 tmp = null; 498 } 499 tmp = null; 500 501 if (result) { 502 mGroupEntries.put (group.getName (), entry); 503 } 504 505 return result; 506 } 507 508 513 public void setGroupEntries (Hashtable groupEntries) { 514 mGroupEntries = groupEntries; 515 } 516 517 524 public synchronized boolean removeGroupEntry (JahiaGroup group) { 525 if (group == null) { 526 return false; 527 } 528 529 try { 530 if (AclDBUtils.getInstance ().removeACLEntry (mID, GROUP_TYPE_ENTRY, group.getName ())) { 531 mGroupEntries.remove (group.getName ()); 532 return true; 533 } 534 } catch (JahiaDatabaseException ex) { 535 } 536 537 return false; 538 } 539 540 556 public Vector getGroupnameListNoAdmin (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaACLEntry entry) { 557 Vector result = getGroupnameList (parentACLFinder, aclResource, entry); 558 for (int i = 0; i < result.size (); i++) { 559 String adminGroup = (String ) result.elementAt (i); 560 if (adminGroup.indexOf (JahiaGroupManagerService.ADMINISTRATORS_GROUPNAME) == 0) 561 result.removeElementAt (i--); 562 } 563 return result; 564 } 565 566 578 public Vector getGroupnameListNoAdmin (JahiaACLEntry entry) { 579 return getGroupnameListNoAdmin(this, this, entry); 580 } 581 582 598 public Vector getGroupnameList (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaACLEntry entry) { 599 Map table = new HashMap (mGroupEntries.size()); 600 recursePermissions (parentACLFinder, aclResource, null, table); 601 Vector result = getNameList (table, entry); 602 table = null; 603 return result; 604 } 605 606 616 public Vector getGroupnameList (JahiaACLEntry entry) { 617 return getGroupnameList(this, this, entry); 618 } 619 620 635 public boolean getPermission (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaGroup group, int permission) { 636 boolean result = false; 637 638 if (group != null) { 639 Map map = new HashMap (mGroupEntries.size()); 640 recursePermissions (parentACLFinder, aclResource, null, map); 641 JahiaACLEntry entry = (JahiaACLEntry) map.get (group.getName ()); 642 if (entry != null) { 643 result = (entry.getPermission (permission) == 644 JahiaACLEntry.ACL_YES); 645 } 646 map = null; 647 entry = null; 648 } 649 if (logger.isDebugEnabled()) { 650 logger.debug("JahiaACL{" + mID + ", " + mParentID + ", " 651 + mInheritance + "}.getPermission(" 652 + (group != null ? group.getGroupKey() : null) + ", " 653 + permission + "):" + result); 654 } 655 return result; 656 } 657 658 670 public boolean getPermission (JahiaGroup group, int permission) { 671 return getPermission(this, this, group, permission); 672 } 673 674 690 public boolean getPermission (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, JahiaUser user, int permission) { 691 int result = -1; 692 693 if (user == null) { 694 return false; 695 } 696 697 try { 698 699 702 711 ParamBean paramBean = Jahia.getThreadParamBean(); 712 JahiaGroup adminGroup = null; 713 int contextSiteID = -1; 714 if (paramBean != null) { 715 contextSiteID = paramBean.getSiteID(); 716 } else { 717 logger.debug("Warning, no ParamBean found in thread context, using user siteID to resolve administrator group lookup ! Possible false permissions !"); 718 contextSiteID = user.getSiteID(); 719 } 720 721 if (contextSiteID != -1) { 722 adminGroup = ServicesRegistry.getInstance() 723 .getJahiaGroupManagerService().getAdministratorGroup( 724 contextSiteID); 725 if (adminGroup != null) { 726 if (adminGroup.isMember(user)) { 727 result = 1; 728 } 729 } 730 } else { 731 logger.warn("User comes from LDAP, so we can test it's apartanence to the administrators group when we have no site ID"); 732 } 733 735 if (result == -1) { 736 adminGroup = null; 737 738 Map userMap = new HashMap (mUserEntries.size()); 741 Map groupMap = new HashMap (mGroupEntries.size()); 742 recursePermissions (parentACLFinder, aclResource, userMap, groupMap); 743 744 745 result = getUserPermissionInMap (user, permission, userMap); 748 749 751 if (result == -1) { 752 result = getUserPermissionInGroupMap (user, permission, 756 groupMap); 757 } 758 } 760 } catch (NullPointerException ex) { 761 result = 0; 762 } 763 764 if (logger.isDebugEnabled()) { 765 logger.debug("JahiaACL{" + mID + ", " + mParentID + ", " 766 + mInheritance + "}.getPermission(" 767 + (user != null ? user.getUserKey() : null) + ", " 768 + permission + "): " + (result == 1)); 769 } 770 771 return (result == 1); 774 } 775 776 788 public boolean getPermission (JahiaUser user, int permission) { 789 return getPermission(this, this, user, permission); 790 } 791 792 798 public String toString () { 799 StringBuffer buffer = new StringBuffer (); 800 String key = null; 801 JahiaACLEntry entry = null; 802 803 buffer.append ("\n"); 804 buffer.append ("Detail of ACL object ["); 805 buffer.append (Integer.toString (mID)); 806 buffer.append ("] :\n"); 807 buffer.append (" -ACL parent ID = "); 808 809 if ((getParent(this) != null) && 810 (getParent(this).getACL() != null)) { 811 buffer.append (Integer.toString (mParentID)); 812 } else { 813 buffer.append ("-no parent-"); 814 } 815 buffer.append ("\n"); 816 buffer.append (" -ACL inheritance = "); 817 buffer.append (Integer.toString (mInheritance)); 818 819 buffer.append ("\n\n"); 820 821 buffer.append (" -Local user access : "); 823 Enumeration usernames = mUserEntries.keys (); 824 if (usernames.hasMoreElements ()) { 825 buffer.append ("\n"); 826 while (usernames.hasMoreElements ()) { 827 key = (String ) usernames.nextElement (); 828 entry = (JahiaACLEntry) mUserEntries.get (key); 829 int state = entry.getState (); 830 int triState = entry.getTriState (); 831 buffer.append (" -" + key + " : [" + Integer.toBinaryString (state) + 832 "] [" + Integer.toBinaryString (triState) + "]\n"); 833 } 834 } else { 835 buffer.append ("-no users-\n"); 836 } 837 838 buffer.append (" -Local group access : "); 840 Enumeration groupnames = mGroupEntries.keys (); 841 if (groupnames.hasMoreElements ()) { 842 buffer.append ("\n"); 843 while (groupnames.hasMoreElements ()) { 844 key = (String ) groupnames.nextElement (); 845 entry = (JahiaACLEntry) mGroupEntries.get (key); 846 int state = entry.getState (); 847 int triState = entry.getTriState (); 848 buffer.append (" -" + key + " : [" + Integer.toBinaryString (state) + 849 "] [" + Integer.toBinaryString (triState) + "]\n"); 850 } 851 } else { 852 buffer.append ("-no groups-\n"); 853 } 854 855 Hashtable userTable = new Hashtable (mUserEntries.size()); 857 Hashtable groupTable = new Hashtable (mGroupEntries.size()); 858 recursePermissions (this, this, userTable, groupTable); 859 860 buffer.append (" -recursed user access : "); 861 usernames = userTable.keys (); 862 if (usernames.hasMoreElements ()) { 863 buffer.append ("\n"); 864 while (usernames.hasMoreElements ()) { 865 key = (String ) usernames.nextElement (); 866 entry = (JahiaACLEntry) userTable.get (key); 867 int state = entry.getState (); 868 int triState = entry.getTriState (); 869 buffer.append (" -" + key + " : [" + Integer.toBinaryString (state) + 870 "] [" + Integer.toBinaryString (triState) + "]\n"); 871 } 872 } else { 873 buffer.append ("-no users-\n"); 874 } 875 876 buffer.append (" -recursed group access : "); 877 groupnames = groupTable.keys (); 878 if (groupnames.hasMoreElements ()) { 879 buffer.append ("\n"); 880 while (groupnames.hasMoreElements ()) { 881 key = (String ) groupnames.nextElement (); 882 entry = (JahiaACLEntry) groupTable.get (key); 883 int state = entry.getState (); 884 int triState = entry.getTriState (); 885 buffer.append (" -" + key + " : [" + Integer.toBinaryString (state) + 886 "] [" + Integer.toBinaryString (triState) + "]\n"); 887 } 888 } else { 889 buffer.append ("-no groups-\n"); 890 } 891 892 usernames = null; 893 groupnames = null; 894 userTable = null; 895 groupTable = null; 896 key = null; 897 entry = null; 898 899 return buffer.toString (); 900 } 901 902 914 private int getUserPermissionInMap (JahiaUser user, int permission, Map map) { 915 int result = -1; 917 JahiaACLEntry entry = (JahiaACLEntry) map.get (user.getName ()); 919 if (entry != null) { 920 switch (entry.getPermission (permission)) { 921 case JahiaACLEntry.ACL_YES: 922 result = 1; 923 break; 924 925 case JahiaACLEntry.ACL_NO: 926 result = 0; 927 break; 928 } 929 } 930 entry = null; 931 932 return result; 933 } 934 935 948 private int getUserPermissionInGroupMap (JahiaUser user, int permission, 949 Map map) { 950 int result = -1; 951 952 for (Iterator keys = map.keySet().iterator(); keys.hasNext();) { 954 String groupKey = (String ) keys.next(); 955 JahiaGroup group = ServicesRegistry.getInstance (). 956 getJahiaGroupManagerService ().lookupGroup (groupKey); 957 958 if (group != null) { 959 961 963 if (group.isMember (user)) { 964 966 if (result < 0) { 970 result = 0; 971 } 972 973 JahiaACLEntry entry = (JahiaACLEntry) map.get (groupKey); 975 if (entry.getPermission (permission) == 976 JahiaACLEntry.ACL_YES) { 977 result = 1; 978 } 979 entry = null; 980 } else { 981 } 983 984 } } 987 return result; 988 } 989 990 1006 private void recursePermissions (ParentACLFinder parentACLFinder, ACLResourceInterface aclResource, Map userTable, Map groupTable) { 1007 1008 if (userTable != null) { 1009 buildPermissions (userTable, mUserEntries); 1010 } 1011 if (groupTable != null) { 1012 buildPermissions (groupTable, mGroupEntries); 1013 } 1014 ACLResourceInterface parentACLResource = parentACLFinder.getParent(aclResource); 1015 if (parentACLResource != null && 1016 getInternalACL(parentACLResource) != null && 1017 mInheritance == 0) { 1018 getInternalACL(parentACLResource).recursePermissions (parentACLFinder, parentACLResource, userTable, groupTable); 1019 } 1020 } 1021 1022 1033 private static final void buildPermissions (Map map, Map localMap) { 1034 for (Iterator keys = localMap.keySet().iterator(); keys.hasNext();) { 1038 String key = (String ) keys.next(); 1039 1040 if (key != null) { 1041 JahiaACLEntry entry = (JahiaACLEntry) map.get (key); 1042 JahiaACLEntry localEntry = (JahiaACLEntry) localMap.get (key); 1043 1044 if (entry != null) { 1047 int tristate = entry.getTriState (); 1048 int localTristate = localEntry.getTriState (); 1049 1050 int mask = ((~localTristate) & tristate); 1052 1053 if (mask != 0) { 1056 int state = entry.getState (); 1057 1058 int permissionMask = (localEntry.getState () & mask); 1060 1061 state = (state | permissionMask); 1063 1064 tristate = ((~mask) & tristate); 1066 1067 entry.set (state, tristate); 1069 } 1070 } else { 1071 map.put (key, localEntry.clone ()); 1072 } 1073 } 1074 } 1076 } 1077 1078 1089 private Vector getNameList (Map map, JahiaACLEntry entry) { 1090 Vector result; 1091 1092 if (entry == null) { 1093 return getKeysFromHashMap (map); 1094 } else { 1095 result = new Vector (); 1096 for (Iterator keys = map.keySet().iterator(); keys.hasNext();) { 1097 String name = (String ) keys.next(); 1098 JahiaACLEntry hashtableEntry = (JahiaACLEntry) map.get (name); 1099 if (hashtableEntry.hasSameBitsActivated (entry)) { 1100 result.add (name); 1101 } 1102 } 1103 } 1104 return result; 1105 } 1106 1107 1115 protected Vector getKeysFromHashMap (Map map) { 1116 Vector vect = new Vector (map.size()); 1117 for (Iterator keys = map.keySet().iterator(); keys.hasNext();) { 1118 vect.add(keys.next()); 1119 } 1120 return vect; 1121 } 1122 1123 1129 public Hashtable getAllUserEntries () { 1130 return mUserEntries; 1131 } 1132 1133 1139 public Hashtable getAllGroupEntries () { 1140 return mGroupEntries; 1141 } 1142 1143 1151 public void setParentACL (JahiaACL parentACL) 1152 throws JahiaDatabaseException { 1153 setParentACL (parentACL, true); 1154 } 1155 1156 1165 protected void setParentACL (JahiaACL parentACL, boolean update) 1166 throws JahiaDatabaseException { 1167 if (parentACL == null) { 1168 throw new JahiaDatabaseException ( 1169 "Could not set parent of ACL because the parameter passed as the parent is null", 1170 JahiaDatabaseException.ACL_ERROR); 1171 } 1172 1173 mParentID = parentACL.getID (); 1174 1175 if (update) { 1176 AclDBUtils.getInstance ().updateACL (this); 1177 } 1178 } 1179 1180 1185 public Object clone() { 1186 final JahiaACL acl = new JahiaACL(mID, mParentID, mInheritance); 1187 acl.setUserEntries(new Hashtable (mUserEntries)); 1188 acl.setGroupEntries(new Hashtable (mGroupEntries)); 1189 return acl; 1190 } 1191 1192 1201 public boolean isAclInParents (int aclId) { 1202 JahiaACL parentAcl = getInternalACL(this.getParent (this)); 1203 if (parentAcl == null) { 1204 return false; 1205 } 1206 if (parentAcl.getID () == aclId) { 1207 return true; 1208 } 1209 return parentAcl.isAclInParents (aclId); 1210 } 1211 1212 1213 1214 public JahiaBaseACL getACL() { 1215 try { 1216 return new JahiaBaseACL(getID()); 1217 } catch (Throwable t) { 1218 return null; 1220 } 1221 } 1222 1223 public int getAclID() { 1224 return getID(); 1225 } 1226 1227 private JahiaACL getInternalACL(ACLResourceInterface aclResource) { 1228 if (aclResource.getACL() == null) { 1229 return null; 1230 } 1231 return aclResource.getACL().getACL(); 1232 } 1233} 1234 | Popular Tags |