Changeset: 1e05197b6e11 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1e05197b6e11
Added Files:
        sql/test/Tests/comment-auth-a.sql
        sql/test/Tests/comment-auth-superuser.sql
        sql/test/Tests/comment-auth.SQL.py
        sql/test/Tests/comment-auth.stable.err
        sql/test/Tests/comment-auth.stable.out
Modified Files:
        sql/scripts/97_comments.sql
        sql/scripts/99_system.sql
        sql/server/rel_schema.c
        sql/test/Tests/All
Branch: comment-on
Log Message:

Implement access control on comments; slightly broken yet


diffs (truncated from 531 to 300 lines):

diff --git a/sql/scripts/97_comments.sql b/sql/scripts/97_comments.sql
--- a/sql/scripts/97_comments.sql
+++ b/sql/scripts/97_comments.sql
@@ -8,6 +8,7 @@ CREATE TABLE sys.comments (
         id INTEGER NOT NULL PRIMARY KEY,
         remark VARCHAR(65000) NOT NULL
 );
+GRANT SELECT ON sys.comments TO PUBLIC;
 
 CREATE PROCEDURE sys.comment_on(obj_id INTEGER, obj_remark VARCHAR(65000))
 BEGIN
@@ -19,14 +20,13 @@ BEGIN
                 INSERT INTO sys.comments VALUES (obj_id, obj_remark);
         END IF;
 END;
-
+-- do not grant to public
 
 
--- We have to create table systemfunctions first, because describe_all_objects 
uses it
--- to recognize system functions.  For some reason, the functions table does 
not have a
--- 'system' column.
-
+-- This used to be in 99_system.sql but we need the systemfunctions table
+-- in sys.describe_all_objects() defined below.
 CREATE TABLE systemfunctions (function_id INTEGER NOT NULL);
+GRANT SELECT ON systemfunctions TO PUBLIC;
 
 CREATE FUNCTION sys.describe_all_objects()
 RETURNS TABLE (
@@ -105,6 +105,7 @@ BEGIN
            ORDER BY system, name, fullname, ntype
        );
 END;
+GRANT EXECUTE ON FUNCTION sys.describe_all_objects() TO PUBLIC;
 
 CREATE VIEW commented_function_signatures AS
 WITH
@@ -147,3 +148,4 @@ SELECT  fid,
         ROW_NUMBER() OVER (ORDER BY fid, n) AS line
 FROM commented_function_params
 ORDER BY line;
+GRANT SELECT ON sys.commented_function_signatures TO PUBLIC;
diff --git a/sql/scripts/99_system.sql b/sql/scripts/99_system.sql
--- a/sql/scripts/99_system.sql
+++ b/sql/scripts/99_system.sql
@@ -6,7 +6,6 @@
 
 -- only system functions until now
 insert into systemfunctions select id from functions;
-grant select on systemfunctions to public;
 
 create trigger system_update_schemas after update on sys.schemas for each 
statement call sys_update_schemas(); 
 create trigger system_update_tables after update on sys._tables for each 
statement call sys_update_tables(); 
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -1989,7 +1989,7 @@ current_or_designated_schema(mvc *sql, c
 }
 
 static sqlid
-rel_find_designated_schema(mvc *sql, symbol *sym) {
+rel_find_designated_schema(mvc *sql, symbol *sym, sql_schema **schema_out) {
        char *sname;
        sql_schema *s;
 
@@ -1999,11 +1999,13 @@ rel_find_designated_schema(mvc *sql, sym
                sql_error(sql, 02, "3F000!COMMENT ON:no such schema: %s", 
sname);
                return 0;
        }
+
+       *schema_out = s;
        return s->base.id;
 }
 
 static sqlid
-rel_find_designated_table(mvc *sql, symbol *sym) {
+rel_find_designated_table(mvc *sql, symbol *sym, sql_schema **schema_out) {
        dlist *qname;
        sql_schema *s;
        char *tname;
@@ -2016,8 +2018,10 @@ rel_find_designated_table(mvc *sql, symb
                return 0;
        tname = qname_table(qname);
        t = mvc_bind_table(sql, s, tname);
-       if (t && !want_table == !isKindOfTable(t))      /* comparing booleans 
can be tricky */
+       if (t && !want_table == !isKindOfTable(t)) {    /* comparing booleans 
can be tricky */
+               *schema_out = s;
                return t->base.id;
+       }
 
        sql_error(sql, 02, "42S02!COMMENT ON:no such %s: %s.%s",
                want_table ? "table" : "view",
@@ -2026,7 +2030,7 @@ rel_find_designated_table(mvc *sql, symb
 }
 
 static sqlid
-rel_find_designated_column(mvc *sql, symbol *sym) {
+rel_find_designated_column(mvc *sql, symbol *sym, sql_schema **schema_out) {
        char *sname, *tname, *cname;
        dlist *colname;
        sql_schema *s;
@@ -2059,11 +2063,12 @@ rel_find_designated_column(mvc *sql, sym
                sql_error(sql, 02, "42S22!COMMENT ON:no such column: %s.%s", 
tname, cname);
                return 0;
        }
+       *schema_out = s;
        return c->base.id;
 }
 
 static sqlid
-rel_find_designated_index(mvc *sql, symbol *sym) {
+rel_find_designated_index(mvc *sql, symbol *sym, sql_schema **schema_out) {
        dlist *qname;
        sql_schema *s;
        char *iname;
@@ -2075,8 +2080,10 @@ rel_find_designated_index(mvc *sql, symb
                return 0;
        iname = qname_table(qname);
        idx = mvc_bind_idx(sql, s, iname);
-       if (idx)
+       if (idx) {
+               *schema_out = s;
                return idx->base.id;
+       }
 
        sql_error(sql, 02, "42S12!COMMENT ON:no such index: %s.%s",
                s->base.name, iname);
@@ -2084,7 +2091,7 @@ rel_find_designated_index(mvc *sql, symb
 }
 
 static sqlid
-rel_find_designated_sequence(mvc *sql, symbol *sym) {
+rel_find_designated_sequence(mvc *sql, symbol *sym, sql_schema **schema_out) {
        (void)sql;
        (void)sym;
        dlist *qname;
@@ -2098,8 +2105,10 @@ rel_find_designated_sequence(mvc *sql, s
                return 0;
        seqname = qname_table(qname);
        seq = find_sql_sequence(s, seqname);
-       if (seq)
+       if (seq) {
+               *schema_out = s;
                return seq->base.id;
+       }
 
        sql_error(sql, 02, "42000!COMMENT ON:no such sequence: %s.%s",
                s->base.name, seqname);
@@ -2108,7 +2117,7 @@ rel_find_designated_sequence(mvc *sql, s
 
 
 static sqlid
-rel_find_designated_routine(mvc *sql, symbol *sym) {
+rel_find_designated_routine(mvc *sql, symbol *sym, sql_schema **schema_out) {
        (void)sql;
        (void)sym;
        dlist *designator;
@@ -2136,8 +2145,10 @@ rel_find_designated_routine(mvc *sql, sy
                // functions returning a table have a special type
                func = resolve_func(sql, s, fname, typelist, F_UNION, 
"COMMENT");
        }
-       if (func)
+       if (func) {
+               *schema_out = s;
                return func->base.id;
+       }
 
        if (sql->errstr[0] == '\0')
                sql_error(sql, 02, "42000!COMMENT ON:no such routine: %s.%s", 
s->base.name, fname);
@@ -2145,23 +2156,26 @@ rel_find_designated_routine(mvc *sql, sy
 }
 
 static sqlid
-rel_find_designated_object(mvc *sql, symbol *sym) {
+rel_find_designated_object(mvc *sql, symbol *sym, sql_schema **schema_out) {
+       sql_schema *dummy;
 
+       if (schema_out == NULL)
+               schema_out = &dummy;
        switch (sym->token) {
                case SQL_SCHEMA:
-                       return rel_find_designated_schema(sql, sym);
+                       return rel_find_designated_schema(sql, sym, schema_out);
                case SQL_TABLE:
-                       return rel_find_designated_table(sql, sym);
+                       return rel_find_designated_table(sql, sym, schema_out);
                case SQL_VIEW:
-                       return rel_find_designated_table(sql, sym);
+                       return rel_find_designated_table(sql, sym, schema_out);
                case SQL_COLUMN:
-                       return rel_find_designated_column(sql, sym);
+                       return rel_find_designated_column(sql, sym, schema_out);
                case SQL_INDEX:
-                       return rel_find_designated_index(sql, sym);
+                       return rel_find_designated_index(sql, sym, schema_out);
                case SQL_SEQUENCE:
-                       return rel_find_designated_sequence(sql, sym);
+                       return rel_find_designated_sequence(sql, sym, 
schema_out);
                case SQL_ROUTINE:
-                       return rel_find_designated_routine(sql, sym);
+                       return rel_find_designated_routine(sql, sym, 
schema_out);
                default:
                        sql_error(sql, 2, "42000!COMMENT ON %s is not 
supported", token2string(sym->token));
                        return 0;
@@ -2169,33 +2183,52 @@ rel_find_designated_object(mvc *sql, sym
 }
 
 static sql_rel *
-rel_comment_on(mvc *sql, sqlid obj_id, char *remark) {
-       // Impersonate EXEC sys.comment_on(obj_id, remark);
+rel_comment_on(mvc *sql, sqlid obj_id, sql_schema *schema, char *remark) {
+       // Impersonate CALL sys.comment_on(obj_id, remark);
+
+       buffer *buf = NULL;
+       stream *s = NULL;
+       char *escaped = NULL;
+       char *query = NULL;
+       sql_schema *sys;
+       sql_rel *rel = NULL;
 
-       sql_rel *rel;
-       list *exps;
-       sql_exp *exp, *left, *right;
-       sql_subtype *tpe;
+       // Check authorization
+       if (!mvc_schema_privs(sql, schema)) {
+               return sql_error(sql, 02, SQLSTATE(42000) "COMMENT ON: 
insufficient privileges for user '%s' in schema '%s'", stack_get_string(sql, 
"current_user"), schema->base.name);
+       }
+       
+       buf = buffer_create(4000);
+       if (!buf)
+               goto wrap_up;
 
-       // Imitate rel_psm_call()
-       tpe = sql_bind_localtype("str");
-       left = exp_atom_int(sql->sa, obj_id);
-       right = exp_atom_str(sql->sa, remark, tpe);
-       exp = rel_binop_(sql, left, right, mvc_bind_schema(sql, "sys"), 
"comment_on", card_none);
+       s = buffer_wastream(buf, "comment_on_call");
+       if (!s)
+               goto wrap_up;
 
-       // Imitate rel_psm_stmt()
-       exps = new_exp_list(sql->sa);
-       list_append(exps, exp);
+       mnstr_printf(s, "CALL sys.comment_on(%d, ", obj_id);
+       if (!remark) {
+               mnstr_printf(s, "NULL");
+       } else {
+               escaped = sql_escape_str(remark);
+               if (!escaped)
+                       goto wrap_up;
+               mnstr_printf(s, "'%s'", escaped);
+       }
+       mnstr_printf(s, ");");
+       query = buffer_get_buf(buf);
+       sys = mvc_bind_schema(sql, "sys");
+       rel = rel_parse(sql, sys, query, m_execute); // correct mode?
 
-       // Imitate rel_psm_block()
-       rel = rel_create(sql->sa);
-       rel->op = op_ddl;
-       rel->exps = exps;
-       rel->flag = DDL_PSM;
-
-       // Imitate rel_psm()
-       sql->type = Q_UPDATE;
-
+wrap_up:
+       // if (query)
+       //      free(query);
+       // if (escaped)
+       //      free(escaped);
+       // if (s)
+       //      mnstr_destroy(s);
+       // if (buf)
+       //      buffer_destroy(buf);
        return rel;
 }
 
@@ -2391,18 +2424,19 @@ rel_schemas(mvc *sql, symbol *s)
                dlist *l = s->data.lval;
                symbol *catalog_object = l->h->data.sym;
                char *remark;
+               sql_schema *s;
                sqlid id;
 
                assert(l->cnt == 2);
                remark = l->h->next->data.sval;
 
-               id = rel_find_designated_object(sql, catalog_object);
+               id = rel_find_designated_object(sql, catalog_object, &s);
                if (!id) {
                        /* rel_find_designated_object has already set the error 
message so we don't have to */
                        return NULL;
                }
 
-               return rel_comment_on(sql, id, remark);
+               return rel_comment_on(sql, id, s, remark);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to