DASSL / ClassDB

An open-source system to let students experiment with relational data
https://dassl.github.io/ClassDB/
Other
8 stars 2 forks source link

SET SESSION AUTHORIZATION breaks ClassDB.getSessionID() (W) #243

Closed wildtayne closed 6 years ago

wildtayne commented 6 years ago

Observed in testClassDBRolesMgmt.sql. This is because only superusers can view backend_start in pg_stat_activity for other users. This is an issue because DDL operations performed while SET SESSION AUTHORIZATION is active fail because the DDL activity trigger tries to insert a NULL SessionID into DDLActivity. Below is an example error message from trying to perform a DDL op. under SET SESSION AUTHORIZATION:

SET SESSION AUTHORIZATION sysadm;
classdb200=> CREATE TABLE ttable(a INT);
ERROR:  null value in column "sessionid" violates not-null constraint
DETAIL:  Failing row contains (sysadm, 2018-06-22 15:29:47.738855, CREATE TABLE, sysadm.ttable, null).
CONTEXT:  SQL statement "INSERT INTO ClassDB.DDLActivity VALUES
         (SESSION_USER, statement_timestamp() AT TIME ZONE 'utc', TG_TAG, objId,
            ClassDB.getSessionID())"
PL/pgSQL function logddlactivity() line 34 at SQL statement

There are three solutions I see for this issue:

  1. Change ClassDB.getSessionID() owner to superuser, and set it to SECURITY DEFINER. This will allow it to always return a session ID. However the SessionID will be "wrong" under testing conditions in the sense that the session ID stored will be that of the superuser running the test, but the username will be the user specified in SET SESSION AUTHORIZATION. This is probably OK since it will only show up in testing. In normal conditions, this will still return the correct session ID.

  2. Check if the caller of ClassDB.SessionID() is superuser, and if not return the dummy value (0000000.0000000) we are using in ClassDB.ConnectionActivity. In normal usage, the caller of this function will always be a superuser, since the DDL trigger function is executed as a superuser.

  3. COALESCE backend_start with 0000000,

wildtayne commented 6 years ago

For now, I have implemented solution 1 in #240, but am open to discussion about other solutions.