Usuario de solo lectura en DB2

Bueno, lo que había hecho hace un par de días, de revocarle todos los permisos a las tablas al usuario no fué suficiente. El usuario 'readonly' seguía actualizando registros. Cual era entonces el problema?

db2 => get authorizations

 Administrative Authorizations for Current User

 Direct SYSADM authority                    = NO
 Direct SYSCTRL authority                   = NO
 Direct SYSMAINT authority                  = NO
 Direct DBADM authority                     = NO
 Direct CREATETAB authority                 = NO
 Direct BINDADD authority                   = NO
 Direct CONNECT authority                   = YES
 Direct CREATE_NOT_FENC authority           = NO
 Direct IMPLICIT_SCHEMA authority           = NO
 Direct LOAD authority                      = NO
 Direct QUIESCE_CONNECT authority           = NO
 Direct CREATE_EXTERNAL_ROUTINE authority   = NO
 Direct SYSMON authority                    = NO

 Indirect SYSADM authority                  = YES
 Indirect SYSCTRL authority                 = NO
 Indirect SYSMAINT authority                = NO
 Indirect DBADM authority                   = NO
 Indirect CREATETAB authority               = YES
 Indirect BINDADD authority                 = YES
 Indirect CONNECT authority                 = YES
 Indirect CREATE_NOT_FENC authority         = NO
 Indirect IMPLICIT_SCHEMA authority         = YES
 Indirect LOAD authority                    = NO
 Indirect QUIESCE_CONNECT authority         = NO
 Indirect CREATE_EXTERNAL_ROUTINE authority = NO
 Indirect SYSMON authority                  = NO

db2 =>


Básicamente aunque el usuario no tenía el direct SYSADM authority, si lo tenía indirectamente. Y de donde obtiene esa autoridad indirectamente? Me costó bastantes googleadas y chapuzones en la documentación, pero finalmente llegué al documento que explica que db2 mantiene la seguridad en base al sistema operativo, en base a grupos de usuarios. Este usuario pertenecía al mismo grupo que los administradores, así que tenía que sacarlo de ahí y generar un nuevo grupo para administradores y para usuarios de solo lecura, o de otro modo seguiría obteniendo un SYSADM indirecto.

$ db2 get dbm cfg | grep -i sys
 Federated Database System Support           (FEDERATED) = NO
 SYSADM group name                        (SYSADM_GROUP) = STAFF
 SYSCTRL group name                      (SYSCTRL_GROUP) =
 SYSMAINT group name                    (SYSMAINT_GROUP) =
 SYSMON group name                        (SYSMON_GROUP) =
 Priority of agents                           (AGENTPRI) = SYSTEM


El grupo del sistema que contiene a los administradores se llamaba STAFF y había que cambiarlo a DB2IADM. A su vez, había que agregar un grupo al sistema llamado DB2IADM y otro INSTUSER.
En DB2IADM ponemos al propietario de la instancia DB2INST1 y ROOT, mientras que en el grupo INSTUSER dejamos al usuario READONLY.

Después solo es cosa de cambiar el parámetro del sistema:

db2 => UPDATE DBM CFG USING SYSADM_GROUP DB2IADM
DB20000I  The UPDATE DATABASE MANAGER CONFIGURATION command completed
successfully.
db2 =>

Finalmente reiniciar DB2:

$ db2stop [force] && db2start

Revisar que el grupo ha cambiado:

$ db2 get dbm cfg | grep -i sys
 Federated Database System Support           (FEDERATED) = NO
 SYSADM group name                        (SYSADM_GROUP) = DB2IADM
 SYSCTRL group name                      (SYSCTRL_GROUP) =
 SYSMAINT group name                    (SYSMAINT_GROUP) =
 SYSMON group name                        (SYSMON_GROUP) =
 Priority of agents                           (AGENTPRI) = SYSTEM


Revisar que el usuario ya no cuenta con el indirect SYSADM authority:

$ db2 get authorizations

 Administrative Authorizations for Current User

 Direct SYSADM authority                    = NO
 Direct SYSCTRL authority                   = NO
 Direct SYSMAINT authority                  = NO
 Direct DBADM authority                     = NO
 Direct CREATETAB authority                 = NO
 Direct BINDADD authority                   = NO
 Direct CONNECT authority                   = YES
 Direct CREATE_NOT_FENC authority           = NO
 Direct IMPLICIT_SCHEMA authority           = NO
 Direct LOAD authority                      = NO
 Direct QUIESCE_CONNECT authority           = NO
 Direct CREATE_EXTERNAL_ROUTINE authority   = NO
 Direct SYSMON authority                    = NO

 Indirect SYSADM authority                  = NO
 Indirect SYSCTRL authority                 = NO
 Indirect SYSMAINT authority                = NO
 Indirect DBADM authority                   = NO
 Indirect CREATETAB authority               = YES
 Indirect BINDADD authority                 = YES
 Indirect CONNECT authority                 = YES
 Indirect CREATE_NOT_FENC authority         = NO
 Indirect IMPLICIT_SCHEMA authority         = YES
 Indirect LOAD authority                    = NO
 Indirect QUIESCE_CONNECT authority         = NO
 Indirect CREATE_EXTERNAL_ROUTINE authority = NO
 Indirect SYSMON authority                  = NO


Finalmente intentar actualizar algún registro y corroborar que el usuario ya no tiene capacidad de modificar los registros:


db2 => update DB.table set loginid ='foo@bar.com' where userid = 'DBADMIN'
DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0551N  "READONLY" does not have the privilege to perform operation "UPDATE"
on object "DB.table".  SQLSTATE=42501

1 comentario:

yo

Pffffff esto está mas complejo que el ciclo de Krebs