Whilst investigating a user issue today, I came across an unusual occurrence of the “ORA-01031: insufficient privileges” error which was not caused to the usual suspects of missing grants and/or tablespace quota.
The issue was reported us by a user as “Unable to create a table, getting ORA-01031 error”, and as usual the first things to check are that (a) the user has create table privileges and (b) that they have a tablespace quota in which to create the table.
Checking that the user (TAYLORR*) has the necessary privileges:
SYSTEM> select * from dba_sys_privs where grantee in (select granted_role from dba_role_privs where grantee='TAYLORR') order by 1,2; GRANTEE PRIVILEGE ADM ------------------------------ ---------------------------------------- --- DEVELOPER_ROLE CREATE PROCEDURE NO DEVELOPER_ROLE CREATE SYNONYM NO DEVELOPER_ROLE CREATE TABLE NO DEVELOPER_ROLE CREATE VIEW NO DEVELOPER_ROLE UNLIMITED TABLESPACE NO USER_ROLE CREATE SESSION NO
As we can see above, the user has both CREATE TABLE and UNLIMITED TABLESPACE privileges so there shouldn’t be any problem.
Perhaps the user is attempting to create the table as part of a PL/SQL procedure, and therefore needs the privilege to be granted directly instead of via a role? Let’s login as the user and try to create a test table in SQLplus:
TAYLORR> create table test_table (a number); create table test_table (a number); * ERROR at line 1: ORA-01031: insufficient privileges
OK, so we know it’s not a PL/SQL privilege issue. Perhaps the role is not active by default?
TAYLORR> select * from session_roles; ROLE ------------------------------ USER_ROLE
Ah, now we are getting somewhere. Although we have been granted both roles, only the USER_ROLE is active when we are logged in. Let’s activate it using the SET ROLE command:
TAYLORR> set role developer_role; set role developer_role * ERROR at line 1: ORA-01979: missing or invalid password for role 'DEVELOPER_ROLE'
Now that was unexpected!
let’s look at the definition of the role:
SYSTEM> select * from dba_roles where role = 'DEVELOPER_ROLE'; ROLE PASSWORD AUTHENTICATION_TYPE ------------------------------ -------- ------------------- DEVELOPER_ROLE YES PASSWORD
Now we have identified the root cause. The DEVELOPER_ROLE has been created with a password. As a result, we must specify the password to activate the role and create the table (or alternatively remove the password from the role).
TAYLORR> set role developer_role identified by devops; Role set. TAYLORR> create table test_table (a number); Table created.
Note: For reference, the password could have been removed from the role as follows:
SYSTEM> alter role DEVELOPER_ROLE not identified ; Role altered. SYSTEM> select * from dba_roles where role = 'DEVELOPER_ROLE'; ROLE PASSWORD AUTHENTICAT ------------------------------ -------- ----------- DEVELOPER_ROLE NO NONE
* Usernames and other details have been changed to protect the confidentiality of my client.