db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dyre.Tjeldv...@Sun.COM
Subject Re: How to invalidate when a role is revoked, so privileges will be rechecked?
Date Wed, 19 Dec 2007 17:29:44 GMT
"Dag H. Wanvik" <Dag.Wanvik@Sun.COM> writes:

> 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
> unsufficient).
>
> 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?

I agree that b) seems reasonable. However, based on my experience from
DERBY-827 and DERBY-2594, I think you really need to engage Dan on
this. 

At least, I would never have come up with the idea of using a
dependency to invalidate prepared statements by simply looking at the
code. Before Dan pointed out how it was supposed to work I was more
inclined to perform the check on every execute as that seemed to be more
in line with the old behavior.

-- 
dt

Mime
View raw message