BusinessObjects Board

SeeSec - security detail for XIr2 and XI3

Title: SeeSec
Author: Joe Peters
Author notes:

Platform: Java
Version: 1.0
Disclaimer: I have not exhaustively tested the results of these scripts. It’s possible (likely) that there there are assigned rights in the system that are not displayed.

XIr2 code:

import com.crystaldecisions.sdk.occa.infostore.*;
import com.crystaldecisions.sdk.framework.*;
import com.crystaldecisions.sdk.exception.SDKException;
import com.crystaldecisions.sdk.plugin.desktop.folder.*; 
import java.util.*;

/* Classpath:
	C:\Program Files\Business Objects\common\3.5\java\lib\ebus405.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\boconfig.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\cecore.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\celib.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\ceplugins.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\cesession.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\ceutils.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\corbaidl.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\rascore.jar
	C:\Program Files\Business Objects\common\3.5\java\lib\Serialization.jar
*/

public class SeeSec
{
	// Set the following three variables with logon info the the CMS.
	public static String strUser = "<user name>";
	public static String strCMS = "<cms name>";
	public static String strPwd = "<user password>";
	
	// Set this to true to display all advanced rights; false will just display a count of assigned rights if the access level is "advanced"
	public static Boolean showAdvancedDetail = false;

	
	public static IInfoStore infoStore;

	public static void main(String[] args) 
	throws SDKException
	{
		System.out.println ("Connecting to: " + strCMS);
		
		// Print out header
		if(showAdvancedDetail)
			System.out.println("Principal\tObject ID\tObject Kind\tPath\tAccess Level\tGranted/Denied\tAdvanced Right");
		else
			System.out.println("Principal\tObject ID\tObject Kind\tPath\tAccess Level\tCount of Advanced Rights");

		// Log in to CMS and get infoStore
		ISessionMgr oSessionMgr; 
		IEnterpriseSession oEnterpriseSession;
		oSessionMgr = CrystalEnterprise.getSessionMgr();
		oEnterpriseSession = oSessionMgr.logon(strUser, strPwd, strCMS, "secEnterprise");
		infoStore = (IInfoStore)oEnterpriseSession.getService("", "InfoStore");

		// Hold the last ID in each batch, so we know where to start the next one.
	    Integer theID = new Integer(0);
	    
	    while(true)
	    {
	    	IInfoObjects iObjects = infoStore.query("SELECT TOP 1000 si_path,si_id,si_kind,si_parentid FROM CI_infoobjects,ci_systemobjects,ci_appobjects where si_kind not in ('personalcategory','MetaData.DataDBField','MetaData.BusinessField','AuditEventInfo','BIWidgets','ClientAction','ClientActionSet','ClientActionUsage') and si_kind not like 'Encyclopedia%' and si_instance = 0 and si_id > " + theID + " order by si_id");
	    	// Run until there are no more objects.
			if(iObjects.size() == 0)
				break;
				
			theID = printEm(infoStore,iObjects);
		}
	}
	
	static Integer printEm(IInfoStore oInfoStore,IInfoObjects iObjects)
	throws SDKException
	{
		Integer maxID = new Integer(99999999);
	    for(int i = 0; i < iObjects.size(); i++)
	    {
	        IInfoObject iObject = (IInfoObject) iObjects.get(i);
	    	maxID = new Integer(iObject.getID());
	    	
	    	// Get SecurityInfo for the object
	        ISecurityInfo objectSecurityInfo = iObject.getSecurityInfo();
	        
	        // And get the principals that have assigned rights
	        IObjectPrincipals iEPs = objectSecurityInfo.getObjectPrincipals();
	        
	        // Loop through each principal
	        for(Iterator<IObjectPrincipal> iopi = iEPs.iterator(); iopi.hasNext();)
	        {
	        	IObjectPrincipal iEP = iopi.next();
	        	
			    if ((iObject.getKind().equals("Inbox") || iObject.getKind().equals("FavoritesFolder") || iObject.getKind().equals("PersonalCategory"))
				  		&amp;&amp; iEP.getName().toLowerCase().equals(iObject.getTitle().toLowerCase()))
			    {
			    	continue; // skip inbox &amp; favorites folders for their owners.
			    }

	        	if (iEP.getRights().size() == 0 &amp;&amp;  iEP.isInherited())
			    	continue; // nothing to see here (no rights assigned, inheriting folders &amp; groups)
			    
	        	ISecurityRights iERights = iEP.getRights();
			    
	        	String outString = iEP.getName() + "\t" + iObject.getID() + "\t" + iObject.getKind() + "\t" + getObjectPath(iObject) + "\t";
	        	outString += iEP.getRole().getDescription(Locale.getDefault()) + "\t";
	        	// If "Advanced" rights, and we're showing detail, then show each individual right; otherwise
	        	// just show a count of assigned rights.
	        	if (("Advanced".equals(iEP.getRole().getDescription(Locale.getDefault()))))
	        	{
	        		if(showAdvancedDetail)
		        	{
		        		if (iERights.size() == 0) 
		        		{
		        			System.out.println(outString + "No rights assigned!");
		        		}
		        		else
		        		{
				        	for(Iterator<ISecurityRight> itRight = iERights.iterator(); itRight.hasNext();)
				        	{
				        		ISecurityRight isRight = itRight.next();
				        		System.out.println ( outString + (isRight.isGranted() ? "Granted\t" : "Denied\t" ) + isRight.getDescription(Locale.getDefault()) );
				        	}
		        		}
		        	}
	        		else // Advanced, just show count
		        	{
		        		System.out.println(outString += iERights.size());
		        	}
	        	}
	        	else // Not advanced rights
	        		System.out.println (outString);
	        }
		}
		return maxID;
	}
	
	// Get the full path of an object
	static String getObjectPath(IInfoObject inObject)
	throws SDKException
	{
		IInfoObject oIO = inObject;
		String path = "";
		
		while(true)
		{
			// If the current object is a folder, get its "si_path" info; otherwise just iterate up through the objects' parents
			if ("Folder".equals(oIO.getKind()))
			{
				oIO = (IInfoObject) infoStore.query("select si_id,si_path from CI_infoobjects,ci_systemobjects,ci_appobjects where si_id = " + oIO.getID()).get(0);
				path = oIO.getTitle() +  path; 
				try {
					if ( oIO.getParentID() != 0)
						for(String pathPart : ((IFolder)oIO).getPath() )
							path = pathPart + "/" + path;
				}
				catch (Exception wtf) 
				{
					// This shouldn't happen since we're checking for path count of 0 above, but just in case...
					return "<" + oIO.getID() + ">" + "/" + path + oIO.getTitle();
				}
				return path;
			}
			else
				path = path + "/" + oIO.getTitle();
			oIO = oIO.getParent();
		}
	}
	
}

XI3 code:


import com.crystaldecisions.sdk.occa.infostore.*;
import com.crystaldecisions.sdk.occa.security.CeSecurityOptions;
import com.crystaldecisions.sdk.framework.*;
import com.crystaldecisions.sdk.exception.SDKException;
import com.crystaldecisions.sdk.plugin.desktop.folder.*; 
import java.util.*;

/* Classpath:
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\cesession.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\cecore.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\celib.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\ceplugins_core.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\ebus405.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\corbaidl.jar
	C:\Program Files\Business Objects\common\4.0\java\lib\logging.jar
	C:\Program Files\Business Objects\BusinessObjects Enterprise 12.0\classes\boconfig.jar
*/


public class SeeSec
{
	// Set the following three variables with logon info the the CMS.
	public static String strUser = "<user name>";
	public static String strCMS = "<cms name>";
	public static String strPwd = "<user password>";
	
	// Set this to true to display all advanced rights; false will just display a count of assigned rights if the access level is "advanced"
	public static Boolean showAdvancedDetail = true;
	
	public static IInfoStore infoStore;

	public static void main(String[] args) 
	throws SDKException
	{
		System.out.println ("Connecting to: " + strCMS);
		
		// Print out header
		if(showAdvancedDetail)
			System.out.println("Principal\tObject ID\tObject Kind\tPath\tAccess Level(s)\tInheriting Folder\tInheriting Group\tAdvanced Right Access\tAdvanced Right Scope\tAdvanced Right Description");
		else
			System.out.println("Principal\tObject ID\tObject Kind\tPath\tAccess Level(s)\tInheriting Folder\tInheriting Group\tAdvanced Right Count");

		// Log in to CMS and get infoStore
		ISessionMgr oSessionMgr; 
		IEnterpriseSession oEnterpriseSession;
		oSessionMgr = CrystalEnterprise.getSessionMgr();
		oEnterpriseSession = oSessionMgr.logon(strUser, strPwd, strCMS, "secEnterprise");
		infoStore = (IInfoStore)oEnterpriseSession.getService("", "InfoStore");

		// Hold the last ID in each batch, so we know where to start the next one.
	    Integer theID = new Integer(0);
	    
	    while(true)
	    {
	    	IInfoObjects iObjects = infoStore.query("SELECT TOP 1000 si_path,si_id,si_kind,si_parentid FROM CI_infoobjects,ci_systemobjects,ci_appobjects where si_kind not in ('personalcategory','MetaData.DataDBField','MetaData.BusinessField','AuditEventInfo','BIWidgets','ClientAction','ClientActionSet','ClientActionUsage') and si_kind not like 'Encyclopedia%' and si_instance = 0 and si_id > " + theID + " order by si_id");
	
			if(iObjects.size() == 0)
				break;
				
			theID = printEm(infoStore,iObjects);
		}
	}
	
	static Integer printEm(IInfoStore oInfoStore,IInfoObjects iObjects)
	throws SDKException
	{
		Integer maxID = new Integer(99999999);
	    for(int i = 0; i < iObjects.size(); i++)
	    {
	        IInfoObject iObject = (IInfoObject) iObjects.get(i);
	    	maxID = new Integer(iObject.getID());
	    	
	        ISecurityInfo2 objectSecurityInfo = iObject.getSecurityInfo2();
	        IExplicitPrincipals iEPs = objectSecurityInfo.getExplicitPrincipals();
	        
	        for(Iterator<IExplicitPrincipal> iopi = iEPs.iterator(); iopi.hasNext();)
	        {
	        	IExplicitPrincipal iEP = (IExplicitPrincipal)iopi.next();
	        	
			    if ((iObject.getKind().equals("Inbox") || iObject.getKind().equals("FavoritesFolder") || iObject.getKind().equals("PersonalCategory"))
				  		&amp;&amp; iEP.getName().toLowerCase().equals(iObject.getTitle().toLowerCase()))
			    {
			    	continue; // skip inbox &amp; favorites folders for their owners.
			    }

	        	if (iEP.getRights().size() == 0 &amp;&amp; iEP.getRoles().size() == 0 &amp;&amp; iEP.isInheritFolders() &amp;&amp; iEP.isInheritGroups())
			    	continue; // nothing to see here (no rights assigned, inheriting folders &amp; groups)
			    
	        	IExplicitRights iERights = iEP.getRights();
			    
	        	String outString = iEP.getName() + "\t" + iObject.getID() + "\t" + iObject.getKind() + "\t" + getObjectPath(iObject) + "\t";

	        	IExplicitRoles iERoles = iEP.getRoles();
	        	for(Iterator<IExplicitRole> itERole = iERoles.iterator(); itERole.hasNext();)
	        	{
	        		IExplicitRole iERole = (IExplicitRole)itERole.next();
	        		outString += iERole.getTitle() + ",";
	        	}
	        	if(iERoles.size() > 0)
	        		outString = outString.substring(0,outString.length()-1);

	        	outString += "\t" + (iEP.isInheritFolders() ? "Y\t" : "N\t") 
  			  					  + (iEP.isInheritGroups() ? "Y\t" : "N\t");
	        	
        		if(showAdvancedDetail)
	        	{
	        		if (iERights.size() != 0) 
	        		{
			        	for(Iterator<IExplicitRight> itRight = iERights.iterator(); itRight.hasNext();)
			        	{
			        		Boolean displayIt = true;
			        		IExplicitRight isRight = itRight.next();
			        		RightDescriptor iRD = new RightDescriptor(isRight.getRightDescriptor());
			        		String myScope = "";
			        		
			        		// XI3 has separate access for Objects and SubObjects, and each one is a separate IExplicitRight.
			        		// We want to collapse them into the same line, and display whether it applies to the Object
			        		// or Subobject.  So, if this is the "object" ("this") right, then check if there is a subobject right too.
			        		if (isRight.getRightDescriptor().scope.equals(CeSecurityOptions.RightScope.CURRENT_OBJECT))
			        		{
			        			iRD.scope = CeSecurityOptions.RightScope.DESCENDANTS;
			        			IExplicitRight iERKids = iERights.get(iRD);
			        			if(!(iERKids==null))
			        			{
			        				if(iERKids.isGranted() == isRight.isGranted())
			        					myScope = "Object &amp; Subobjects";
			        				else // descendants have different access
			        					myScope = "Object only";
			        			}
			        			else // descendants have unassigned access
			        				myScope = "Object only";
			        		}
			        		else // scope is "descendants"; if access matches "this", then don't print anything (since we already printed "this,descendants"
			        		{
				        		iRD.scope = CeSecurityOptions.RightScope.CURRENT_OBJECT;
			        			IExplicitRight iERKids = iERights.get(iRD);
			        			if(!(iERKids==null))
			        			{
			        				if(iERKids.isGranted() != isRight.isGranted())
			        					myScope = "Subobjects only";
			        				else // descendants have SAME access - don't print this line
			        					displayIt = false;
			        			}
			        			else // "this" has unassigned access, but descendants do - print it
			        				myScope = myScope = "Subobjects only";
			        		}
			        		if(displayIt)
			        			System.out.println ( outString + (isRight.isGranted() ? "Granted\t" : "Denied\t" ) + myScope + "\t" + isRight.getDescription(Locale.getDefault()) );
			        	}
	        		}
	        		else // no advanced rights
	        			System.out.println(outString);
	        	}
        		else // Just show count
	        	{
	        		System.out.println(outString += iERights.size());
	        	}
	        	
	        }

		}
		return maxID;
	}
	
	// Get the full path of an object
	static String getObjectPath(IInfoObject inObject)
	throws SDKException
	{
		IInfoObject oIO = inObject;
		String path = "";
		
		while(true)
		{
			// If the current object is a folder, get its "si_path" info; otherwise just iterate up through the objects' parents
			if ("Folder".equals(oIO.getKind()))
			{
				oIO = (IInfoObject) infoStore.query("select si_id,si_path from CI_infoobjects,ci_systemobjects,ci_appobjects where si_id = " + oIO.getID()).get(0);
				path = oIO.getTitle() +  path; 
				try {
					if ( oIO.getParentID() != 0)
						for(String pathPart : ((IFolder)oIO).getPath() )
							path = pathPart + "/" + path;
				}
				catch (Exception wtf) 
				{
					// This shouldn't happen since we're checking for path count of 0 above, but just in case...
					return "<" + oIO.getID() + ">" + "/" + path + oIO.getTitle();
				}
				return path;
			}
			else
				path = path + "/" + oIO.getTitle();
			oIO = oIO.getParent();
		}
	}
	
}

joepeters :us: (BOB member since 2002-08-29)

It would be useful to include information on how to use this script ?


adrian.rutter :uk: (BOB member since 2002-08-21)

Are you familiar with Eclipse, or Java programming in general?


joepeters :us: (BOB member since 2002-08-29)

I am, but at a basic level.
The use of the phrase "The CMS query in the script excludes some object types that I didn’t care about. You may need to adjust what is included, to fit your needs. " made me think it was a .js or .java file not something to build into a development framework.


adrian.rutter :uk: (BOB member since 2002-08-21)

That’s correct, this is just meant to be run as a freestanding application; not incorporated into BO in any way.

To implement:

  1. Create a new project in Eclipse.
  2. At the top of the script I list a bunch of jar files. Add these to the project’s Java Build Path
  3. Create a new class named SeeSec; paste in the entire script
  4. Run!

joepeters :us: (BOB member since 2002-08-29)

Thanks for the clarification.


adrian.rutter :uk: (BOB member since 2002-08-21)

Hi Joe

any chance you can update this to BI4.0 or BI4.1?

It is throwing this error when I try to do it myself

for this line

  oSessionMgr = CrystalEnterprise.getSessionMgr();

I had a best guess at setting the Java Build Path. The original says

C:\Program Files\Business Objects\common\3.5\java\lib\

so I use

C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib

but was not too sure about which logging.jar to use so I used the one from the same folder as the others

it also wanted to add @SuppressWarnings(“unchecked”) in several places (to the rights querying) so I let it

many thanks
Andrew[/quote]


chipdale2010 :uk: (BOB member since 2010-10-15)

Hi, Andrew.

Signature is in aspectjrt.jar. I use a common user library for all my BI4.1 projects; the list is at the end of this post. The project doesn’t need all of them, but it doesn’t hurt to include them all.

Regarding the SuppressWarnings message – that’s just a Type Safety warning; you can ignore it or let it add the SuppressWarnings annotation. Either way, it doesn’t change the behavior of the code.

Joe

C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\boconfig.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cecore.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\celib.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\ceplugins_core.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cesession.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\corbaidl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\ebus405.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\logging.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\aspectjrt.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\ceaspect.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\TraceLog.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\bcm.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.session.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.server.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.server.common.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.server.corba.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\sdk.core.session.cms.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\inproc_container.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\CTPlugin_idl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cdz_cluster_mgmt_types_idl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cvom.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\dsl_sdk_services.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\org.eclipse.emf.ecore_2.4.2.v200902171115.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\org.eclipse.emf.common_2.4.0.v200902171115.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cdzidl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\GenericContainer_proxy.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\GenericContainer_idl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\IEPlugin_idl.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\ie_proxies.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\commons-codec-1.3.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\cryptojFIPS.jar
C:\Program Files (x86)\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\lib\ccis.jar


joepeters :us: (BOB member since 2002-08-29)

thanks Joe the script is running now

in the XIR3 code there is extra code that stops the loop from repeating

// Hold the last ID in each batch, so we know where to start the next one. 
...snip...
if(true) break;

Also this shows up as faulty

else // "this" has unassigned access, but descendants do - print it 
myScope = myScope = "Subobjects only"; 

thanks again

regards
Andrew


chipdale2010 :uk: (BOB member since 2010-10-15)

Thanks Joe for sharing the script.

It works fine if the folder hierarchy is up to two levels however i wanted to see if it see through more than two levels

Appreciate your help

Viru


viru4808 :australia: (BOB member since 2008-01-09)

Probably because of the artifact debugging code that Andrew found (“if(true) break”). You should get more complete data if you remove it (I updated my post).

Joe


joepeters :us: (BOB member since 2002-08-29)

Thanks Joe,

I remember trying this earlier with //“if(true) break”) commented but it still didn’t work, maybe it will work with the new code. Will let you know how it goes.

Cheers
Viru


viru4808 :australia: (BOB member since 2008-01-09)

Has anyone got an update for BOBJ 4.1 ?


BusObjGuy2 :india: (BOB member since 2005-05-27)

My XI3 code above works with BI4, as long as you are using the BI4 libraries.


joepeters :us: (BOB member since 2002-08-29)

For those who are not familiar with Eclipse or Java, this post is very useful :
https://busintblog.wordpress.com/2014/06/27/discover-business-objects-xi-with-java-sdk/


Jibc :fr: (BOB member since 2011-07-20)

Is it possible to get this code approach on Excel VBA?


b0user (BOB member since 2016-05-25)

Sort of. The COM implementation of the Platform SDK is not as complete as Java. The code has the following limitations:
[list][:6957c0e724]No detailed rights are displayed
[
:6957c0e724]All objects appear to inherit rights from parent folders and groups[/list]
The second point may not appear to be significant, but it means that objects that break inheritance from their parents will not display in the output (they will in the Java version).

So, use at your own risk:

Option Explicit
' Required references:
'
' Crystal Enterprise Framework Library 14.0
' Crystal Enterprise InfoStore Library 14.0
' Microsoft Scripting Runtime

' Set the following three variables with logon info the the CMS.
Const strUser = "<user name>"
Const strCMS = "<cms name>"
Const strPwd = "<user password>"
    
Dim infoStore As infoStore
Dim c As Range
Dim allPrincs As Dictionary

Sub SeeSec()
    With ActiveSheet
        .UsedRange.Clear
        .Range("a1") = "Principal"
        .Range("b1") = "Object ID"
        .Range("c1") = "Object Kind"
        .Range("d1") = "Path"
        .Range("e1") = "Access Levels"
        .Range("f1") = "Inherits Folder"
        .Range("g1") = "Inherits Group"
        .Range("h1") = "Advanced Right Count"
    End With

    Set c = Range("a2")
    
    ' Log in to CMS and get infoStore
    Dim oSessionMgr As SessionMgr
    Dim oEnterpriseSession As EnterpriseSession
    Set oSessionMgr = New CrystalEnterpriseLib.SessionMgr
    Set oEnterpriseSession = oSessionMgr.Logon(strUser, strPwd, strCMS, "secEnterprise")
    Set infoStore = oEnterpriseSession.Service("", "InfoStore")
    
    Dim ioPrincs As InfoObjects
    Dim ioPrinc As InfoObject
    Set allPrincs = New Dictionary
    Set ioPrincs = infoStore.Query("select si_id,si_name from ci_systemobjects where si_kind in ('user','usergroup','customrole')")
    For Each ioPrinc In ioPrincs
        allPrincs.Add ioPrinc.ID, ioPrinc.Title
    Next
    

    ' Hold the last ID in each batch, so we know where to start the next one.
    Dim theID As Long
    Dim iObjects As InfoObjects
    While (True)
        Set iObjects = infoStore.Query("SELECT TOP 1000 si_path,si_id,si_kind,si_parentid FROM CI_infoobjects,ci_systemobjects,ci_appobjects where si_kind not in ('personalcategory','MetaData.DataDBField','MetaData.BusinessField','AuditEventInfo','BIWidgets','ClientAction','ClientActionSet','ClientActionUsage') and si_kind not like 'Encyclopedia%' and si_instance = 0 and si_id > " &amp; theID &amp; " order by si_id")
            
        If iObjects.Count = 0 Then GoTo skipit
             
        theID = printEm(infoStore, iObjects)
   Wend
skipit:
    Debug.Print "Done!"
   End Sub
    
Function printEm(oInfoStore As infoStore, iObjects As InfoObjects) As Long
    Dim maxID As Long
    
    Dim iObject As InfoObject
    For Each iObject In iObjects
        maxID = iObject.ID
        Dim objectSecurityInfo As SecurityInfo2
        Set objectSecurityInfo = iObject.SecurityInfo2
        Dim iEPs As ExplicitPrincipals
        Set iEPs = objectSecurityInfo.ExplicitPrincipals
        
        Dim iEP As ExplicitPrincipal
        
        For Each iEP In iEPs
            If (iObject.Kind = "Inbox" Or iObject.Kind = "FavoritesFolder" Or iObject.Kind = "PersonalCategory") _
                And LCase(iEP.Name) = LCase(iObject.Title) Then
                    GoTo skipout ' skip inbox &amp; favorites folders for their owners.
            End If
            
            If iEP.Rights.Count = 0 And iEP.Roles.Count = 0 And iEP.InheritFolders And iEP.InheritGroups Then
                GoTo skipout ' nothing to see here (no rights assigned, inheriting folders &amp; groups)
            End If
            
            Dim iERights As ExplicitRights
            Set iERights = iEP.Rights

            c.Value = allPrincs.Item(iEP.ID)
            c.Offset(0, 1) = iObject.ID
            c.Offset(0, 2) = iObject.Kind
            c.Offset(0, 3) = getObjectPath(iObject)
            
            Dim iERoles As ExplicitRoles
            Dim IERole As ExplicitRole
            Set iERoles = iEP.Roles

            For Each IERole In iERoles
                c.Offset(0, 4) = c.Offset(0, 4) &amp; allPrincs.Item(IERole.ID) &amp; "," ' should be Title
            Next
            
            If iERoles.Count > 0 Then
                c.Offset(0, 4) = Left(c.Offset(0, 4), Len(c.Offset(0, 4)) - 1)
            End If

            If iEP.InheritFolders Then
                c.Offset(0, 5) = "Y"
            Else
                c.Offset(0, 5) = "N"
            End If
            
            If iEP.InheritGroups Then
                c.Offset(0, 6) = "Y"
            Else
                c.Offset(0, 6) = "N"
            End If
            c.Offset(0, 7) = iERights.Count
            Set c = c.Offset(1, 0)
skipout:
        Next
    Next
    printEm = maxID

End Function
    
Function getObjectPath(inObject As InfoObject)
    Dim oio As InfoObject: Set oio = inObject
    
    Do
        getObjectPath = oio.Title &amp; "/" &amp; getObjectPath
        Set oio = oio.Parent
    Loop Until oio.ID = 4
End Function

joepeters :us: (BOB member since 2002-08-29)

Thank you :slight_smile:


b0user (BOB member since 2016-05-25)