Applied Dimensionality

Cognos Content Store Security Overview in SQL

Posted at — Jan 23, 2012
Cognos Content Store Security Overview in SQL

Ever found yourself wondering what users are really there in your BI Consumers or any other group? Sure, you’ve got a few of them explicitly listed there (bad practice) but mostly you’ve got just a list of other groups like “Western Division”, “Marketing” and all those (good practice). And they’re, most likely, nested into each other a few times (like Western Division OpEx and Marketing Asia).  Or, looking at it from totally other point of view — what groups Jack Smith is really in (again, with all these nesting ones)? Is he a member of Western Division or what?

Built-in Cognos Security administration is quite awkward (compared to so long gone Access Manager, sigh), so questions like above are so frequent. There are 3 main solutions:

  1. Buy an externally developed tool from BSP or Motio. I had a chance to look at BSP MetaManager recently and it does a whole lot of stuff to make your administration life easy. Bit of an overkill to just ask “who’s there”, but totally worth it if you’re going big scale \ long term.
  2. Buy an SDK license and use the sample script from IBM as a base and extend it just for this task and then use SDK left and right to do anything you want in Cognos. If you have an SDK license through some global license deal — the sample script maybe just what you need to get the job done.
  3. Write SQL queries to Content Store database to return just this info. It’s an unsupported (I’ll even stress this) unsupported way of doing it, but if you just want to have a quick look or are happy to loose it at some upgrade point (although it works on both 8.4 and 10.1, CS database schema isn’t changing that much), here are the scripts for both MS SQL Server and Oracle.

I used the script from this SQL.RU topic as a base and added group nesting unwrapping with Connect By in Oracle and CTE’s in SQL Server. You can turn this SQL into FM query subject and have a nifty report.

Oracle

select distinct parent_group_id,
                  group_info.name group_name,
                  user_info.ldap_id,
                  user_info.last_name,
                  user_info.first_name,
                  user_info.email,
                  user_info.user_id
                  from
    ( --unwrapping groups and roles hierarchy, by recursively connecting all child roles or groups to parent
    select rel.cmid parent_group_id, grp.cmid child_group_id  from
    cmreford1 rel, cmobjects grp
    where
    rel.refcmid = grp.cmid
   AND grp.classid IN (26, 54) -- groups and roles
    CONNECT BY PRIOR  rel.cmid = grp.cmid
    -- adding groups that just have users directly without any parent groups
    union all
    select rel.cmid parent_group_id, rel.cmid child_group_id  from
    cmreford1 rel, cmobjects grp
    where
    rel.refcmid = grp.cmid
    -- users
   AND grp.classid IN (5)
   -- no parents
   and rel.cmid not in
   (
    select rel.refcmid child_group_id  from
    cmreford1 rel
   )
    ) grp_unwrapped,
    cmreford1 user_group_relation,
    ( -- user information
    SELECT c33.cmid user_id, c33.NAME as ldap_id,
                     c1.surname last_name, c1.givenname first_name,
                     c1.email email, c1.objid
               FROM cmobjprops1 c1
               LEFT JOIN cmobjprops33 c33 ON c33.cmid = c1.cmid
               UNION
               SELECT cmobjprops1.cmid user_id, cmobjprops33.NAME as ldap_id,
                      cmobjprops1.surname last_name,
                      cmobjprops1.givenname first_name, cmobjprops1.email,
                      cmobjprops1.objid
                 FROM cmobjprops1, cmobjprops33
                 WHERE cmobjprops1.cmid = cmobjprops33.cmid
             ) user_info,
    ( -- group_information
      SELECT cmobjnames.cmid cmid, cmobjnames.NAME as NAME,
                    cmobjects.created created, cmobjects.modified modified,
                    cmobjects.disabled disabled,
                    cmobjects.classid
               FROM cmobjects, cmobjnames
               WHERE cmobjects.cmid = cmobjnames.cmid
                    AND cmobjects.classid IN (26, 54)
                     --search in english groupnames only, remove this filter to search any language
                     and  cmobjnames.mapdlocaleid = 24
    ) group_info
  where (1=1)
  and user_group_relation.cmid = grp_unwrapped.child_group_id
  and user_group_relation.refcmid = user_info.user_id
  and group_info.cmid = grp_unwrapped.parent_group_id

-- add your filters here
-- search by group name like

and group_info.name like '%Planning%Users%'

-- or search by user name like
 -- and user_info.ldap_id like '%Jack%Smith%'</pre>

MS SQL Server

with groups_unwrapped (parent_group_id, child_group_id, lvl)
as
(
select rel.cmid parent_group_id, grp.cmid child_group_id, 0 lvl from
cmreford1 rel, cmobjects grp
where
rel.refcmid = grp.cmid
AND grp.classid IN (26, 54)
-- highest ranking groups, without any parents for anchor expression
and rel.cmid not in
(select grp.cmid child_group_id from
cmreford1 rel, cmobjects grp
where
rel.refcmid = grp.cmid
AND grp.classid IN (26, 54)
)
union all
select rel.cmid parent_group_id, grp.cmid child_group_id, lvl + 1 from
cmreford1 rel, cmobjects grp, groups_unwrapped unwp
where
rel.refcmid = grp.cmid
AND grp.classid IN (26, 54)
and rel.CMID = unwp.child_group_id
)
select distinct parent_group_id,
group_info.name group_name,
user_info.ldap_id,
user_info.last_name,
user_info.first_name,
user_info.email,
user_info.user_id
from
(
select * from groups_unwrapped
-- adding just groups with users, without parents
union all
select rel.cmid parent_group_id, rel.cmid child_group_id, 0 lvl from
 cmreford1 rel, cmobjects grp
 where
 rel.refcmid = grp.cmid
 -- users
 AND grp.classid IN (5)
 -- without any parent groups
 and rel.cmid not in
 (select rel.refcmid child_group_id from
 cmreford1 rel
 )
)
grp_unwrapped,
cmreford1 user_group_relation,
( -- user information
SELECT c33.cmid user_id, c33.NAME as ldap_id,
c1.surname last_name, c1.givenname first_name,
c1.email email, c1.objid
FROM cmobjprops1 c1
LEFT JOIN cmobjprops33 c33 ON c33.cmid = c1.cmid
UNION
SELECT cmobjprops1.cmid user_id, cmobjprops33.NAME as ldap_id,
cmobjprops1.surname last_name,
cmobjprops1.givenname first_name, cmobjprops1.email,
cmobjprops1.objid
FROM cmobjprops1, cmobjprops33
WHERE cmobjprops1.cmid = cmobjprops33.cmid
) user_info,
( -- group_information
SELECT cmobjnames.cmid cmid, cmobjnames.NAME as NAME,
cmobjects.created created, cmobjects.modified modified,
cmobjects.disabled disabled,
cmobjects.classid
FROM cmobjects, cmobjnames
WHERE cmobjects.cmid = cmobjnames.cmid
AND cmobjects.classid IN (26, 54)
--search in english groupnames only, remove this filter to search any language
and cmobjnames.mapdlocaleid = 24
) group_info
where (1=1)
and user_group_relation.cmid = grp_unwrapped.child_group_id
and user_group_relation.refcmid = user_info.user_id
and group_info.cmid = grp_unwrapped.parent_group_id

-- add your filters here
-- search by group name like

and group_info.name like '%Consumer%'

-- or search by user name like
-- and user_info.ldap_id like '%Jack%'
comments powered by Disqus