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

Reply via email to