Changeset: 043801ad6464 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=043801ad6464 Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 sql/backends/monet5/sql.c sql/backends/monet5/sql.mal sql/common/sql_types.c sql/server/rel_schema.c sql/server/rel_select.c sql/server/rel_select.h sql/server/sql_parser.y sql/server/sql_privileges.c sql/server/sql_privileges.h sql/test/BugTracker-2015/Tests/create-temp-table-using-like.Bug-3767.stable.err sql/test/BugTracker-2015/Tests/create-temp-table-using-like.Bug-3767.stable.out sql/test/BugTracker-2015/Tests/schema_view2.Bug-3766.stable.err sql/test/BugTracker-2015/Tests/schema_view2.Bug-3766.stable.out Branch: Jul2015 Log Message:
create/grant/revoke roles is now protected fixed bus 3767 and 3766 diffs (truncated from 600 to 300 lines): diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -40543,10 +40543,14 @@ pattern sql.catalog(type:int,user:str,pa address SQLcatalog; comment a user catalog statement -pattern sql.catalog(type:int,grantee:str,role:str):void +pattern sql.catalog(type:int,grantee:str,role:str,grantor:int,admin:int):void address SQLcatalog; comment a grant/revoke role statement +pattern sql.catalog(type:int,sname:str,tname:str):void +address SQLcatalog; +comment a catalog trigger statement + pattern sql.catalog(type:int,sname:str,t:ptr,restart:lng):void address SQLcatalog; comment a catalog statement diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -51478,10 +51478,14 @@ pattern sql.catalog(type:int,user:str,pa address SQLcatalog; comment a user catalog statement -pattern sql.catalog(type:int,grantee:str,role:str):void +pattern sql.catalog(type:int,grantee:str,role:str,grantor:int,admin:int):void address SQLcatalog; comment a grant/revoke role statement +pattern sql.catalog(type:int,sname:str,tname:str):void +address SQLcatalog; +comment a catalog trigger statement + pattern sql.catalog(type:int,sname:str,t:ptr,restart:lng):void address SQLcatalog; comment a catalog statement diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -1257,14 +1257,18 @@ SQLcatalog(Client cntxt, MalBlkPtr mb, M } case DDL_GRANT_ROLES:{ char *auth = SaveArgReference(stk, pci, 3); - - msg = sql_grant_role(sql, sname /*grantee */ , auth); + int grantor = *getArgReference_int(stk, pci, 4); + int admin = *getArgReference_int(stk, pci, 5); + + msg = sql_grant_role(sql, sname /*grantee */ , auth, grantor, admin); break; } case DDL_REVOKE_ROLES:{ char *auth = SaveArgReference(stk, pci, 3); - - msg = sql_revoke_role(sql, sname /*grantee */ , auth); + int grantor = *getArgReference_int(stk, pci, 4); + int admin = *getArgReference_int(stk, pci, 5); + + msg = sql_revoke_role(sql, sname /*grantee */ , auth, grantor, admin); break; } case DDL_GRANT:{ diff --git a/sql/backends/monet5/sql.mal b/sql/backends/monet5/sql.mal --- a/sql/backends/monet5/sql.mal +++ b/sql/backends/monet5/sql.mal @@ -79,7 +79,11 @@ pattern catalog(type:int,sname:str,t:ptr address SQLcatalog comment "a catalog statement"; -pattern catalog(type:int,grantee:str,role:str):void +pattern catalog(type:int,sname:str,tname:str):void +address SQLcatalog +comment "a catalog trigger statement"; + +pattern catalog(type:int,grantee:str,role:str,grantor:int,admin:int):void address SQLcatalog comment "a grant/revoke role statement"; diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -546,7 +546,7 @@ sql_bind_member_aggr(sql_allocator *sa, if (strcmp(a->base.name, sqlaname) == 0 && list_length(a->ops) == nrargs && arg_subtype_cmp(a->ops->h->data, type) == 0) - return _dup_subaggr(sa, a, type); + return _dup_subaggr(sa, a, NULL); n = n->next; } if (s) { @@ -560,7 +560,7 @@ sql_bind_member_aggr(sql_allocator *sa, if (strcmp(a->base.name, sqlaname) == 0 && list_length(a->ops) == nrargs && arg_subtype_cmp(a->ops->h->data, type) == 0) - return _dup_subaggr(sa, a, type); + return _dup_subaggr(sa, a, NULL); } } return NULL; 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 @@ -756,8 +756,10 @@ table_element(mvc *sql, symbol *s, sql_s if (!os) os = ss; ot = mvc_bind_table(sql, os, name); - if (!ot) + if (!ot) { + sql_error(sql, 02, "3F000!CREATE TABLE: no such table '%s'", name); return SQL_ERR; + } for (n = ot->columns.set->h; n; n = n->next) { sql_column *oc = n->data; @@ -941,7 +943,7 @@ rel_create_view(mvc *sql, sql_schema *ss return sql_error(sql, 01, "42000!CREATE VIEW: ORDER BY not supported"); } - sq = rel_selects(sql, query); + sq = schema_selects(sql, s, query); if (!sq) return NULL; @@ -1207,7 +1209,7 @@ sql_alter_table(mvc *sql, dlist *qname, } static sql_rel * -rel_role(sql_allocator *sa, char *grantee, char *auth, int type) +rel_role(sql_allocator *sa, char *grantee, char *auth, int grantor, int admin, int type) { sql_rel *rel = rel_create(sa); list *exps = new_exp_list(sa); @@ -1215,6 +1217,8 @@ rel_role(sql_allocator *sa, char *grante assert(type == DDL_GRANT_ROLES || type == DDL_REVOKE_ROLES); append(exps, exp_atom_clob(sa, grantee)); append(exps, exp_atom_clob(sa, auth)); + append(exps, exp_atom_int(sa, grantor)); + append(exps, exp_atom_int(sa, admin)); rel->l = NULL; rel->r = NULL; rel->op = op_ddl; @@ -1233,16 +1237,13 @@ rel_grant_roles(mvc *sql, sql_schema *sc dnode *r, *g; (void) schema; - (void) grant; - (void) grantor; /* Stefan: unused!? */ - for (r = roles->h; r; r = r->next) { char *role = r->data.sval; for (g = grantees->h; g; g = g->next) { char *grantee = g->data.sval; - if ((res = rel_list(sql->sa, res, rel_role(sql->sa, grantee, role, DDL_GRANT_ROLES))) == NULL) { + if ((res = rel_list(sql->sa, res, rel_role(sql->sa, grantee, role, grantor, grant, DDL_GRANT_ROLES))) == NULL) { rel_destroy(res); return NULL; } @@ -1259,16 +1260,13 @@ rel_revoke_roles(mvc *sql, sql_schema *s dnode *r, *g; (void) schema; - (void) admin; - (void) grantor; /* Stefan: unused!? */ - for (r = roles->h; r; r = r->next) { char *role = r->data.sval; for (g = grantees->h; g; g = g->next) { char *grantee = g->data.sval; - if ((res = rel_list(sql->sa, res, rel_role(sql->sa, grantee, role, DDL_REVOKE_ROLES))) == NULL) { + if ((res = rel_list(sql->sa, res, rel_role(sql->sa, grantee, role, grantor, admin, DDL_REVOKE_ROLES))) == NULL) { rel_destroy(res); return NULL; } @@ -1748,7 +1746,7 @@ rel_schemas(mvc *sql, symbol *s) dlist *l = s->data.lval; char *rname = l->h->data.sval; ret = rel_schema2(sql->sa, DDL_CREATE_ROLE, rname, NULL, - l->h->next->data.i_val); + l->h->next->data.i_val ? sql->user_id : sql->role_id); } break; case SQL_DROP_ROLE: { diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -6027,3 +6027,16 @@ rel_selects(mvc *sql, symbol *s) (void) sql_error(sql, 02, "relational query without result"); return ret; } + +sql_rel * +schema_selects(mvc *sql, sql_schema *schema, symbol *s) +{ + sql_rel *res; + sql_schema *os = sql->session->schema; + + sql->session->schema = schema; + res = rel_selects(sql, s); + sql->session->schema = os; + return res; +} + diff --git a/sql/server/rel_select.h b/sql/server/rel_select.h --- a/sql/server/rel_select.h +++ b/sql/server/rel_select.h @@ -19,6 +19,7 @@ extern sql_rel* rel_setop(sql_allocator extern sql_rel* rel_inplace_setop(sql_rel *rel, sql_rel *l, sql_rel *r, operator_type setop, list *exps); extern sql_rel *rel_selects(mvc *sql, symbol *sym); +extern sql_rel *schema_selects(mvc *sql, sql_schema *s, symbol *sym); extern sql_rel * rel_subquery(mvc *sql, sql_rel *rel, symbol *sq, exp_kind ek, int apply); extern sql_rel * rel_logical_exp(mvc *sql, sql_rel *rel, symbol *sc, int f); extern sql_exp * rel_logical_value_exp(mvc *sql, sql_rel **rel, symbol *sc, int f); diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y --- a/sql/server/sql_parser.y +++ b/sql/server/sql_parser.y @@ -888,8 +888,8 @@ revoke: { dlist *l = L(); append_list(l, $3); append_list(l, $5); + append_int(l, $2); append_int(l, $6); - append_int(l, $2); $$ = _symbol_create_list( SQL_REVOKE_ROLES, l); } ; diff --git a/sql/server/sql_privileges.c b/sql/server/sql_privileges.c --- a/sql/server/sql_privileges.c +++ b/sql/server/sql_privileges.c @@ -23,6 +23,8 @@ #include "sql_semantic.h" #include <sql_parser.h> +#define PRIV_ROLE_ADMIN 0 + static const char * priv2string(int priv) { @@ -204,6 +206,9 @@ sql_create_role(mvc *m, str auth, int gr sql_table *auths = find_sql_table(sys, "auths"); sql_column *auth_name = find_sql_column(auths, "name"); + if (grantor != USER_MONETDB) + return sql_message("0P000!CREATE ROLE: insufficient privileges to create role '%s'", auth); + if (table_funcs.column_find_row(m->session->tr, auth_name, auth, NULL) != oid_nil) return sql_message("0P000!CREATE ROLE: role '%s' already exists", auth); @@ -227,8 +232,77 @@ sql_drop_role(mvc *m, str auth) return NULL; } +static oid +sql_privilege_rid(mvc *m, int auth_id, int obj_id, int priv, int sub) +{ + sql_schema *sys = find_sql_schema(m->session->tr, "sys"); + sql_table *privs = find_sql_table(sys, "privileges"); + sql_column *priv_obj = find_sql_column(privs, "obj_id"); + sql_column *priv_auth = find_sql_column(privs, "auth_id"); + sql_column *priv_priv = find_sql_column(privs, "privileges"); + + (void) sub; + return table_funcs.column_find_row(m->session->tr, priv_obj, &obj_id, priv_auth, &auth_id, priv_priv, &priv, NULL); +} + +int +sql_privilege(mvc *m, int auth_id, int obj_id, int priv, int sub) +{ + oid rid = sql_privilege_rid(m, auth_id, obj_id, priv, sub); + int res = 0; + + if (rid != oid_nil) { + /* found priv */ + res = priv; + } + return res; +} + +int +schema_privs(int grantor, sql_schema *s) +{ + if (grantor == USER_MONETDB || grantor == s->auth_id) { + return 1; + } + return 0; +} + +int +table_privs(mvc *m, sql_table *t, int priv) +{ + /* temporary tables are owned by the session user */ + if (t->persistence != SQL_PERSIST || t->commit_action) + return 1; + if (m->user_id == USER_MONETDB || m->role_id == t->s->auth_id || sql_privilege(m, m->user_id, t->base.id, priv, 0) == priv || sql_privilege(m, m->role_id, t->base.id, priv, 0) == priv || sql_privilege(m, ROLE_PUBLIC, t->base.id, priv, 0) == priv) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list