Changeset: 80a9f224fe46 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/80a9f224fe46
Modified Files:
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_user.c
        sql/backends/monet5/sql_user.h
        sql/storage/store.c
        sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
Branch: iso
Log Message:

Look if user and default schema still exist when the session starts


diffs (260 lines):

diff --git a/sql/backends/monet5/sql_scenario.c 
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -273,10 +273,18 @@ SQLprepareClient(Client c, int login)
        }
        MT_lock_unset(&sql_contextLock);
        if (login) {
-               str schema = monet5_user_set_def_schema(m, c->user);
-               if (!schema) {
-                       msg = createException(PERMD,"sql.initClient", 
SQLSTATE(08004) "Schema authorization error");
-                       goto bailout;
+               switch (monet5_user_set_def_schema(m, c->user)) {
+                       case -1:
+                               msg = createException(SQL,"sql.initClient", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+                               goto bailout;
+                       case -2:
+                               msg = createException(SQL,"sql.initClient", 
SQLSTATE(42000) "The user was not found in the database, this session is going 
to terminate");
+                               goto bailout;
+                       case -3:
+                               msg = createException(SQL,"sql.initClient", 
SQLSTATE(42000) "The user's default schema was not found, this session is going 
to terminate");
+                               goto bailout;
+                       default:
+                               break;
                }
        }
 
@@ -619,14 +627,18 @@ SQLtrans(mvc *m)
                        throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
                s = m->session;
                if (!s->schema) {
-                       s->schema_name = monet5_user_get_def_schema(m, 
m->user_id);
+                       if (monet5_user_get_def_schema(m, m->user_id, 
&s->schema_name) < 0) {
+                               mvc_cancel_session(m);
+                               throw(SQL, "sql.trans", SQLSTATE(42000) "The 
user was not found in the database, this session is going to terminate");
+                       }
                        if (!s->schema_name) {
                                mvc_cancel_session(m);
                                throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
                        }
-                       assert(s->schema_name);
-                       s->schema = find_sql_schema(s->tr, s->schema_name);
-                       assert(s->schema);
+                       if (!(s->schema = find_sql_schema(s->tr, 
s->schema_name))) {
+                               mvc_cancel_session(m);
+                               throw(SQL, "sql.trans", SQLSTATE(42000) "The 
user's default schema was not found, this session is going to terminate");
+                       }
                }
        }
        return MAL_SUCCEED;
diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c
--- a/sql/backends/monet5/sql_user.c
+++ b/sql/backends/monet5/sql_user.c
@@ -553,8 +553,8 @@ monet5_user_init(backend_functions *be_f
        be_funcs->fschuserdep = &monet5_schema_user_dependencies;
 }
 
-str
-monet5_user_get_def_schema(mvc *m, int user)
+int
+monet5_user_get_def_schema(mvc *m, int user, str *schema)
 {
        oid rid;
        sqlid schema_id = int_nil;
@@ -563,7 +563,6 @@ monet5_user_get_def_schema(mvc *m, int u
        sql_table *schemas = NULL;
        sql_table *auths = NULL;
        str username = NULL;
-       str schema = NULL;
        sqlstore *store = m->session->tr->store;
        ptr cbat;
 
@@ -574,7 +573,7 @@ monet5_user_get_def_schema(mvc *m, int u
 
        rid = store->table_api.column_find_row(m->session->tr, 
find_sql_column(auths, "id"), &user, NULL);
        if (is_oid_nil(rid))
-               return NULL;
+               return -1;
        username = store->table_api.column_find_string_start(m->session->tr, 
find_sql_column(auths, "name"), rid, &cbat);
        rid = store->table_api.column_find_row(m->session->tr, 
find_sql_column(user_info, "name"), username, NULL);
        store->table_api.column_find_string_end(cbat);
@@ -585,14 +584,14 @@ monet5_user_get_def_schema(mvc *m, int u
                rid = store->table_api.column_find_row(m->session->tr, 
find_sql_column(schemas, "id"), &schema_id, NULL);
                if (!is_oid_nil(rid)) {
                        str sname = 
store->table_api.column_find_string_start(m->session->tr, 
find_sql_column(schemas, "name"), rid, &cbat);
-                       schema = sa_strdup(m->session->sa, sname);
+                       *schema = sa_strdup(m->session->sa, sname);
                        store->table_api.column_find_string_end(cbat);
                }
        }
-       return schema;
+       return 0;
 }
 
-str
+int
 monet5_user_set_def_schema(mvc *m, oid user)
 {
        oid rid;
@@ -606,20 +605,22 @@ monet5_user_set_def_schema(mvc *m, oid u
        sql_column *schemas_name = NULL;
        sql_column *schemas_id = NULL;
        sql_table *auths = NULL;
+       sql_column *auths_id = NULL;
        sql_column *auths_name = NULL;
-       str path_err = NULL, other = NULL, schema = NULL, schema_path = NULL, 
username = NULL, err = NULL;
+       str path_err = NULL, other = NULL, schema = NULL, schema_cpy, 
schema_path = NULL, username = NULL, err = NULL;
        void *p = 0;
+       int ok = 1, res = 0;
 
        TRC_DEBUG(SQL_TRANS, OIDFMT "\n", user);
 
        if ((err = AUTHresolveUser(&username, user)) != MAL_SUCCEED) {
                freeException(err);
-               return (NULL);  /* don't reveal that the user doesn't exist */
+               return -2;
        }
 
        if (mvc_trans(m) < 0) {
                GDKfree(username);
-               return NULL;
+               return -1;
        }
 
        sys = find_sql_schema(m->session->tr, "sys");
@@ -634,7 +635,7 @@ monet5_user_set_def_schema(mvc *m, oid u
                if (m->session->tr->active && (other = mvc_rollback(m, 0, NULL, 
false)) != MAL_SUCCEED)
                        freeException(other);
                GDKfree(username);
-               return NULL;
+               return -2;
        }
        schema_id = store->table_api.column_find_sqlid(m->session->tr, 
users_schema, rid);
 
@@ -646,51 +647,54 @@ monet5_user_set_def_schema(mvc *m, oid u
        schemas_name = find_sql_column(schemas, "name");
        schemas_id = find_sql_column(schemas, "id");
        auths = find_sql_table(m->session->tr, sys, "auths");
+       auths_id = find_sql_column(auths, "id");
        auths_name = find_sql_column(auths, "name");
 
        rid = store->table_api.column_find_row(m->session->tr, schemas_id, 
&schema_id, NULL);
-       if (!is_oid_nil(rid))
-               schema = store->table_api.column_find_value(m->session->tr, 
schemas_name, rid);
-
-       if (schema) {
-               char *old = schema;
-               schema = sa_strdup(m->session->sa, schema);
-               _DELETE(old);
+       if (is_oid_nil(rid)) {
+               if (m->session->tr->active && (other = mvc_rollback(m, 0, NULL, 
false)) != MAL_SUCCEED)
+                       freeException(other);
+               GDKfree(username);
+               _DELETE(schema_path);
+               return -3;
        }
+       schema = store->table_api.column_find_value(m->session->tr, 
schemas_name, rid);
+       schema_cpy = schema;
+       schema = sa_strdup(m->session->sa, schema);
+       _DELETE(schema_cpy);
 
-       /* only set schema if user is found */
+       /* check if username exists */
        rid = store->table_api.column_find_row(m->session->tr, auths_name, 
username, NULL);
-       if (!is_oid_nil(rid)) {
-               sql_column *auths_id = find_sql_column(auths, "id");
-               sqlid id = store->table_api.column_find_sqlid(m->session->tr, 
auths_id, rid);
-
-               m->user_id = m->role_id = id;
-       } else {
-               schema = NULL;
+       if (is_oid_nil(rid)) {
+               if (m->session->tr->active && (other = mvc_rollback(m, 0, NULL, 
false)) != MAL_SUCCEED)
+                       freeException(other);
+               GDKfree(username);
+               _DELETE(schema_path);
+               return -2;
        }
+       m->user_id = m->role_id = 
store->table_api.column_find_sqlid(m->session->tr, auths_id, rid);
 
        /* while getting the session's schema, set the search path as well */
-       if (!schema || !mvc_set_schema(m, schema) || (path_err = 
parse_schema_path_str(m, schema_path, true)) != MAL_SUCCEED) {
-               if (m->session->tr->active) {
-                       if ((other = mvc_rollback(m, 0, NULL, false)) != 
MAL_SUCCEED)
-                               freeException(other);
-               }
+       if (!(ok = mvc_set_schema(m, schema)) || (path_err = 
parse_schema_path_str(m, schema_path, true)) != MAL_SUCCEED) {
+               if (m->session->tr->active && (other = mvc_rollback(m, 0, NULL, 
false)) != MAL_SUCCEED)
+                       freeException(other);
                GDKfree(username);
                _DELETE(schema_path);
                freeException(path_err);
-               return NULL;
+               return ok == 0 ? -3 : -1;
        }
+       
        /* reset the user and schema names */
        if (!sqlvar_set_string(find_global_var(m, sys, "current_schema"), 
schema) ||
                !sqlvar_set_string(find_global_var(m, sys, "current_user"), 
username) ||
                !sqlvar_set_string(find_global_var(m, sys, "current_role"), 
username)) {
-               schema = NULL;
+               res = -1;
        }
        GDKfree(username);
        _DELETE(schema_path);
        if ((other = mvc_rollback(m, 0, NULL, false)) != MAL_SUCCEED) {
                freeException(other);
-               return NULL;
+               return -1;
        }
-       return schema;
+       return res;
 }
diff --git a/sql/backends/monet5/sql_user.h b/sql/backends/monet5/sql_user.h
--- a/sql/backends/monet5/sql_user.h
+++ b/sql/backends/monet5/sql_user.h
@@ -11,8 +11,8 @@
 #include "sql.h"               /* includes sql_backend.h */
 
 extern void monet5_user_init(backend_functions *be_funcs);
-extern str monet5_user_set_def_schema(mvc *m, oid user /* mal user id */);
-extern str monet5_user_get_def_schema(mvc *m, int user /* sql user id */);
+extern int monet5_user_set_def_schema(mvc *m, oid user /* mal user id */);
+extern int monet5_user_get_def_schema(mvc *m, int user /* sql user id */, str 
*schema);
 
 extern str db_users_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 extern str db_password_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -6770,6 +6770,7 @@ sql_trans_end(sql_session *s, int ok)
        } else if (ok == SQL_ERR) { /* if a conflict happened, it was already 
rollbacked */
                sql_trans_rollback(s->tr);
        }
+       assert(s->tr->active);
        s->tr->active = 0;
        s->auto_commit = s->ac_on_commit;
        sqlstore *store = s->tr->store;
diff --git a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py 
b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
--- a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
+++ b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
@@ -129,3 +129,19 @@ with SQLTestCase() as mdb1:
         mdb1.execute('drop table parent8;').assertSucceeded()
         mdb1.execute('drop schema mys2;').assertSucceeded()
         mdb1.execute('commit;').assertSucceeded()
+
+with SQLTestCase() as mdb1:
+    with SQLTestCase() as mdb2:
+        mdb1.connect(username="monetdb", password="monetdb")
+        mdb1.execute('CREATE schema mys3;').assertSucceeded()
+        mdb1.execute("CREATE USER duser3 WITH PASSWORD 'ups' NAME 'ups' SCHEMA 
mys3;").assertSucceeded()
+
+        mdb2.connect(username="duser3", password="ups")
+        mdb2.execute('select 1;').assertSucceeded()
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('drop user duser3;').assertSucceeded()
+        mdb1.execute('drop schema mys3;').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('start transaction;').assertFailed(err_code="42000", 
err_message="The user was not found in the database, this session is going to 
terminate")
+        # mbd2 cannot do anything else, the connection was terminated
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to