Return-Path: Delivered-To: apmail-db-derby-dev-archive@www.apache.org Received: (qmail 76064 invoked from network); 19 Dec 2007 17:30:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 19 Dec 2007 17:30:18 -0000 Received: (qmail 94437 invoked by uid 500); 19 Dec 2007 17:30:07 -0000 Delivered-To: apmail-db-derby-dev-archive@db.apache.org Received: (qmail 94399 invoked by uid 500); 19 Dec 2007 17:30:07 -0000 Mailing-List: contact derby-dev-help@db.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: Delivered-To: mailing list derby-dev@db.apache.org Received: (qmail 94390 invoked by uid 99); 19 Dec 2007 17:30:07 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Dec 2007 09:30:07 -0800 X-ASF-Spam-Status: No, hits=-1.0 required=10.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Received: from [192.18.6.21] (HELO gmp-eb-mail-1.sun.com) (192.18.6.21) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Dec 2007 17:29:43 +0000 Received: from fe-emea-09.sun.com (gmp-eb-lb-2-fe1.eu.sun.com [192.18.6.10]) by gmp-eb-mail-1.sun.com (8.13.7+Sun/8.12.9) with ESMTP id lBJHTjxM025029 for ; Wed, 19 Dec 2007 17:29:45 GMT Received: from conversion-daemon.fe-emea-09.sun.com by fe-emea-09.sun.com (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007)) id <0JTB002014CYM000@fe-emea-09.sun.com> (original mail from Dyre.Tjeldvoll@Sun.COM) for derby-dev@db.apache.org; Wed, 19 Dec 2007 17:29:45 +0000 (GMT) Received: from khepri32.sun.com ([129.159.112.244]) by fe-emea-09.sun.com (Sun Java System Messaging Server 6.2-8.04 (built Feb 28 2007)) with ESMTPSA id <0JTB005Q54LK4120@fe-emea-09.sun.com> for derby-dev@db.apache.org; Wed, 19 Dec 2007 17:29:45 +0000 (GMT) Date: Wed, 19 Dec 2007 18:29:44 +0100 From: Dyre.Tjeldvoll@Sun.COM Subject: Re: How to invalidate when a role is revoked, so privileges will be rechecked? In-reply-to: <18278.44002.546498.717347@gargle.gargle.HOWL> Sender: Dyre.Tjeldvoll@Sun.COM To: derby-dev@db.apache.org Cc: Dag.Wanvik@Sun.COM Message-id: MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT References: <18278.44002.546498.717347@gargle.gargle.HOWL> User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.1 (usg-unix-v) X-Virus-Checked: Checked by ClamAV on apache.org "Dag H. Wanvik" 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