db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mamta Satoor" <msat...@gmail.com>
Subject Re: [Grant/Revoke]Proposal for invoker/definer model
Date Wed, 15 Mar 2006 09:27:25 GMT
Here is the proposal for invoker/definer model based on StatementContext.

I am proposing that we continue to keep the "invoker" authorizer information
in GenericeLanguageConnectionContext. In addition to that, we will keep a
stack of authorizers and corresponding default schema descriptors in a
StatementContext. When authorizer information (like getAuthorizationId,
getDefaultSchema, getCurrentSchemaName etc) will be requested from
LanguageConnectionContext, it will check if it has an active
StatementContext. If it does have an active StatementContext, then
the authorization information requested will be obtained from authorizer at
the top of StatementContext's authorizer stack. But if there is no active
StatementContext, then authorization information requested will come from
LanguageConnectionContext's invoker authorizer.

Any time, a new StatementContext will be pushed, it will get it's first
authorizer for it's authorizer stack from it's parent
StatementContext(similar to what we do for sqlAllowed information in
GenericeLanguageConnectionContext.pushStatementContext). If there is no
parent StatementContext, then the first authorizer for the StatementContext
will be the invoker authorizer from GenericeLanguageConnectionContext.

I am also proposing to add three methods to StatementContext,
addAuthorizerToTopOfStack(2 variations, one that takes the name of the
definer and creates an authorizer from it and adds it to the authorizer
stack. This is required to put a definer authorizer on StatementContext's
authorizer stack. The other method will take the invoker authorizer and will
add it to the authorizer stack. This is required to put the invoker
authorizer on StatementContext's authorizer stack) and
removeAuthorizerFromTopOfStack(This is required to pop the authorizer on top
of the authorizer stack). Calls to these methods will be generated during
the generation phase of a sql depending on what that sql's needs are for
different authorizers. It will be the responsibility of the sql generation
phase to generate calls to removeAuthorizerFromTopOfStack when it is
finished with the authorizer that it added earlier using
addAuthorizerToTopOfStack.

To reitreate, a call to StatementContext.addAuthorizerToTopOfStack(Sting
definerName) method should be generated if an object requires a need to
switch to the object definer's authorization. The code generation will
involve passing the name of the object definer to StatementContext's
addAuthorizerToTopOfStack method and that method will generate definer
authorizer by using the definer name and will put that authorizer on top of
StatementContext's stack of authorizers. Example of code generation for
adding a definer authorizer to StatementContext
//We want to put the DEFINER authorizer by finding the owner name of the
object and
//generating code to call StatementContext.addAuthorizerToTopOfStack(String
definerName)
 acb.pushThisAsActivation(mb);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "getLanguageConnectionContext ", ClassName.LanguageConnectionContext, 0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
   "getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext",
0);
 String objectOwnerName = getDataDictionary().getSchemaDescriptor(
  objectSchemaUUID,
getLanguageConnectionContext().getTransactionCompile()).getSchemaName();
 mb.push(objectOwnerName);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null, "addAuthorizerToTopOfStack",
"void", 1);

If an object needs to switch to invoker's authorization, code should be
generated to get the invoker authorizer from
GenericLanguageConnectionContext and put that authorizer to the top of
authorizer stack by generating code addAuthorizerToTopOfStack(Authorizer
invokerAuthorizer). To get the invoker authorizer, I am planning on adding
method getInvokerAuthorizer to GenericLanguageConnectionContext.
Example of code generation for adding an invoker authorizer
//We want to put the INVOKER authorizer on StatementContext's authorizer
stack.
//We can find the INVOKER authorizer from LanguageConnectionContext.
 acb.pushThisAsActivation(mb);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
   "getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext",
0);
 acb.pushThisAsActivation(mb);
 mb.callMethod (VMOpcode.INVOKEINTERFACE, null,
  "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "getInvokerAuthorizer", " org.apache.derby.iapi.sql.conn.Authorizer", 0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "addAuthorizerToTopOfStack", "void", 1);

Irrespective of which authorizer was added (definer/invoker) to
StatementContext, the sql code generation phase should make sure that it
generates the code to pop that authorizer from the stack when it is finished
with that authorizer. Example of code generation for popping the authorizer
that was added earlier and should not be used anymore
 acb.pushThisAsActivation(mb);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "getLanguageConnectionContext", ClassName.LanguageConnectionContext, 0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
   "getStatementContext", "org.apache.derby.iapi.sql.conn.StatementContext",
0);
 mb.callMethod(VMOpcode.INVOKEINTERFACE, null,
  "removeAuthorizerFromTopOfStack", "void", 0);
In case the sql being executed runs into an exception, the StatementContext
gets popped out and hence no cleanup action is required for authorizers.

I think this covers it all. Please send your feedback.
Mamta
On 3/13/06, Mamta Satoor <msatoor@gmail.com> wrote:
>
> Thanks, Dan and Satheesh, for your comments. I can see why having the
> authorizer information at LanguageConnectionContext won't work. I will look
> into putting this information in StatementContext, similar to what is done
> for SQL permissions for routines.
>
> thanks,
> Mamta
>
>  On 3/13/06, Daniel John Debrunner <djd@apache.org> wrote:
> >
> > Mamta Satoor wrote:
> > > While going through some of the Derbylist mails on Grant/Revoke, I
> > > realized that various database objects in a sqlStandard mode may
> > require
> > > switching authorizers from the invoker to different definers and vice
> > > versa. This piece of task sounds interesting to me and hence I have
> > > following proposal for implementing it.
> >
> >
> > [snip view example]
> > >
> > > I am considering implementing above scenario of switching from one
> > > authorizer to another by keeping a stack of authorizers in
> > > GenericLanguageConnectionContext. Prior to intoduction of sqlStandard
> > > mode for Grant/Revoke, Derby was written to run everything with
> > invoker
> > > as the authorizer. This single invoker authorizer information is
> > > currently kept in GenericLanguageConnectionContext's
> > > authorizer(GenericAuthorizer) field. This field gets set to invoker's
> > > authorizer when GenericLanguageConnectionContext gets initialized at
> > the
> > > database connect time. This happens in
> > > GenericLanguageConnectionContext.initilize method. In addition to
> > > initilizing authorizer, this method also sets the default schema to a
> > > schema with the same name as the invoker. So, as we can see,
> > > GenericLanguageConnectionContext currently just deals with one
> > > authorizer and that authorizer is always the authorizer corresponding
> > to
> > > the user who has made connection to the database.
> > >
> > > But with the addition of Grant/Revoke to Derby, we can have different
> > > authorizers active during the execution of a single sql statement. To
> > > support multiple authorizers, GenericLanguageConnectionContext will
> > need
> > > to keep a stack of these authorizers and a corresponding stack of
> > > default schemas descriptors for those authorizers.
> >
> > How will this handle multiple open statements within a Connection, each
> > with a different stack of authorization identifiers? Maybe with
> > Satheesh's comment that this scheme wouldn't work for views makes this
> > an irrelevant question. Though, while the language connection context
> > seems ideal when there was only a single authorization identifier, it
> > doesn't quite seem right now, when statement execution drives the
> > current authorization identifier.
> >
> > How similar or different is the requirement to the existing model for
> > pushing and popping SQL permission restrictions for routines (NO SQL,
> > CONTAINS SQL etc.)? In that case the current sql permission level is
> > maintained in the statement context, and not the language connection
> > context.
> >
> > The statement context might match exception clean up better:
> >
> > > In case the sql being executed runs into an exception, as part of the
> > cleanup work,
> > > we need to remove all the authorizers (except the first one on the
> > stack since
> > > it belongs to the "invoker" ie the user who has made this connection
> > to the database)
> >
> > I don't think is correct, consider any nested situation, for example
> > routines with server-side JDBC logic, the exception can be caught in the
> >
> > routine and execution continued. The effective authorization identifer
> > can not be revoked back to the initial connection, it needs to be reset
> > to the correct level. For example if the routine was invoked by a
> > trigger then the authorization identifier should revert to the definer
> > of the trigger. Using the statement context might provide the correct
> > behaviour here, as statement contexts are (hopefully :-) popped
> > correctly in such a situation.
> >
> > Thanks,
> > Dan.
> >
> >
>

Mime
View raw message