Nadav Har'El created CASSANDRA-21734:
----------------------------------------

             Summary: CREATE AGGREGATE with a non-existent SFUNC or FINALFUNC 
fails with NoSuchElementException instead of InvalidRequest when authorization 
is enabled
                 Key: CASSANDRA-21734
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21734
             Project: Apache Cassandra
          Issue Type: Bug
            Reporter: Nadav Har'El


Tested on versions: 5.0.9, 6.0-alpha2

Description:

With an authorizer enabled (e.g. {{{}authorizer: CassandraAuthorizer{}}}), a 
CREATE AGGREGATE statement whose state function or final function doesn't exist 
fails with a server error. The expected InvalidRequest is "... doesn't exist":
{code:sql}
CREATE FUNCTION ks.f(a int, b int) CALLED ON NULL INPUT RETURNS int LANGUAGE 
java AS 'return a + b;';
CREATE AGGREGATE ks.agg(int) SFUNC f_not_there STYPE int;
{code}
{noformat}
ServerError: java.util.NoSuchElementException: No value present
at 
org.apache.cassandra.auth.FunctionResource.applicablePermissions(FunctionResource.java:301)
at 
org.apache.cassandra.auth.CassandraAuthorizer.authorize(CassandraAuthorizer.java:96)
...
at 
org.apache.cassandra.service.ClientState.ensurePermission(ClientState.java:530)
at 
org.apache.cassandra.cql3.statements.schema.CreateAggregateStatement.authorize(CreateAggregateStatement.java:275)
at 
org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:307)
{noformat}
The same happens when the state function exists but has the wrong argument 
types for the given STYPE, and when FINALFUNC names an aggregate rather than a 
scalar function. In all these cases the client should get an InvalidRequest.

The cause: {{CreateAggregateStatement.authorize()}} checks EXECUTE permission 
on the state and final functions before anything validates that they exist. 
{{FunctionResource.applicablePermissions()}} assumes the function exists. It 
has {{{}assert function.isPresent(){}}}, which is disabled in production, 
followed by {{{}function.get(){}}}.

The existing unit tests don't catch this. AggregationTest's 
{{{}testJavaAggregateIncompatibleTypes{}}}, 
{{{}testJavaAggregateNonExistingFuncs{}}}, 
{{testJavaAggregateWithoutStateOrFinal}} and 
{{testAggregatesReferencedInAggregates}} check exactly these statements. But 
CQLTester runs without an authorizer by default, and executes statements 
internally, so the {{authorize()}} step never runs. We found it while 
translating AggregationTest to ScyllaDB's Python-based CQL tests, which run 
against a real Cassandra node with {{{}CassandraAuthorizer{}}}. Without the 
authorizer, these tests pass.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to