Как проверить все роли, которые не назначены ни одному пользователю, кроме пользователей Oracle по умолчанию (root, system и т. Д.)? - PullRequest
0 голосов
/ 05 марта 2019

Я пытаюсь создать SQL для получения всех ролей, которые не используются ни одним пользовательским (не по умолчанию) пользователем oracle или они используются пользователями в недопустимом состоянии.Для меня недопустимое состояние означает, что пользователь, который начинает с SRV_% и имеет свой статус, отличается от OPEN.

. У меня есть sql:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select *
from
  DBA_ROLE_PRIVS drolp
  join DBA_ROLES drol ON drol.ROLE = drolp.GRANTED_ROLE
where
  GRANTEE in (select USERNAME from INVALID_USERS)
  and GRANTEE not in (select USERNAME from VALID_USERS);

Вероятно, мне нужно использовать HAVING, чтобы удалить вхождения допустимых пользователей из использования недопустимой роли пользователей.Я застрял там.

1 Ответ

0 голосов
/ 05 марта 2019

Я понятия не имею, правильны ли ваши запросы VALID_USER и INVALID_USER, так как вы не предоставили нам свои требования по ним.Но я думаю, что это проблема вашего основного запроса:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select *
from
  DBA_ROLES drol
where
  -- role is assigned to AT LEAST ONE "invalid user"
  EXISTS (select 1 from DBA_ROLE_PRIVS drolp where drol.ROLE = drolp.GRANTED_ROLE and GRANTEE in (select USERNAME from INVALID_USERS))
  -- and role is not assigned to ANY "valid users"
  and NOT EXISTS (select 1 from DBA_ROLE_PRIVS drolp where drol.ROLE = drolp.GRANTED_ROLE and GRANTEE in (select USERNAME from VALID_USERS));

Логика WHERE вашего запроса проверяется один раз для каждой строки в DBA_ROLE_PRIVS, и поэтому GRANTEE всегда будет иметь одно значение - один пользователь.Так что он вернет true только для любого GRANTEE, который входит в ваши VALID_USERS и INVALID_USERS - вероятно, не то, что вы хотите.

Вам необходимо дважды запросить таблицу DBA_ROLE_PRIVS - один раз, чтобы проверить допустимых пользователей, и один раз, чтобы проверить недействительных пользователей.Вы можете обойти это с помощью агрегатных функций, хотя вам придется поместить ваши условия вне GROUP BY - сделать это подзапросом или переместить их в предложение HAVING, например:

with
  INVALID_USERS as
    (
      select
        USERNAME
      from
        DBA_USERS
      where
        USERNAME like 'SRV_%'
        and ACCOUNT_STATUS != 'OPEN'
    ),
  VALID_USERS as (
    select
      USERNAME
    from
      DBA_USERS
    where
      USERNAME not like 'SRV_%'
      and (not ACCOUNT_STATUS = 'LOCKED')
  )
select GRANTED_ROLE
from
  DBA_ROLE_PRIVS drolp
  join DBA_ROLES drol on drol.ROLE = drolp.GRANTED_ROLE
group by GRANTED_ROLE
having
  -- role is assigned to AT LEAST ONE "invalid user"
  sum(CASE when GRANTEE in (select USERNAME from INVALID_USERS) THEN 1 else 0 end) > 0
  -- and role is not assigned to ANY "valid users"
  and sum(CASE when GRANTEE in (select USERNAME from VALID_USERS) THEN 1 else 0 end) = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...