for (Iterator gIter = grantees.iterator(); gIter.hasNext();) {
String grantee = (String)gIter.next();
// check that role exists
RoleGrantDescriptor rdDef =
dd.getRoleDefinitionDescriptor(role);
if (rdDef == null) {
throw StandardException.
newException(SQLState.ROLE_INVALID_SPECIFICATION, role);
}
// Check that role is granted to us (or PUBLIC) with
// WITH ADMIN option so we can grant (and hence
// revoke) it. For database owner, a role definition
// always fulfills this requirement. If we implement
// granting with WITH ADMIN option later, we need to
// look for a grant to us or to PUBLIC which has WITH
// ADMIN. The role definition descriptor will not
// suffice in that case, so we need something like:
//
// rd = dd.findRoleGrantWithAdminToRoleOrPublic(grantor)
// if (rd != null) {
// :
if (grantor.equals(lcc.getDataDictionary().
getAuthorizationDatabaseOwner())) {
// All ok, we are database owner
if (SanityManager.DEBUG) {
SanityManager.ASSERT(
rdDef.getGrantee().equals(grantor),
"expected database owner in role grant descriptor");
SanityManager.ASSERT(
rdDef.isWithAdminOption(),
"expected role definition to have ADMIN OPTION");
}
} else {
throw StandardException.newException
(SQLState.AUTH_ROLE_DBO_ONLY, "REVOKE role");
}
RoleGrantDescriptor rd =
dd.getRoleGrantDescriptor(role, grantee, grantor);
if (rd != null && withAdminOption) {
// NOTE: Never called yet, withAdminOption not yet
// implemented.
if (SanityManager.DEBUG) {
SanityManager.NOTREACHED();
}
// revoke only the ADMIN OPTION from grantee
//
if (rd.isWithAdminOption()) {
// Invalidate and remove old descriptor and add a new
// one without admin option.
//
// RoleClosureIterator rci =
// dd.createRoleClosureIterator
// (activation.getTransactionController(),
// role, false);
//
// String r;
// while ((r = rci.next()) != null) {
// rdDef = dd.getRoleDefinitionDescriptor(r);
//
// dd.getDependencyManager().invalidateFor
// (rdDef, DependencyManager.REVOKE_ROLE, lcc);
// }
//
// rd.drop(lcc);
// rd.setWithAdminOption(false);
// dd.addDescriptor(rd,
// null, // parent
// DataDictionary.SYSROLES_CATALOG_NUM,
// false, // no duplicatesAllowed
// tc);
} else {
activation.addWarning
(StandardException.newWarning
(SQLState.LANG_WITH_ADMIN_OPTION_NOT_REVOKED,
role, grantee));
}
} else if (rd != null) {
// Normal revoke of role from grantee.
//
// When a role is revoked, for every role in its grantee
// closure, we call the REVOKE_ROLE action. It is used to
// invalidate dependent objects (constraints, triggers and
// views). Note that until DERBY-1632 is fixed, we risk
// dropping objects not really dependent on this role, but
// one some other role just because it inherits from this
// one. See also DropRoleConstantAction.
RoleClosureIterator rci =
dd.createRoleClosureIterator
(activation.getTransactionController(),
role, false);
String r;
while ((r = rci.next()) != null) {
rdDef = dd.getRoleDefinitionDescriptor(r);
dd.getDependencyManager().invalidateFor
(rdDef, DependencyManager.REVOKE_ROLE, lcc);
}
rd.drop(lcc);
} else {
activation.addWarning
(StandardException.newWarning
(SQLState.LANG_ROLE_NOT_REVOKED, role, grantee));