some work on the ACLs to improve their editability, creation of the ACL helper,

creation of the first conferencing permissions, and the use of those
permissions in the first conference display
This commit is contained in:
Eric J. Bowersox 2003-06-25 07:46:20 +00:00
parent 8b40695626
commit db492cf185
15 changed files with 556 additions and 123 deletions

View File

@ -586,8 +586,12 @@ INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES
(6, 'bnc.configure', '!Configure' ), (6, 'bnc.configure', '!Configure' ),
(6, 'bn.create', '!create.jpg' ), (6, 'bn.create', '!create.jpg' ),
(6, 'bnc.create', '!Create' ), (6, 'bnc.create', '!Create' ),
(6, 'bn.create.new', '!create_new.jpg' ),
(6, 'bnc.create.new', '!Create New' ),
(6, 'bn.federate', '!federate.jpg' ), (6, 'bn.federate', '!federate.jpg' ),
(6, 'bnc.federate', '!Federate' ), (6, 'bnc.federate', '!Federate' ),
(6, 'bn.find', '!find.jpg' ),
(6, 'bnc.find', '!Find' ),
(6, 'bn.i.accept', '!user_accept.jpg' ), (6, 'bn.i.accept', '!user_accept.jpg' ),
(6, 'bnc.i.accept', '!I Accept' ), (6, 'bnc.i.accept', '!I Accept' ),
(6, 'bn.i.decline', '!user_decline.jpg' ), (6, 'bn.i.decline', '!user_decline.jpg' ),
@ -596,6 +600,8 @@ INSERT INTO globalprop (nsid, prop_name, prop_value) VALUES
(6, 'bnc.login', '!Log In' ), (6, 'bnc.login', '!Log In' ),
(6, 'bn.logout', '!logout.jpg' ), (6, 'bn.logout', '!logout.jpg' ),
(6, 'bnc.logout', '!Log Out' ), (6, 'bnc.logout', '!Log Out' ),
(6, 'bn.manage', '!manage.jpg' ),
(6, 'bnc.manage', '!Manage' ),
(6, 'bn.next', '!arrow_next.jpg' ), (6, 'bn.next', '!arrow_next.jpg' ),
(6, 'bnc.next', '!Next' ), (6, 'bnc.next', '!Next' ),
(6, 'bn.no', '!no.jpg' ), (6, 'bn.no', '!no.jpg' ),
@ -937,7 +943,7 @@ UPDATE groups SET gaclid = 4 WHERE gid = 5;
# Create the ACL for the initial community. # Create the ACL for the initial community.
# (ACL 5, ACEs 9, 10, 11, 12) # (ACL 5, ACEs 9, 10, 11, 12)
INSERT INTO acl (aclid, aclname) VALUES (5, 'ACL:piazza'); INSERT INTO acl (aclid, aclname) VALUES (5, 'ACL:piazza');
INSERT INTO aclowner (aclid, ownerid, flags) VALUES (5, 5, 1); INSERT INTO aclowner (aclid, ownerid, flags) VALUES (5, 5, 1), (5, 1, 1), (5, 1, 0);
INSERT INTO ace (aceid, pri, flags) VALUES (12, 2, 16); INSERT INTO ace (aceid, pri, flags) VALUES (12, 2, 16);
INSERT INTO acldata (aclid, seq, aceid) VALUES (5, 0, 12); INSERT INTO acldata (aclid, seq, aceid) VALUES (5, 0, 12);
INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES INSERT INTO acedata (aceid, perm_nsid, perm_name) VALUES

View File

@ -30,4 +30,17 @@ comm = vlib.getCommunity(req); // get community
// Create the view. // Create the view.
rc = new VelocityView("Conference List: " + comm.name,"conf/conferences.vm"); rc = new VelocityView("Conference List: " + comm.name,"conf/conferences.vm");
rc.setParameter("community",comm); rc.setParameter("community",comm);
// Can we manage the conference list?
perm_namespace = "http://www.silverwrist.com/NS/venice/2003/06/25/conferencing.permissions";
srm = cast.querySecurityReferenceMonitor(req_help.getRequestObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,"srm"));
acl1 = comm.getAcl();
acl2 = srm.getGlobalAcl();
if (acl1.testPermission(user,perm_namespace,"manage.order") || acl2.testPermission(user,perm_namespace,"manage.order"))
rc.setParameter("can_manage",Boolean.TRUE);
// Can we create new conferences?
if (acl1.testPermission(user,perm_namespace,"create") || acl2.testPermission(user,perm_namespace,"create"))
rc.setParameter("can_create",Boolean.TRUE);
dynamo.scriptOutput(rc); dynamo.scriptOutput(rc);

View File

@ -17,7 +17,9 @@
*# *#
#* #*
Parameters: Parameters:
community = The community we're getting the conferences of. community = The community we're getting the conferences of.
can_manage = Set if we can manage the ordering of conferences.
can_create = Set if we can create new conferences.
*# *#
#header2( "Conference List:" $community.Name ) #header2( "Conference List:" $community.Name )
## TEMPORARY ## TEMPORARY
@ -25,3 +27,16 @@
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
## END TEMPORARY
<div align="left">
#set( $cid = $community.getCID() )
<a href="#formatURL( "SERVLET" "conf/TODO.js.vs?cc=${cid}" )">#button( "IMAGE" "find" )</a>
#if( $can_manage )
&nbsp;&nbsp;
<a href="#formatURL( "SERVLET" "conf/TODO.js.vs?cc=${cid}" )">#button( "IMAGE" "manage" )</a>
#end
#if( $can_create )
&nbsp;&nbsp;
<a href="#formatURL( "SERVLET" "conf/TODO.js.vs?cc=${cid}" )">#button( "IMAGE" "create.new" )</a>
#end
</div>

View File

@ -22,4 +22,7 @@ public interface ConfNamespaces
public static final String CONFERENCING_NAMESPACE = public static final String CONFERENCING_NAMESPACE =
"http://www.silverwrist.com/NS/venice/2003/06/19/conferencing"; "http://www.silverwrist.com/NS/venice/2003/06/19/conferencing";
public static final String PERMISSIONS_NAMESPACE =
"http://www.silverwrist.com/NS/venice/2003/06/25/conferencing.permissions";
} // end interface ConfNamespaces } // end interface ConfNamespaces

View File

@ -17,16 +17,29 @@
*/ */
package com.silverwrist.venice.conf.module; package com.silverwrist.venice.conf.module;
import java.security.Principal;
import java.security.acl.*;
import java.util.*; import java.util.*;
import org.apache.log4j.Logger;
import com.silverwrist.dynamo.except.*; import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*; import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
import com.silverwrist.venice.except.*; import com.silverwrist.venice.except.*;
import com.silverwrist.venice.iface.*; import com.silverwrist.venice.iface.*;
import com.silverwrist.venice.obj.*; import com.silverwrist.venice.obj.*;
import com.silverwrist.venice.util.*;
import com.silverwrist.venice.conf.ConfNamespaces;
import com.silverwrist.venice.conf.iface.UseCount; import com.silverwrist.venice.conf.iface.UseCount;
class Controller implements CommunityServiceController class Controller implements CommunityServiceController
{ {
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(Controller.class);
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Attributes * Attributes
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -34,17 +47,19 @@ class Controller implements CommunityServiceController
private DynamicImplCommunityServiceController m_dobj; private DynamicImplCommunityServiceController m_dobj;
private UseCount m_uc; private UseCount m_uc;
private String m_srm_name;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
Controller(UseCount uc) Controller(UseCount uc, String srm_name)
{ {
m_dobj = new DynamicImplCommunityServiceController(this); m_dobj = new DynamicImplCommunityServiceController(this);
m_uc = uc; m_uc = uc;
uc.incrementUseCount(); uc.incrementUseCount();
m_srm_name = srm_name;
} // end constructor } // end constructor
@ -110,12 +125,67 @@ class Controller implements CommunityServiceController
public void addServiceToCommunity(Request req, VeniceCommunity comm) public void addServiceToCommunity(Request req, VeniceCommunity comm)
throws DatabaseException, CommunityServiceException throws DatabaseException, CommunityServiceException
{ {
} if (logger.isDebugEnabled())
logger.debug("[Conferencing service] addServiceToCommunity(" + req.toString() + ", " + comm.getName() + ")");
AclEditHelper helper = new AclEditHelper(req,m_srm_name);
DynamoUser hostuser = comm.getHostUser();
DynamoGroup hostgroup = comm.getHostGroup();
try
{ // add the necessary default permissions to the community ACL
DynamoAcl acl = comm.getAcl();
helper.addPermission(hostuser,acl,hostgroup,false,ConfNamespaces.PERMISSIONS_NAMESPACE,"create");
helper.addPermission(hostuser,acl,hostgroup,false,ConfNamespaces.PERMISSIONS_NAMESPACE,"manage.order");
} // end try
catch (AclNotFoundException e)
{ // what happened to the community's ACL?
CommunityServiceException cse = new CommunityServiceException(Controller.class,"ModuleMessages","cse.noAcl",e);
cse.setParameter(0,comm.getName());
throw cse;
} // end catch
catch (NotOwnerException e)
{ // damn! we need to be the ACL owner!
CommunityServiceException cse = new CommunityServiceException(Controller.class,"ModuleMessages",
"cse.notAclOwner",e);
cse.setParameter(0,comm.getName());
throw cse;
} // end catch
} // end addServiceToCommunity
public void removeServiceFromCommunity(Request req, VeniceCommunity comm) public void removeServiceFromCommunity(Request req, VeniceCommunity comm)
throws DatabaseException, CommunityServiceException throws DatabaseException, CommunityServiceException
{ {
} if (logger.isDebugEnabled())
logger.debug("[Conferencing service] removeServiceFromCommunity(" + req.toString() + ", " + comm.getName()
+ ")");
AclEditHelper helper = new AclEditHelper(req,m_srm_name);
DynamoUser hostuser = comm.getHostUser();
try
{ // remove permissions from the community ACL
DynamoAcl acl = comm.getAcl();
helper.stripPermission(hostuser,acl,ConfNamespaces.PERMISSIONS_NAMESPACE,"create");
helper.stripPermission(hostuser,acl,ConfNamespaces.PERMISSIONS_NAMESPACE,"manage.order");
} // end try
catch (AclNotFoundException e)
{ // what happened to the community's ACL?
CommunityServiceException cse = new CommunityServiceException(Controller.class,"ModuleMessages","cse.noAcl",e);
cse.setParameter(0,comm.getName());
throw cse;
} // end catch
catch (NotOwnerException e)
{ // damn! we need to be the ACL owner!
CommunityServiceException cse = new CommunityServiceException(Controller.class,"ModuleMessages",
"cse.notAclOwner",e);
cse.setParameter(0,comm.getName());
throw cse;
} // end catch
} // end removeServiceFromCommunity
} // end class Controller } // end class Controller

View File

@ -57,6 +57,7 @@ public class ModuleMain implements ModuleFunctions, UseCount
private int m_usecount = 0; private int m_usecount = 0;
private ModuleSite m_site = null; private ModuleSite m_site = null;
private String m_srm_name = null;
private Controller m_controller = null; private Controller m_controller = null;
private ComponentShutdown m_res1; private ComponentShutdown m_res1;
private ComponentShutdown m_res2; private ComponentShutdown m_res2;
@ -93,6 +94,15 @@ public class ModuleMain implements ModuleFunctions, UseCount
} // end getInstallScript } // end getInstallScript
private synchronized final void loadSRMName(ServiceProvider sp)
{
if (m_srm_name!=null)
return;
ModuleConfigurationData conf_data = (ModuleConfigurationData)(sp.queryService(ModuleConfigurationData.class));
m_srm_name = conf_data.getValue(Namespaces.DYNAMO_OBJECT_NAMESPACE,"security");
} // end loadSRMName
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface ModuleFunctions * Implementations from interface ModuleFunctions
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -113,6 +123,7 @@ public class ModuleMain implements ModuleFunctions, UseCount
public void initialize(ModuleSite site, ServiceProvider services) throws ModuleException public void initialize(ModuleSite site, ServiceProvider services) throws ModuleException
{ {
loadSRMName(services);
m_site = site; m_site = site;
try try
@ -151,15 +162,12 @@ public class ModuleMain implements ModuleFunctions, UseCount
public boolean canInstall(ServiceProvider services, Principal installer) public boolean canInstall(ServiceProvider services, Principal installer)
{ {
loadSRMName(services);
try try
{ // get the module configuration data to get the SRM name, then use that to get the actual SRM, then get { // get the actual SRM, then get the global ACL, then test permissions
// the global ACL, then test permissions
ModuleConfigurationData conf_data =
(ModuleConfigurationData)(services.queryService(ModuleConfigurationData.class));
String srm_name = conf_data.getValue(Namespaces.DYNAMO_OBJECT_NAMESPACE,"security");
SecurityReferenceMonitor srm = SecurityReferenceMonitor srm =
(SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class, (SecurityReferenceMonitor)(GetObjectUtils.getDynamoComponent(services,SecurityReferenceMonitor.class,
srm_name)); m_srm_name));
DynamoAcl gacl = srm.getGlobalAcl(); DynamoAcl gacl = srm.getGlobalAcl();
return gacl.testPermission((DynamoUser)installer,VeniceNamespaces.SYSTEM_PERMS_NAMESPACE,"edit.menus"); return gacl.testPermission((DynamoUser)installer,VeniceNamespaces.SYSTEM_PERMS_NAMESPACE,"edit.menus");
@ -175,10 +183,11 @@ public class ModuleMain implements ModuleFunctions, UseCount
public void install(ModuleSite site, ServiceProvider services, Principal installer, DynamoLog log) public void install(ModuleSite site, ServiceProvider services, Principal installer, DynamoLog log)
throws ModuleException throws ModuleException
{ {
loadSRMName(services);
synchronized (this) synchronized (this)
{ // create Controller object if necessary { // create Controller object if necessary
if (m_controller==null) if (m_controller==null)
m_controller = new Controller(this); m_controller = new Controller(this,m_srm_name);
} // end synchronized block } // end synchronized block
@ -236,6 +245,7 @@ public class ModuleMain implements ModuleFunctions, UseCount
public void uninstall(ModuleSite site, ServiceProvider services, Principal uninstaller, DynamoLog log) public void uninstall(ModuleSite site, ServiceProvider services, Principal uninstaller, DynamoLog log)
throws ModuleException throws ModuleException
{ {
loadSRMName(services);
try try
{ // uninstall the community service { // uninstall the community service
CommunityServiceInstall csi = (CommunityServiceInstall)(services.queryService(CommunityServiceInstall.class)); CommunityServiceInstall csi = (CommunityServiceInstall)(services.queryService(CommunityServiceInstall.class));
@ -290,7 +300,7 @@ public class ModuleMain implements ModuleFunctions, UseCount
synchronized (this) synchronized (this)
{ // create it if necessary { // create it if necessary
if (m_controller==null) if (m_controller==null)
m_controller = new Controller(this); m_controller = new Controller(this,m_srm_name);
return m_controller; return m_controller;
} // end synchronized block } // end synchronized block

View File

@ -22,3 +22,5 @@ uninstall.service.fail=Failed to uninstall community service object: {0}
install.cmenu.fail=Failed to install community menu items: {0} install.cmenu.fail=Failed to install community menu items: {0}
uninstall.cmenu.fail=Failed to uninstall community menu items: {0} uninstall.cmenu.fail=Failed to uninstall community menu items: {0}
no.db.script=Unable to find the database initialization script "{0}." no.db.script=Unable to find the database initialization script "{0}."
cse.notAclOwner=Internal error: host of community "{0}" must be an owner of its ACL.
cse.noAcl=Internal error: ACL not found for community "{0}."

View File

@ -11,16 +11,27 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
package com.silverwrist.dynamo.iface; package com.silverwrist.dynamo.iface;
import java.security.acl.AclEntry; import java.security.acl.AclEntry;
import com.silverwrist.dynamo.except.DatabaseException;
public interface DynamoAce extends AclEntry public interface DynamoAce extends AclEntry
{ {
public int getAceID(); public int getAceID();
public boolean isGroupAce();
public int getNumPermissions();
public boolean addPermission(String namespace, String name) throws DatabaseException;
public boolean removePermission(String namespace, String name) throws DatabaseException;
public boolean checkPermission(String namespace, String name) throws DatabaseException;
} // end interface DynamoAce } // end interface DynamoAce

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -31,6 +31,11 @@ public interface DynamoAcl extends Acl, NamedObject
public DynamoAce getAce(Principal caller, int index) throws DatabaseException, NotOwnerException; public DynamoAce getAce(Principal caller, int index) throws DatabaseException, NotOwnerException;
public DynamoAce getMatchingAce(Principal caller, Principal target, boolean negative)
throws DatabaseException, NotOwnerException;
public int getIndexOfAce(Principal caller, DynamoAce ace) throws DatabaseException, NotOwnerException;
public boolean insertEntry(Principal caller, AclEntry entry, int at_index) public boolean insertEntry(Principal caller, AclEntry entry, int at_index)
throws DatabaseException, NotOwnerException; throws DatabaseException, NotOwnerException;

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -309,6 +309,49 @@ class AceObject implements DynamoAce
} // end getAceID } // end getAceID
public boolean isGroupAce()
{
return m_pr.isGroup();
} // end isGroupAce
public int getNumPermissions()
{
return m_perms.size();
} // end getNumPermissions
public synchronized boolean addPermission(String namespace, String name) throws DatabaseException
{
PropertyKey pkey = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
PermObject pobj = new PermObject(pkey,m_ns_cache);
if (m_perms.contains(pobj))
return false;
m_ops.addPermission(m_aceid,pkey);
m_perms.add(pobj);
return true;
} // end addPermission
public synchronized boolean removePermission(String namespace, String name) throws DatabaseException
{
PropertyKey pkey = new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name);
PermObject pobj = new PermObject(pkey,m_ns_cache);
if (!(m_perms.contains(pobj)))
return false;
m_ops.removePermission(m_aceid,pkey);
m_perms.remove(pobj);
return true;
} // end removePermission
public synchronized boolean checkPermission(String namespace, String name) throws DatabaseException
{
PermObject pobj = new PermObject(new PropertyKey(m_ns_cache.namespaceNameToId(namespace),name),m_ns_cache);
return m_perms.contains(pobj);
} // end checkPermission
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External operations * External operations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -327,6 +327,22 @@ class AclObject implements DynamoAcl
} // end getAce } // end getAce
public DynamoAce getMatchingAce(Principal caller, Principal target, boolean negative)
throws DatabaseException, NotOwnerException
{
int aid = m_ops.getMatchingAceID(m_aclid,new PrincipalID(caller),new PrincipalID(target),negative);
if (aid<0)
return null;
return m_ace_cache.getAce(aid);
} // end getMatchingAce
public int getIndexOfAce(Principal caller, DynamoAce ace) throws DatabaseException, NotOwnerException
{
return m_ops.getIndexOfAceIDInAcl(m_aclid,new PrincipalID(caller),ace.getAceID());
} // end getIndexOfAce
public boolean insertEntry(Principal caller, AclEntry entry, int at_index) public boolean insertEntry(Principal caller, AclEntry entry, int at_index)
throws DatabaseException, NotOwnerException throws DatabaseException, NotOwnerException
{ {

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -69,6 +69,12 @@ abstract class AclOperations extends OpsBase
abstract int getAceID(int aclid, PrincipalID caller, int index) throws DatabaseException, NotOwnerException; abstract int getAceID(int aclid, PrincipalID caller, int index) throws DatabaseException, NotOwnerException;
abstract int getMatchingAceID(int aclid, PrincipalID caller, PrincipalID target, boolean negative)
throws DatabaseException, NotOwnerException;
abstract int getIndexOfAceIDInAcl(int aclid, PrincipalID caller, int aceid)
throws DatabaseException, NotOwnerException;
abstract boolean insertAce(int aclid, PrincipalID caller, int aceid, int at_index) abstract boolean insertAce(int aclid, PrincipalID caller, int aceid, int at_index)
throws DatabaseException, NotOwnerException; throws DatabaseException, NotOwnerException;

View File

@ -75,6 +75,42 @@ class AclOperations_mysql extends AclOperations
} // end constructor } // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private static final boolean testOwner(Connection conn, int aclid, PrincipalID owner) throws SQLException
{
PreparedStatement stmt = null;
ResultSet rs = null;
try
{ // prepare the statement
stmt = conn.prepareStatement(OWNER_TEST_STMT);
stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID());
stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
return rs.next();
} // end try
finally
{ // shut down things
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
} // end finally
} // end testOwner
private static final void ensureOwner(Connection conn, int aclid, PrincipalID owner)
throws SQLException, NotOwnerException
{
if (!testOwner(conn,aclid,owner))
throw new NotOwnerException();
} // end ensureOwner
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Abstract implementations from class AclOperations * Abstract implementations from class AclOperations
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -83,19 +119,10 @@ class AclOperations_mysql extends AclOperations
boolean testOwner(int aclid, PrincipalID owner) throws DatabaseException boolean testOwner(int aclid, PrincipalID owner) throws DatabaseException
{ {
Connection conn = null; Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try try
{ // get a connection { // get a connection
conn = getConnection(); conn = getConnection();
return testOwner(conn,aclid,owner);
// create the appropriate SQL statement
stmt = conn.prepareStatement(OWNER_TEST_STMT);
stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID());
stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
return rs.next();
} // end try } // end try
catch (SQLException e) catch (SQLException e)
@ -105,8 +132,6 @@ class AclOperations_mysql extends AclOperations
} // end catch } // end catch
finally finally
{ // shut everything down { // shut everything down
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(conn); SQLUtils.shutdown(conn);
} // end finally } // end finally
@ -141,15 +166,15 @@ class AclOperations_mysql extends AclOperations
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID()); stmt.setInt(2,owner.getID());
stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER)); stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
SQLUtils.shutdown(rs); rs.close();
rs = stmt.executeQuery(); rs = stmt.executeQuery();
if (rs.next()) if (rs.next())
return false; // owner already present return false; // owner already present
// insert the new owner record // insert the new owner record
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("INSERT INTO aclowner (aclid, ownerid, flags) VALUES (?, ?, ?);"); stmt = conn.prepareStatement("INSERT INTO aclowner (aclid, ownerid, flags) VALUES (?, ?, ?);");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID()); stmt.setInt(2,owner.getID());
@ -203,15 +228,15 @@ class AclOperations_mysql extends AclOperations
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID()); stmt.setInt(2,owner.getID());
stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER)); stmt.setInt(3,(owner.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
SQLUtils.shutdown(rs); rs.close();
rs = stmt.executeQuery(); rs = stmt.executeQuery();
if (!(rs.next())) if (!(rs.next()))
return false; // owner not present return false; // owner not present
// is the owner we're about to remove the last one? // is the owner we're about to remove the last one?
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("SELECT COUNT(*) FROM aclowner WHERE aclid = ?;"); stmt = conn.prepareStatement("SELECT COUNT(*) FROM aclowner WHERE aclid = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
rs = stmt.executeQuery(); rs = stmt.executeQuery();
@ -219,9 +244,9 @@ class AclOperations_mysql extends AclOperations
throw new LastOwnerException(); throw new LastOwnerException();
// OK, go ahead and delete it. // OK, go ahead and delete it.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("DELETE FROM aclowner WHERE aclid = ? AND ownerid = ? AND flags = ?;"); stmt = conn.prepareStatement("DELETE FROM aclowner WHERE aclid = ? AND ownerid = ? AND flags = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,owner.getID()); stmt.setInt(2,owner.getID());
@ -252,7 +277,6 @@ class AclOperations_mysql extends AclOperations
Connection conn = null; Connection conn = null;
PreparedStatement stmt = null; PreparedStatement stmt = null;
Statement stmt2 = null; Statement stmt2 = null;
ResultSet rs = null;
try try
{ // get a connection { // get a connection
conn = getConnection(); conn = getConnection();
@ -262,24 +286,14 @@ class AclOperations_mysql extends AclOperations
stmt2.executeUpdate("LOCK TABLES acl WRITE, aclowner READ;"); stmt2.executeUpdate("LOCK TABLES acl WRITE, aclowner READ;");
// test to see if we own the thing first // test to see if we own the thing first
stmt = conn.prepareStatement(OWNER_TEST_STMT); ensureOwner(conn,aclid,caller);
stmt.setInt(1,aclid);
stmt.setInt(2,caller.getID());
stmt.setInt(3,(caller.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
if (!(rs.next()))
throw new NotOwnerException();
// poke in the new name // poke in the new name
SQLUtils.shutdown(rs);
rs = null;
SQLUtils.shutdown(stmt);
stmt = conn.prepareStatement("UPDATE acl SET aclname = ? WHERE aclid = ?;"); stmt = conn.prepareStatement("UPDATE acl SET aclname = ? WHERE aclid = ?;");
stmt.setString(1,name); stmt.setString(1,name);
stmt.setInt(2,aclid); stmt.setInt(2,aclid);
stmt.executeUpdate(); stmt.executeUpdate();
} // end try } // end try
catch (SQLException e) catch (SQLException e)
{ // translate to a general DatabaseException { // translate to a general DatabaseException
@ -289,7 +303,6 @@ class AclOperations_mysql extends AclOperations
finally finally
{ // shut everything down { // shut everything down
MySQLUtils.unlockTables(conn); MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt); SQLUtils.shutdown(stmt);
SQLUtils.shutdown(stmt2); SQLUtils.shutdown(stmt2);
SQLUtils.shutdown(conn); SQLUtils.shutdown(conn);
@ -344,18 +357,9 @@ class AclOperations_mysql extends AclOperations
stmt2.executeUpdate("LOCK TABLES acldata READ, aclowner READ;"); stmt2.executeUpdate("LOCK TABLES acldata READ, aclowner READ;");
// test to see if we own the thing first // test to see if we own the thing first
stmt = conn.prepareStatement(OWNER_TEST_STMT); ensureOwner(conn,aclid,caller);
stmt.setInt(1,aclid);
stmt.setInt(2,caller.getID());
stmt.setInt(3,(caller.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
if (!(rs.next()))
throw new NotOwnerException();
// now query the ACL data to find the ACE ID // now query the ACL data to find the ACE ID
SQLUtils.shutdown(rs);
rs = null;
SQLUtils.shutdown(stmt);
stmt = conn.prepareStatement("SELECT aceid FROM acldata WHERE aclid = ? AND seq = ?;"); stmt = conn.prepareStatement("SELECT aceid FROM acldata WHERE aclid = ? AND seq = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,index); stmt.setInt(2,index);
@ -382,6 +386,100 @@ class AclOperations_mysql extends AclOperations
} // end getAceId } // end getAceId
int getMatchingAceID(int aclid, PrincipalID caller, PrincipalID target, boolean negative)
throws DatabaseException, NotOwnerException
{
Connection conn = null;
PreparedStatement stmt = null;
Statement stmt2 = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// lock the tables we need
stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES acldata READ, ace READ, aclowner READ;");
// test to see if we own the thing first
ensureOwner(conn,aclid,caller);
// prepare and execute the query statement
stmt = conn.prepareStatement("SELECT f.aceid FROM acldata f, ace a WHERE f.aceid = a.aceid AND f.aclid = ? "
+ "AND a.pri = ? AND a.flags = ? ORDER BY f.seq;");
stmt.setInt(1,aclid);
stmt.setInt(2,target.getID());
stmt.setInt(3,(target.isGroup() ? PRINCIPALFLAG_GROUP : PRINCIPALFLAG_USER)
| (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE));
rs = stmt.executeQuery();
if (rs.next())
return rs.getInt(1);
else
return -1;
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(stmt2);
SQLUtils.shutdown(conn);
} // end finally
} // end getMatchingAceID
int getIndexOfAceIDInAcl(int aclid, PrincipalID caller, int aceid) throws DatabaseException, NotOwnerException
{
Connection conn = null;
PreparedStatement stmt = null;
Statement stmt2 = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// lock the tables we need
stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES acldata READ, aclowner READ;");
// test to see if we own the thing first
ensureOwner(conn,aclid,caller);
// create and execute the statement
stmt = conn.prepareStatement("SELECT seq FROM acldata WHERE aclid = ? AND aceid = ?;");
stmt.setInt(1,aclid);
stmt.setInt(2,aceid);
rs = stmt.executeQuery();
if (rs.next())
return rs.getInt(1);
else
return -1;
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(stmt2);
SQLUtils.shutdown(conn);
} // end finally
} // end getIndexOfAceIDInAcl
boolean insertAce(int aclid, PrincipalID caller, int aceid, int at_index) boolean insertAce(int aclid, PrincipalID caller, int aceid, int at_index)
throws DatabaseException, NotOwnerException throws DatabaseException, NotOwnerException
{ {
@ -398,20 +496,11 @@ class AclOperations_mysql extends AclOperations
stmt2.executeUpdate("LOCK TABLES acldata WRITE, aclowner READ, ace READ;"); stmt2.executeUpdate("LOCK TABLES acldata WRITE, aclowner READ, ace READ;");
// test to see if we own the thing first // test to see if we own the thing first
stmt = conn.prepareStatement(OWNER_TEST_STMT); ensureOwner(conn,aclid,caller);
stmt.setInt(1,aclid);
stmt.setInt(2,caller.getID());
stmt.setInt(3,(caller.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
if (!(rs.next()))
throw new NotOwnerException();
// An ACL can contain at most one positive and one negative ACE for each unique Principal. // An ACL can contain at most one positive and one negative ACE for each unique Principal.
// This translates out to a unique combination of principal ID and flags for each ACE. So // This translates out to a unique combination of principal ID and flags for each ACE. So
// get the principal ID and flags from our specified ACE to test against the current ACL contents. // get the principal ID and flags from our specified ACE to test against the current ACL contents.
SQLUtils.shutdown(rs);
rs = null;
SQLUtils.shutdown(stmt);
stmt = conn.prepareStatement("SELECT pri, flags FROM ace WHERE aceid = ?;"); stmt = conn.prepareStatement("SELECT pri, flags FROM ace WHERE aceid = ?;");
stmt.setInt(1,aceid); stmt.setInt(1,aceid);
rs = stmt.executeQuery(); rs = stmt.executeQuery();
@ -428,9 +517,9 @@ class AclOperations_mysql extends AclOperations
int ace_flags = rs.getInt(2); int ace_flags = rs.getInt(2);
// Now conduct a query to look for another ACE with that same combination already in our ACL. // Now conduct a query to look for another ACE with that same combination already in our ACL.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("SELECT ace.aceid FROM ace, acldata WHERE ace.pri = ? AND ace.flags = ? " stmt = conn.prepareStatement("SELECT ace.aceid FROM ace, acldata WHERE ace.pri = ? AND ace.flags = ? "
+ "AND ace.aceid = acldata.aceid AND acldata.aclid = ?;"); + "AND ace.aceid = acldata.aceid AND acldata.aclid = ?;");
stmt.setInt(1,ace_pri); stmt.setInt(1,ace_pri);
@ -441,9 +530,9 @@ class AclOperations_mysql extends AclOperations
return false; return false;
// Figure out the new sequence number for this ACE. // Figure out the new sequence number for this ACE.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("SELECT MAX(seq) FROM acldata WHERE aclid = ?;"); stmt = conn.prepareStatement("SELECT MAX(seq) FROM acldata WHERE aclid = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
rs = stmt.executeQuery(); rs = stmt.executeQuery();
@ -458,9 +547,9 @@ class AclOperations_mysql extends AclOperations
if (renumber) if (renumber)
{ // Renumber the other ACEs to provide room. { // Renumber the other ACEs to provide room.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("UPDATE acldata SET seq = seq + 1 WHERE seq >= ?;"); stmt = conn.prepareStatement("UPDATE acldata SET seq = seq + 1 WHERE seq >= ?;");
stmt.setInt(1,at_index); stmt.setInt(1,at_index);
stmt.executeUpdate(); stmt.executeUpdate();
@ -468,9 +557,9 @@ class AclOperations_mysql extends AclOperations
} // end if } // end if
// Now add the new record to the ACL data table. // Now add the new record to the ACL data table.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("INSERT INTO acldata (aclid, seq, aceid) VALUES (?, ?, ?);"); stmt = conn.prepareStatement("INSERT INTO acldata (aclid, seq, aceid) VALUES (?, ?, ?);");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,at_index); stmt.setInt(2,at_index);
@ -511,18 +600,9 @@ class AclOperations_mysql extends AclOperations
stmt2.executeUpdate("LOCK TABLES acldata WRITE, aclowner READ;"); stmt2.executeUpdate("LOCK TABLES acldata WRITE, aclowner READ;");
// test to see if we own the thing first // test to see if we own the thing first
stmt = conn.prepareStatement(OWNER_TEST_STMT); ensureOwner(conn,aclid,caller);
stmt.setInt(1,aclid);
stmt.setInt(2,caller.getID());
stmt.setInt(3,(caller.isGroup() ? OWNERFLAG_GROUP : OWNERFLAG_USER));
rs = stmt.executeQuery();
if (!(rs.next()))
throw new NotOwnerException();
// Look for the ACE ID in the list, and get the old sequence number. // Look for the ACE ID in the list, and get the old sequence number.
SQLUtils.shutdown(rs);
rs = null;
SQLUtils.shutdown(stmt);
stmt = conn.prepareStatement("SELECT seq FROM acldata WHERE aclid = ? AND aceid = ?;"); stmt = conn.prepareStatement("SELECT seq FROM acldata WHERE aclid = ? AND aceid = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,aceid); stmt.setInt(2,aceid);
@ -532,16 +612,16 @@ class AclOperations_mysql extends AclOperations
int old_seq = rs.getInt(1); int old_seq = rs.getInt(1);
// Remove this entry from the table. // Remove this entry from the table.
SQLUtils.shutdown(rs); rs.close();
rs = null; rs = null;
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("DELETE FROM acldata WHERE aclid = ? AND seq = ?;"); stmt = conn.prepareStatement("DELETE FROM acldata WHERE aclid = ? AND seq = ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,old_seq); stmt.setInt(2,old_seq);
stmt.executeUpdate(); stmt.executeUpdate();
// Now renumber all the entries after the one we just updated. // Now renumber all the entries after the one we just updated.
SQLUtils.shutdown(stmt); stmt.close();
stmt = conn.prepareStatement("UPDATE acldata SET seq = seq - 1 WHERE aclid = ? AND seq > ?;"); stmt = conn.prepareStatement("UPDATE acldata SET seq = seq - 1 WHERE aclid = ? AND seq > ?;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,old_seq); stmt.setInt(2,old_seq);
@ -576,12 +656,9 @@ class AclOperations_mysql extends AclOperations
conn = getConnection(); conn = getConnection();
// and here's the query... // and here's the query...
stmt = conn.prepareStatement("SELECT acedata.perm_nsid, acedata.perm_name " stmt = conn.prepareStatement("SELECT d.perm_nsid, d.perm_name FROM acedata d, ace a, acldata f, groupmembers m "
+ "FROM acedata, ace, acldata, groupmembers " + "WHERE d.aceid = a.aceid AND a.aceid = f.aceid AND f.aclid = ? AND a.flags = ? "
+ "WHERE acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "AND a.pri = m.gid AND m.uid = ? ORDER BY f.seq;");
+ "AND acldata.aclid = ? AND ace.flags = ? "
+ "AND ace.pri = groupmembers.gid AND groupmembers.uid = ? "
+ "ORDER BY acldata.seq;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,PRINCIPALFLAG_GROUP | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE)); stmt.setInt(2,PRINCIPALFLAG_GROUP | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE));
stmt.setInt(3,uid); stmt.setInt(3,uid);
@ -619,10 +696,9 @@ class AclOperations_mysql extends AclOperations
conn = getConnection(); conn = getConnection();
// and here's the query... // and here's the query...
stmt = conn.prepareStatement("SELECT acedata.perm_nsid, acedata.perm_name FROM acedata, ace, acldata " stmt = conn.prepareStatement("SELECT d.perm_nsid, d.perm_name FROM acedata d, ace a, acldata f "
+ "WHERE acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "WHERE d.aceid = a.aceid AND a.aceid = f.aceid AND f.aclid = ? AND a.flags = ? "
+ "AND acldata.aclid = ? AND ace.flags = ? AND ace.pri = ? " + "AND a.pri = ? ORDER BY f.seq;");
+ "ORDER BY acldata.seq;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,PRINCIPALFLAG_GROUP | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE)); stmt.setInt(2,PRINCIPALFLAG_GROUP | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE));
stmt.setInt(3,gid); stmt.setInt(3,gid);
@ -660,10 +736,9 @@ class AclOperations_mysql extends AclOperations
conn = getConnection(); conn = getConnection();
// and here's the query... // and here's the query...
stmt = conn.prepareStatement("SELECT acedata.perm_nsid, acedata.perm_name FROM acedata, ace, acldata " stmt = conn.prepareStatement("SELECT d.perm_nsid, d.perm_name FROM acedata d, ace a, acldata f "
+ "WHERE acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "WHERE d.aceid = a.aceid AND a.aceid = f.aceid AND f.aclid = ? AND a.flags = ? "
+ "AND acldata.aclid = ? AND ace.flags = ? AND ace.pri = ? " + "AND a.pri = ? ORDER BY f.seq;");
+ "ORDER BY acldata.seq;");
stmt.setInt(1,aclid); stmt.setInt(1,aclid);
stmt.setInt(2,PRINCIPALFLAG_USER | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE)); stmt.setInt(2,PRINCIPALFLAG_USER | (negative ? ACEFLAG_NEGATIVE : ACEFLAG_POSITIVE));
stmt.setInt(3,uid); stmt.setInt(3,uid);
@ -705,11 +780,10 @@ class AclOperations_mysql extends AclOperations
int table_index = 0; int table_index = 0;
// test for positive and negative user values first // test for positive and negative user values first
stmt = conn.prepareStatement("SELECT DISTINCT ace.aceid, ace.flags FROM acedata, ace, acldata, groupmembers " stmt = conn.prepareStatement("SELECT DISTINCT a.aceid, a.flags FROM acedata d, ace a, acldata f "
+ "WHERE acedata.perm_nsid = ? AND acedata.perm_name = ? " + "WHERE d.perm_nsid = ? AND d.perm_name = ? AND d.aceid = a.aceid "
+ "AND acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "AND a.aceid = f.aceid AND f.aclid = ? AND (a.flags = 0 OR a.flags = 16) "
+ "AND acldata.aclid = ? AND (ace.flags = 0 OR ace.flags = 16) " + "AND a.pri = ?;");
+ "AND ace.pri = ?;");
stmt.setInt(1,perm.getNamespaceID()); stmt.setInt(1,perm.getNamespaceID());
stmt.setString(2,perm.getName()); stmt.setString(2,perm.getName());
stmt.setInt(3,aclid); stmt.setInt(3,aclid);
@ -743,11 +817,10 @@ class AclOperations_mysql extends AclOperations
rs.close(); rs.close();
rs = null; rs = null;
stmt.close(); stmt.close();
stmt = conn.prepareStatement("SELECT DISTINCT ace.aceid, ace.flags FROM acedata, ace, acldata, groupmembers " stmt = conn.prepareStatement("SELECT DISTINCT a.aceid, a.flags FROM acedata d, ace a, acldata f, groupmembers m "
+ "WHERE acedata.perm_nsid = ? AND acedata.perm_name = ? " + "WHERE d.perm_nsid = ? AND d.perm_name = ? AND d.aceid = a.aceid "
+ "AND acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "AND a.aceid = f.aceid AND d.aclid = ? AND (a.flags = 1 OR a.flags = 17) "
+ "AND acldata.aclid = ? AND (ace.flags = 1 OR ace.flags = 17) " + "AND a.pri = m.gid AND m.uid = ?;");
+ "AND ace.pri = groupmembers.gid AND groupmembers.uid = ?;");
stmt.setInt(1,perm.getNamespaceID()); stmt.setInt(1,perm.getNamespaceID());
stmt.setString(2,perm.getName()); stmt.setString(2,perm.getName());
stmt.setInt(3,aclid); stmt.setInt(3,aclid);
@ -811,11 +884,10 @@ class AclOperations_mysql extends AclOperations
boolean negative = false; boolean negative = false;
// test for positive and negative values simultaneously // test for positive and negative values simultaneously
stmt = conn.prepareStatement("SELECT DISTINCT acedata.aceid, acedata.aceflags FROM acedata, ace, acldata, " stmt = conn.prepareStatement("SELECT DISTINCT d.aceid, d.aceflags FROM acedata d, ace a, acldata f, "
+ "groupmembers WHERE acedata.perm_nsid = ? AND acedata.perm_name = ? " + "groupmembers m WHERE d.perm_nsid = ? AND d.perm_name = ? AND d.aceid = a.aceid "
+ "AND acedata.aceid = ace.aceid AND ace.aceid = acldata.aceid " + "AND a.aceid = f.aceid AND f.aclid = ? AND (a.flags = 1 OR a.flags = 17) "
+ "AND acldata.aclid = ? AND (ace.flags = 1 OR ace.flags = 17) " + "AND a.pri = ?;");
+ "AND ace.pri = ?;");
stmt.setInt(1,perm.getNamespaceID()); stmt.setInt(1,perm.getNamespaceID());
stmt.setString(2,perm.getName()); stmt.setString(2,perm.getName());
stmt.setInt(3,aclid); stmt.setInt(3,aclid);

View File

@ -11,7 +11,7 @@
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
*/ */
@ -282,6 +282,7 @@ public class SRMObject implements NamedObject, ComponentInitialize, ComponentShu
} // end catch } // end catch
// Register the property serializer.
PropertySerializerRegistration pszreg = PropertySerializerRegistration pszreg =
(PropertySerializerRegistration)(services.queryService(PropertySerializerRegistration.class)); (PropertySerializerRegistration)(services.queryService(PropertySerializerRegistration.class));
m_shut_psz = pszreg.registerPropertySerializer(new AclSerialize()); m_shut_psz = pszreg.registerPropertySerializer(new AclSerialize());

View File

@ -0,0 +1,160 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.util;
import java.security.Principal;
import java.security.acl.*;
import java.util.*;
import org.apache.log4j.Logger;
import com.silverwrist.dynamo.Namespaces;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.security.SecurityReferenceMonitor;
public class AclEditHelper
{
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private SecurityReferenceMonitor m_srm;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public AclEditHelper(ServiceProvider services, String srm_name)
{
ObjectProvider op = (ObjectProvider)(services.queryService(ObjectProvider.class));
Object tmp = op.getObject(Namespaces.DYNAMO_OBJECT_NAMESPACE,srm_name);
if (tmp instanceof SecurityReferenceMonitor)
m_srm = (SecurityReferenceMonitor)tmp;
else if (tmp instanceof ServiceProvider)
m_srm = (SecurityReferenceMonitor)(((ServiceProvider)tmp).queryService(SecurityReferenceMonitor.class));
} // end AclEditHelper
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public SecurityReferenceMonitor getSRM()
{
return m_srm;
} // end getSRM
public void insertAce(DynamoUser caller, DynamoAcl acl, DynamoAce ace) throws DatabaseException, NotOwnerException
{
// Locate the place to insert this ACE into the ACL.
int acecount = acl.getAceCount();
int ipoint = 0;
if (ace.isNegative())
{ // negative ACEs get inserted before positive ACEs
if (ace.isGroupAce())
{ // skip all user ACEs, insert before group ACEs (or before positive ACEs)
DynamoAce tmp = acl.getAce(caller,ipoint);
while ((ipoint<acecount) && tmp.isNegative() && !(tmp.isGroupAce()))
tmp = acl.getAce(caller,++ipoint);
} // end if
// else this ACE gets inserted at the front anyway
} // end if
else
{ // a positive ACE - skip over the negative ACEs and insert
DynamoAce tmp = acl.getAce(caller,ipoint);
while ((ipoint<acecount) && (tmp.isNegative()))
tmp = acl.getAce(caller,++ipoint);
if ((ipoint<acecount) && ace.isGroupAce())
{ // skip all user ACEs, insert before group ACEs
while ((ipoint<acecount) && !(tmp.isGroupAce()))
tmp = acl.getAce(caller,++ipoint);
} // end if
// else it's a positive user ACE - we're there
} // end else
// Perform the insert!
acl.insertEntry(caller,ace,ipoint);
} // end insertAce
public void addPermission(DynamoUser caller, DynamoAcl acl, Principal subject, boolean negative, String namespace,
String name) throws DatabaseException, NotOwnerException
{
DynamoAce ace = acl.getMatchingAce(caller,subject,negative);
if (ace==null)
{ // Create a new ACE.
ace = m_srm.createAce();
ace.setPrincipal(subject);
if (negative)
ace.setNegativePermissions();
// insert the ACE into the ACL
this.insertAce(caller,acl,ace);
} // end if
// Now add the permission to the ACE.
ace.addPermission(namespace,name);
} // end addPermission
public void removePermission(DynamoUser caller, DynamoAcl acl, Principal subject, boolean negative, String namespace,
String name) throws DatabaseException, NotOwnerException
{
DynamoAce ace = acl.getMatchingAce(caller,subject,negative);
if (ace!=null)
{ // remove the permission
ace.removePermission(namespace,name);
if (ace.getNumPermissions()==0)
acl.removeEntry(caller,ace); // ACE is now empty - remove it
} // end if
} // end removePermission
public void stripPermission(DynamoUser caller, DynamoAcl acl, String namespace, String name)
throws DatabaseException, NotOwnerException
{
int acecount = acl.getAceCount();
LinkedList null_aces = new LinkedList();
for (int i=0; i<acecount; i++)
{ // remove permission from each ACE in the ACL
DynamoAce ace = acl.getAce(caller,i);
ace.removePermission(namespace,name);
if (ace.getNumPermissions()==0)
null_aces.addLast(ace);
} // end for
while (null_aces.size()>0)
{ // zap the ACEs that are now empty
DynamoAce ace = (DynamoAce)(null_aces.removeFirst());
acl.removeEntry(caller,ace);
} // end while
} // end stripPermission
} // end class AclEditHelper