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