Changeset 448

Show
Ignore:
Timestamp:
05/04/06 15:16:09
Author:
douglm
Message:

Define new class to hold all allowed privileges
Add code to handle special cases of attempting to access the user calendar root folder or
home directories.

User root should be denied to all except superuser to prevent user browsing
User home directory needs to be limited to read + write-content + writeacl for anybody except
the superuser to prevent users deleting or renaming that directory.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/calendar3/access/src/edu/rpi/cct/uwcal/access/Access.java

    r320 r448  
    5858import edu.rpi.cct.uwcal.access.Acl.CurrentAccess; 
    5959 
    60 /** Class to handle access control. Because we may be evaluating access  
     60/** Class to handle access control. Because we may be evaluating access 
    6161 * frequently we try do so without creating (many) objects. 
    6262 * 
     
    110110      acl.addAce(new Ace(null, false, Ace.whoTypeUnauthenticated, read)); 
    111111      defaultPublicAccess = new String(acl.encode()); 
    112        
     112 
    113113      acl.clear(); 
    114114      acl.addAce(new Ace(null, false, Ace.whoTypeOwner, all)); 
     
    119119    } 
    120120  } 
    121    
     121 
    122122  /** Constructor 
    123123   * 
     
    186186   * @param how      Privilege set definign desired access 
    187187   * @param aclString String defining current acls for object 
     188   * @param filter    if not null specifies maximum access 
    188189   * @return CurrentAccess   access + allowed/disallowed 
    189190   * @throws AccessException 
    190191   */ 
    191192  public CurrentAccess evaluateAccess(AccessPrincipal who, String owner, 
    192                                       Privilege[] how, String aclString) 
    193           throws AccessException { 
    194     return new Acl(debug).evaluateAccess(who, owner, how, aclString.toCharArray()); 
     193                                      Privilege[] how, String aclString, 
     194                                      PrivilegeSet filter) 
     195          throws AccessException { 
     196    return new Acl(debug).evaluateAccess(who, owner, how, 
     197                                         aclString.toCharArray(), 
     198                                         filter); 
    195199  } 
    196200 
     
    201205   * @param how      Privilege set defining desired access 
    202206   * @param aclChars char[] defining current acls for object 
     207   * @param filter    if not null specifies maximum access 
    203208   * @return CurrentAccess   access + allowed/disallowed 
    204209   * @throws AccessException 
    205210   */ 
    206211  public CurrentAccess evaluateAccess(AccessPrincipal who, String owner, 
    207                                       Privilege[] how, char[] aclChars) 
    208           throws AccessException { 
    209     return new Acl(debug).evaluateAccess(who, owner, how, aclChars); 
     212                                      Privilege[] how, char[] aclChars, 
     213                                      PrivilegeSet filter) 
     214          throws AccessException { 
     215    return new Acl(debug).evaluateAccess(who, owner, how, aclChars, 
     216                                         filter); 
    210217  } 
    211218 
     
    215222   * @param owner    String owner of object 
    216223   * @param aclChars char[] defining current acls for object 
     224   * @param filter    if not null specifies maximum access 
    217225   * @return CurrentAccess   access + allowed/disallowed 
    218226   * @throws AccessException 
    219227   */ 
    220228  public CurrentAccess checkRead(AccessPrincipal who, String owner, 
    221                                  char[] aclChars) 
    222           throws AccessException { 
    223     return new Acl(debug).evaluateAccess(who, owner, privSetRead, aclChars); 
     229                                 char[] aclChars, 
     230                                 PrivilegeSet filter) 
     231          throws AccessException { 
     232    return new Acl(debug).evaluateAccess(who, owner, privSetRead, aclChars, 
     233                                         filter); 
    224234  } 
    225235 
     
    229239   * @param owner    String owner of object 
    230240   * @param aclChars char[] defining current acls for object 
     241   * @param filter    if not null specifies maximum access 
    231242   * @return CurrentAccess   access + allowed/disallowed 
    232243   * @throws AccessException 
    233244   */ 
    234245  public CurrentAccess checkReadWrite(AccessPrincipal who, String owner, 
    235                                       char[] aclChars) 
    236           throws AccessException { 
    237     return new Acl(debug).evaluateAccess(who, owner, privSetReadWrite, aclChars); 
     246                                      char[] aclChars, 
     247                                      PrivilegeSet filter) 
     248          throws AccessException { 
     249    return new Acl(debug).evaluateAccess(who, owner, privSetReadWrite, aclChars, 
     250                                         filter); 
    238251  } 
    239252 
     
    244257   * @param priv     int desired access as defined above 
    245258   * @param aclChars char[] defining current acls for object 
     259   * @param filter    if not null specifies maximum access 
    246260   * @return CurrentAccess   access + allowed/disallowed 
    247261   * @throws AccessException 
    248262   */ 
    249263  public CurrentAccess evaluateAccess(AccessPrincipal who, String owner, 
    250                                       int priv, char[] aclChars) 
     264                                      int priv, char[] aclChars, 
     265                                      PrivilegeSet filter) 
    251266          throws AccessException { 
    252267    return new Acl(debug).evaluateAccess(who, owner, 
    253268                                         new Privilege[]{Privileges.makePriv(priv)}, 
    254                                          aclChars); 
     269                                         aclChars, filter); 
    255270  } 
    256271} 
  • trunk/calendar3/access/src/edu/rpi/cct/uwcal/access/Ace.java

    r445 r448  
    166166  private boolean notWho; 
    167167 
    168   /** array of allowed/denied/undefined indexed by Privilege index 
    169    */ 
    170   private char[] how; 
     168  /** allowed/denied/undefined indexed by Privilege index 
     169   */ 
     170  private PrivilegeSet how; 
    171171 
    172172  /** Privilege objects defining the access. Used when manipulating acls 
     
    200200             boolean notWho, 
    201201             int whoType, 
    202              char[] how) { 
     202             PrivilegeSet how) { 
    203203    this.who = who; 
    204204    this.notWho = notWho; 
     
    287287 
    288288  /** 
    289    * @param val char[] array of allowed/denied/undefined indexed by Privilege index 
    290    */ 
    291   public void setHow(char[] val) { 
     289   * @param val PrivilegeSet of allowed/denied/undefined indexed by Privilege index 
     290   */ 
     291  public void setHow(PrivilegeSet val) { 
    292292    how = val; 
    293293  } 
     
    295295  /** 
    296296   * 
    297    * @return char[] array of allowed/denied/undefined indexed by Privilege index 
    298    */ 
    299   public char[] getHow() { 
     297   * @return PrivilegeSet array of allowed/denied/undefined indexed by Privilege index 
     298   */ 
     299  public PrivilegeSet getHow() { 
    300300    return how; 
    301301  } 
     
    348348   * @param name 
    349349   * @param whoType 
    350    * @return char[]    merged privileges if we find a match else null 
     350   * @return PrivilegeSet    merged privileges if we find a match else null 
    351351   * @throws AccessException 
    352352   */ 
    353   public static char[] findMergedPrivilege(Acl acl, 
     353  public static PrivilegeSet findMergedPrivilege(Acl acl, 
    354354                                           String name, int whoType) throws AccessException { 
    355     char[] privileges = null; 
     355    PrivilegeSet privileges = null; 
    356356    Iterator it = acl.getAces().iterator(); 
    357357 
     
    363363           (whoType == whoTypeOwner) || 
    364364            ace.whoMatch(name))) { 
    365         privileges = mergePrivileges(privileges, ace.getHow(), 
    366                                      ace.getInherited()); 
     365        privileges = PrivilegeSet.mergePrivileges(privileges, ace.getHow(), 
     366                                                  ace.getInherited()); 
    367367      } 
    368368    } 
    369369 
    370370    return privileges; 
    371   } 
    372  
    373   /** If current is null it is set to a cloned copy of morePriv otherwise the 
    374    * privilege(s) in morePriv are merged into current. 
    375    * 
    376    * <p>Specified access overrides inherited access,<br/> 
    377    * allowed overrides denied overrides unspecified so the order is, from 
    378    * highest to lowest:<br/> 
    379    * 
    380    * allowed, denied, allowedInherited, deniedInherited, unspecified. 
    381    * 
    382    * <p>Only allowed and denied appear in encoded aces. 
    383    * 
    384    * @param current 
    385    * @param morePriv 
    386    * @param inherited   true if the ace was an inherited ace 
    387    * @return char[]  mergedPrivileges 
    388    */ 
    389   public static char[] mergePrivileges(char[] current, char[] morePriv, 
    390                                        boolean inherited) { 
    391     char[] mp = (char[])morePriv.clone(); 
    392  
    393     if (inherited) { 
    394       for (int i = 0; i <= privMaxType; i++) { 
    395         char p = mp[i]; 
    396         if (p == allowed) { 
    397           mp[i] = allowedInherited; 
    398         } else if (p == denied) { 
    399           mp[i] = deniedInherited; 
    400         } 
    401       } 
    402     } 
    403     if (current == null) { 
    404       return mp; 
    405     } 
    406  
    407     for (int i = 0; i <= privMaxType; i++) { 
    408       if (current[i] < mp[i]) { 
    409         current[i] = mp[i]; 
    410       } 
    411     } 
    412  
    413     return current; 
    414371  } 
    415372 
  • trunk/calendar3/access/src/edu/rpi/cct/uwcal/access/Acl.java

    r445 r448  
    130130     * @see PrivilegeDefs 
    131131     */ 
    132     public char[] privileges = null; 
     132    public PrivilegeSet privileges = null; 
    133133 
    134134    /** Privileges desired */ 
     
    183183   * @param how 
    184184   * @param acl 
     185   * @param filter    if not null specifies maximum access 
    185186   * @return CurrentAccess   access + allowed/disallowed 
    186187   * @throws AccessException 
    187188   */ 
    188189  public CurrentAccess evaluateAccess(AccessPrincipal who, String owner, 
    189                                       Privilege[] how, char[] acl) 
     190                                      Privilege[] how, char[] acl, 
     191                                      PrivilegeSet filter) 
    190192          throws AccessException { 
    191193    boolean authenticated = !who.getUnauthenticated(); 
     
    222224        ca.privileges = Ace.findMergedPrivilege(this, null, Ace.whoTypeOwner); 
    223225        if (ca.privileges == null) { 
    224           ca.privileges = defaultOwnerPrivileges
     226          ca.privileges = PrivilegeSet.makeDefaultOwnerPrivileges()
    225227        } 
    226228 
     
    232234      if (ca.privileges != null) { 
    233235        if (debug) { 
    234           debugsb.append("... For user got: " + new String(ca.privileges)); 
     236          debugsb.append("... For user got: " + ca.privileges); 
    235237        } 
    236238 
     
    248250            debugsb.append("...Try access for group " + group); 
    249251          } 
    250           char[] privs = Ace.findMergedPrivilege(this, group, Ace.whoTypeGroup); 
     252          PrivilegeSet privs = Ace.findMergedPrivilege(this, group, Ace.whoTypeGroup); 
    251253          if (privs != null) { 
    252             ca.privileges = Ace.mergePrivileges(ca.privileges, privs, false); 
     254            ca.privileges = PrivilegeSet.mergePrivileges(ca.privileges, privs, false); 
    253255          } 
    254256        } 
     
    257259      if (ca.privileges != null) { 
    258260        if (debug) { 
    259           debugsb.append("...For groups got: " + new String(ca.privileges)); 
     261          debugsb.append("...For groups got: " + ca.privileges); 
    260262        } 
    261263 
     
    267269      if (ca.privileges != null) { 
    268270        if (debug) { 
    269           debugsb.append("...For other got: " + new String(ca.privileges)); 
     271          debugsb.append("...For other got: " + ca.privileges); 
    270272        } 
    271273 
     
    281283    } 
    282284 
    283     ca.privileges = (char[])ca.privileges.clone(); 
    284     for (int pi = 0; pi < ca.privileges.length; pi++) { 
    285       if (ca.privileges[pi] == unspecified) { 
    286         if (isOwner) { 
    287           ca.privileges[pi] = allowed; 
    288         } else { 
    289           ca.privileges[pi] = denied; 
    290         } 
    291       } 
     285    ca.privileges.setUnspecified(isOwner); 
     286 
     287    if (filter != null) { 
     288      ca.privileges.filterPrivileges(filter); 
    292289    } 
    293290 
    294291    for (int i = 0; i < how.length; i++) { 
    295       char priv = ca.privileges[how[i].getIndex()]
     292      char priv = ca.privileges.getPrivilege(how[i].getIndex())
    296293 
    297294      if ((priv != allowed) && (priv != allowedInherited)) { 
     
    377374    } 
    378375 
    379     return aces.remove(new Ace(who, notWho, whoType, (char[])null)); 
     376    return aces.remove(new Ace(who, notWho, whoType, (PrivilegeSet)null)); 
    380377  } 
    381378 
  • trunk/calendar3/access/src/edu/rpi/cct/uwcal/access/PrivilegeDefs.java

    r445 r448  
    184184 
    185185  /** Default privs for an owner 
    186    *
     186   *
    187187  public char[] defaultOwnerPrivileges = { 
    188188    allowed,   // privAll 
     
    201201  }; 
    202202 
     203  /** User home max privileges for non-super user 
     204   * This allows us to turn off privileges which would allow delete or rename 
     205   * for example. 
     206   * / 
     207  public char[] userHomeMaxPrivileges = { 
     208     denied,   // privAll 
     209    allowed,   // privRead 
     210    allowed,   // privReadAcl 
     211    allowed,   // privReadCurrentUserPrivilegeSet 
     212    allowed,   // privReadFreeBusy 
     213     denied,   // privWrite 
     214    allowed,   // privWriteAcl 
     215    allowed,   // privWriteProperties 
     216    allowed,   // privWriteContent 
     217     denied,   // privBind 
     218     denied,   // privUnbind 
     219    allowed,   // privUnlock 
     220    allowed,   // privNone 
     221  }; 
     222 
    203223  /** Default privs for a non owner 
    204    *
     224   *
    205225  public char[] defaultNonOwnerPrivileges = { 
    206226    denied,   // privAll 
     
    217237    denied,   // privUnlock 
    218238    denied,   // privNone 
    219   }; 
     239  };*/ 
    220240 
    221241} 
  • trunk/calendar3/access/src/edu/rpi/cct/uwcal/access/Privileges.java

    r445 r448  
    196196   * @throws AccessException 
    197197   */ 
    198   public static char[] fromEncoding(EncodedAcl acl) throws AccessException { 
     198  public static PrivilegeSet fromEncoding(EncodedAcl acl) throws AccessException { 
    199199    char[] privStates = { 
    200200      unspecified,   // privAll 
     
    229229    } 
    230230 
    231     return privStates
     231    return new PrivilegeSet(privStates)
    232232  } 
    233233 
  • trunk/calendar3/appcommon/src/org/bedework/appcommon/AccessAppUtil.java

    r445 r448  
    6262import edu.rpi.cct.uwcal.access.Privilege; 
    6363import edu.rpi.cct.uwcal.access.PrivilegeDefs; 
     64import edu.rpi.cct.uwcal.access.PrivilegeSet; 
    6465import edu.rpi.cct.uwcal.access.Privileges; 
    6566import edu.rpi.sss.util.xml.QName; 
     
    254255   * returning the representation a a String 
    255256   * 
    256    * @param privileges    char[] of allowed/disallowed 
     257   * @param ps    PrivilegeSet allowed/disallowed 
    257258   * @return String xml 
    258259   * @throws CalFacadeException 
    259260   */ 
    260   public static String getCurrentPrivSetString(char[] privileges) 
     261  public static String getCurrentPrivSetString(PrivilegeSet ps) 
    261262          throws CalFacadeException { 
    262263    try { 
     264      char[] privileges = ps.getPrivileges(); 
     265 
    263266      XmlEmit xml = new XmlEmit(true);  // no headers 
    264267      StringWriter su = new StringWriter(); 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/AccessUtil.java

    r445 r448  
    5858import edu.rpi.cct.uwcal.access.Acl; 
    5959import edu.rpi.cct.uwcal.access.PrivilegeDefs; 
     60import edu.rpi.cct.uwcal.access.PrivilegeSet; 
    6061import edu.rpi.cct.uwcal.access.Acl.CurrentAccess; 
    6162 
     
    6667import org.bedework.calfacade.BwLocation; 
    6768import org.bedework.calfacade.BwSponsor; 
     69import org.bedework.calfacade.BwSystem; 
    6870import org.bedework.calfacade.BwUser; 
    6971import org.bedework.calfacade.CalFacadeAccessException; 
     
    9395  private BwUser authUser; 
    9496 
     97  private BwSystem syspars; 
     98 
     99  private String userRootPath; 
     100 
     101  private String userHomePathPrefix; 
     102 
    95103  private transient Logger log; 
    96104 
     
    140148   */ 
    141149  public void close() { 
     150  } 
     151 
     152  /** Set the system parameters object. 
     153   * @param val 
     154   */ 
     155  public void setSyspars(BwSystem val) { 
     156    syspars = val; 
     157 
     158    userRootPath = "/" + syspars.getUserCalendarRoot(); 
     159    userHomePathPrefix = userRootPath + "/"; 
    142160  } 
    143161 
     
    249267 
    250268    try { 
    251       CurrentAccess ca; 
     269      CurrentAccess ca = null; 
     270 
    252271      String account = ent.getOwner().getAccount(); 
    253  
    254       char[] aclChars = getAclChars(ent); 
    255  
    256       if (desiredAccess == privRead) { 
    257         ca = access.checkRead(authUser, account, aclChars); 
    258       } else if (desiredAccess == privWrite) { 
    259         ca = access.checkReadWrite(authUser, account, aclChars); 
    260       } else { 
    261         ca = access.evaluateAccess(authUser, account, desiredAccess, aclChars); 
     272      PrivilegeSet maxPrivs = null; 
     273 
     274      char[] aclChars = null; 
     275 
     276      if (ent instanceof BwCalendar) { 
     277        BwCalendar cal = (BwCalendar)ent; 
     278        String path = cal.getPath(); 
     279 
     280        if (userRootPath.equals(path)) { 
     281          ca = new CurrentAccess(); 
     282 
     283          if (getSuperUser()) { 
     284            ca.privileges = PrivilegeSet.makeDefaultOwnerPrivileges(); 
     285          } else { 
     286            ca.privileges = PrivilegeSet.makeDefaultNonOwnerPrivileges(); 
     287          } 
     288        } else if (path.equals(userHomePathPrefix + account)){ 
     289          // Accessing user home directory 
     290          if (getSuperUser()) { 
     291            ca = new CurrentAccess(); 
     292 
     293            ca.privileges = PrivilegeSet.makeDefaultOwnerPrivileges(); 
     294          } else { 
     295            // Set the maximumn access 
     296            maxPrivs = PrivilegeSet.userHomeMaxPrivileges; 
     297          } 
     298        } 
     299      } 
     300 
     301      if (ca == null) { 
     302        // Not special 
     303        aclChars = getAclChars(ent); 
     304 
     305        if (desiredAccess == privRead) { 
     306          ca = access.checkRead(authUser, account, aclChars, maxPrivs); 
     307        } else if (desiredAccess == privWrite) { 
     308          ca = access.checkReadWrite(authUser, account, aclChars, maxPrivs); 
     309        } else { 
     310          ca = access.evaluateAccess(authUser, account, desiredAccess, aclChars, 
     311                                     maxPrivs); 
     312        } 
    262313      } 
    263314 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java

    r445 r448  
    298298    authUser.setGroups(groups.getAllGroups(authUser)); 
    299299    access.setAuthUser(authUser); 
     300    access.setSyspars((BwSystem)getSyspars().clone()); 
    300301 
    301302    events = new Events(this, access, currentMode, debug); 
     
    322323      calendars.addNewCalendars(authUser); 
    323324    } 
     325 
    324326    return userCreated; 
    325327  } 
     
    407409    checkOpen(); 
    408410    sess.update(val); 
     411    syspars = null; // Force refresh 
     412    access.setSyspars((BwSystem)getSyspars().clone()); 
    409413  } 
    410414 
  • trunk/calendar3/test/src/org/bedework/tests/access/AccessTest.java

    r320 r448  
    155155                                 Privilege[] how,char[] encoded, 
    156156                                 boolean expected, String title) throws Throwable { 
    157     CurrentAccess ca = new Acl().evaluateAccess(who, owner.getAccount(), how, encoded); 
     157    CurrentAccess ca = new Acl().evaluateAccess(who, owner.getAccount(), how, 
     158                                                encoded, null); 
    158159 
    159160    if (debug) { 
  • trunk/calendar3/webadmin/src/org/bedework/webadmin/system/UpdateSysparsAction.java

    r446 r448  
    6666 * 
    6767 * <p>Parameters are:<ul> 
     68 *      <li>updateCancelled</li> 
     69 *      <li>admingroupsClass</li> 
     70 *      <li>usergroupsClass</li> 
    6871 *      <li>defaultUserViewName</li> 
    6972 *      <li>directoryBrowsingDisallowed</li>