db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dag H. Wanvik" <Dag.Wan...@Sun.COM>
Subject How to invalidate when a role is revoked, so privileges will be rechecked?
Date Mon, 17 Dec 2007 17:03:30 GMT

Working on SQL roles, I have encountered a problem related to
invalidation of prepared statements. 

My understanding at this point: Presently, at execute time, permission
is only checked the first time a prepared statement is executed for a
connection, as part of creating a result set object structure which is
subsequently reused (BaseActivation#resultSet).

When permissions are revoked, invalidation is signaled from
GrantRevokeConstantAction (see TablePrivilegeInfo and
RoutinePrivilegeInfo respectively) via the dependency the prepared
statement has on the *SQL object* (e.g. table) for which premission is
revoked, cf. DERBY-2594, via the action USER_RECOMPILE_REQUEST
(*not* via dependency on the permission descriptor itself). 

This causes the prepare statement to be recompiled, and hence also a
new permissions check (the call to authorize happen as part of
fillResultSet which is conditional, c.f code generation in
StatementNode#generate which generates call to fillResultSet which in
turn calls authorize (see CursorNode#generate which calls
generateAuthorizeCheck to accomplish this). Earlier, permissions
checking happened every time a prepared statement was executed, but
this was changed with the work to reuse result sets, cf. DERBY-827.

Now, with the introduction of roles, when checking permissions at
execute time, an activation can come to rely on a privilege obtained
indirectly via a role grant to the user of the current session. But
when this role is revoked from the user, execution of the (prepared)
statement should (possibly) no longer be allowed. (Note: there is no
revoke of a privilege here, since the grant of the privilege is to the
role, so the current mechanism to force recompilation is

To accomplish the required behavior, the authorize check needs to be
executed anew, possibly leading to an error if no other applicable
privilege can be found to satisfy the query in question.

I can imagine the following ways of making this happen:

a) going back to checking permissions for every execution
   Any revoked role grant would then be effective immediately.

b) as part of authorize() (e.g. in
   StatementTablePermission#hasPermissionOnTable), introduce a
   dependency for the activation on a role grant descriptor (that is,
   if indeed a role is required to satisfy the required privilege),
   causing the dropping of that descriptor to invalidate any dependent
   activation, so a new permission check can take place when the
   statement is executed next time.

c) as part of authorize() introduce a dependency on the Prepared
   statement on the role grant descriptor, causing the dropping of
   that descriptor to invalidate any dependent prepared statement.

Currently, a prepared statement can be a Dependent, but not the
activation as far as i can see. I tried c) and it seems to work (but
is it safe to register a dependency at execute time for a prepared
statement?). This is essentially extending the present solution.  It
seems a bit heavy, though, to have to recompile, when all that is
needed is a new check in the current connection? Maybe there is a
reason why we cannot make an activation a Dependent?

I would also like to avoid a) for performance reasons, so b) seems to
have the correct granularity. Comments?


View raw message