I am attempting to apply a security constraint to Stored Processes by creating a WHERE clause that is generated based on the permissions of the User who executes the Stored Process. I have cobbled together code that will return all groups to which the person exists. However, I have discovered that some persons have additional permissions because they belong to a group that belongs to a group that has appropriate permissions. I need to create a table that pulls two specific groups and any group that belongs to those two groups.
To illustrate, UserGroupA &UserGroupB belong to UserMetaGroupA. I would like to output a table with two obs and two variables (one var for parent group and one var for child group). Ideally, I would have been able to figure it out using the ("omsobj: ...") coding, but I have been unsuccessful to date. I have included my code below that identifies the groups to which the user belongs. However, I want to expand it to evaluate any groups to which the user's stated groups belong.
data groups;
length GroupUri $256 type $60 id $17 GroupName $60 GroupList $5000;
call missing(GroupUri, type, id, GroupName);
if symexist("_metaperson") then clientname=trim(symget('_metaperson'));
else clientname=trim(symget('sysuserid'));
group_obj=cat("omsobj:IdentityGroup?IdentityGroup[MemberIdentities/Person[@Name='",strip(clientname),"']]");
groups=metadata_resolve(group_obj,type,id);
GroupList='';
if (groups >0) then
do n=1 to groups;
nobj=metadata_getnobj(group_obj,n,GroupUri);
rc=metadata_getattr(GroupUri,"Name",GroupName);
output;
end;
keep groupname;
run;
(code borrowed from http://www.mwsug.org/proceedings/2013/BI/MWSUG-2013-BI04.pdf)
Thanks for any help!
Hi:
There is a separate community for Stored Process questions. Also your code uses a DATA step (so it's not SAS Procedure code -- which is the focus of this forum), so this probably is a better question in the forum devoted to Stored Processes.
https://communities.sas.com/community/support-communities/sas_stored_processes
cynthia
I am almost to a solution, but I have returned lists of all members of the parent group (including users). I need to eliminate Persons to only be left IdentityGroups ...
data members;
length uri SelectedGroup group group2 groupuri $256;
/* initialize counters */
n=1; a=1; b=1;
/* Initialize variables to missing. */
uri=''; SelectedGroup='';group=''; groupuri='';
par='Strategy Management Users';
/* par=symget('parSelectedGroup'); Fetch global variable */
nobj=metadata_getnobj("omsobj:IdentityGroup?@name='"||par||"'",n,uri);
if nobj=0 then put 'No Group available.';
else if (nobj > 0) then do;
/* Get the group association information for the current group */
grpassn=metadata_getnasn(uri,"MemberIdentities",a,groupuri);
/* retrive group name */
rc2=metadata_getattr(groupuri, "Name", group);
rc2=metadata_getattr(groupuri, "Type", group2);
if grpassn in (-3,-4) then do;
group="Group has no groups under itselves";
output;
end;
else do while (grpassn > 0);
output;
/* Next Group */
a+1;
grpassn=metadata_getnasn(Uri,"MemberIdentities",a,groupURI);
rc2=metadata_getattr(groupuri, "Name", group);
rc2=metadata_getattr(groupuri, "Type", group2);
end;
end;
/*keep par group;*/
run;
Hi,
I think I understand what you're actually trying to do by evaluating these group memberships, and that is actually deduce the effective permissions for the user executing the stored process on a metadata object (in this case I'm guessing StM related).
I believe there is a better, and simpler, way of doing that, which doesn't require you to manually traverse group memberships to the nth degree. Have a look at the %MDSECDS macro documentation here:
http://support.sas.com/documentation/cdl/en/bisecag/61133/HTML/default/viewer.htm#a003175587.htm
What this will allow you to do is look up the effective permissions on a metadata object for your executing user. This sample code:
%mdsecds(memberfilter="@name = 'Sample: Hello World'", folder="\Products\SAS Intelligence Platform\Samples",identitynames="&_METAUSER",identitytypes="Person",membertypes="StoredProcess");
* this is the dataset you actually use ;
proc print data=MDSECDS_JOIN(keep=identityname ReadMetadata WriteMetadata); run;
will create a dataset which will look like the following:
The SAS System 20:43 Sunday, August 3, 2014 1 |
---|
Obs identityname ReadMetadata WriteMetadata 1 sasdemo Granted Indirectly Denied Indirectly |
You can then query this dataset at runtime to figure out your effective permissions on whatever reference object you choose. Obviously you'll need to change the folder value above to the metadata folder your reference object is located in, and the object name to point to your object. You'll also want to change the membertypes value to the type of your object if you want your output table to only include one row rather than a row for the parent folder as well; if you're not sure what the object type is you can omit the membertypes clause to start with and remove the keep clause in the proc print, and this will give you a column listing the memberType of the object you're after, so you can just substitute it in afterwards.
Also, according to the documentation you should be able to look your metadata object up by using @objID instead of @name and folder, but I've not managed to get this to work.
Hope this helps.
Nik
Thank you, Nik. It appears that your approach was displaying user permissions while I was seeking user memberships to define permissions. With your comments and a little perspective from the weekend, I found a solution by including PublicType.
Thanks,
data members;
length uri SelectedGroup group group2 groupuri $256;
/* initialize counters */
n=1; a=1; b=1;
/* Initialize variables to missing. */
uri=''; SelectedGroup='';group=''; groupuri=''; group2='';
par='Strategy Management Users';
/* par=symget('parSelectedGroup'); Fetch global variable */
nobj=metadata_getnobj("omsobj:IdentityGroup?@name='"||par||"'",n,uri);
if nobj=0 then put 'No Group available.';
else if (nobj > 0) then do;
/* Get the group association information for the current group */
grpassn=metadata_getnasn(uri,"MemberIdentities",a,groupuri);
/* retrive group name */
rc2=metadata_getattr(groupuri, "Name", group);
rc2=metadata_getattr(groupuri, "PublicType", group2);
if grpassn in (-3,-4) then do;
group="Group has no groups under itselves";
if group2='UserGroup' then output;
end;
else do while (grpassn > 0);
if group2='UserGroup' then output;
/* Next Group */
a+1;
grpassn=metadata_getnasn(Uri,"MemberIdentities",a,groupURI);
rc2=metadata_getattr(groupuri, "Name", group);
rc2=metadata_getattr(groupuri, "PublicType", group2);
end;
end;
keep par group;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.