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