remove DirXML-EntitlementRef attribute values via Policy

Hello everyone,

We have the case that we want to delete defined DirXML-EntitlementRef attributes. I have managed to recognize which values we want to delete - my problem lies in actually deleting the value.
Unfortunately, you have to specify the value to be deleted, and with a structured attribute it's a bit more complicated. My problem is with the “Path” of it, no matter how I pass it, the value is simply not deleted from the IDM. So for now a very general question, have any of you already been able to successfully delete the “DirXML-EntitlementRef” attribute via policy, i.e. individual values?

We only want to delete values with nameSpace 0, so no active assignments

BR

Tobias

Tags:

  • 0  

    When I do it automatically I normally read the attribute (Dirxml-Associations), then use xpath to find the specific association: $lvAttribute[contains(., ~dirxml.auto.driverdn~)]/parent::value. That way I know what to remove.

    (my xpath could be fancier, but it gets the job done).

    Didn't see the last line before now...

    1) use ldapsearch to find the associations "(DirXML-Associations=<driver dn>#0#*)"

    2) loop through the result, use do-remove-attribute-value

    Also see here: ldapwiki.com/.../Wiki.jsp

  • 0  

    The key is to remove the Path as a variable, exactly the way it is wrtitten via using a variable to get it out of the Source..

    Here is a quick sample rule I whipped up while being bored on a call where everyone droned on...

    <rule>
    	<description>Remove revoked EntitlementRef values</description>
    	<comment name="author" xml:space="preserve">Geoffrey Carman</comment>
    	<comment name="version" xml:space="preserve">1</comment>
    	<comment name="lastchanged" xml:space="preserve">Jul 16, 2024</comment>
    	<conditions>
    		<and>
    			<if-class-name mode="nocase" op="equal">User</if-class-name>
    		</and>
    	</conditions>
    	<actions>
    		<do-for-each>
    			<arg-node-set>
    				<token-src-attr name="DirXML-EntitlementRef"/>
    			</arg-node-set>
    			<arg-actions>
    				<do-if>
    					<arg-conditions>
    						<and>
    							<if-xpath op="true">$current-node/component[@name='namespace']=0</if-xpath>
    						</and>
    					</arg-conditions>
    					<arg-actions>
    						<do-remove-src-attr-value name="DirXML-EntitlementRef">
    							<arg-value type="structured">
    								<arg-component name="volume">
    									<token-xpath expression='$current-node/component[@name="volume"]'/>
    								</arg-component>
    								<arg-component name="nameSpace">
    									<token-xpath expression='$current-node/component[@name="nameSpace"]'/>
    								</arg-component>
    								<arg-component name="path">
    									<token-xpath expression='$current-node/component[@name="path"]'/>
    								</arg-component>
    							</arg-value>
    						</do-remove-src-attr-value>
    					</arg-actions>
    					<arg-actions/>
    				</do-if>
    			</arg-actions>
    		</do-for-each>
    	</actions>
    </rule>

    Note; There are no conditions on this, so it would fire on every user that makes it to this rule. Put some condition in please before you do anything with it.

    Like if op attr mobile is changing, then trigger the rule.  Or if mobile is changing to CLEAN then you can touch users by setting their mobile to clean it up.

    I did not test that, but I am pretty sure it is close to working.

  • 0  

    Thank you for your feedback. As suggested by you, that was also my plan/procedure, but unfortunately without success. When reading out the “DirXML-EntiltmentRef” attribute, I noticed some special features that I had not yet had in this form. When I read out another structured attribute, the three components “nameSpace” / “volume” / “path” usually came back, but for the Entitlement element it is “path.xml” (I also have to access path.xml via XPATH, otherwise it cannot read out a value).

    <value timestamp="1721138121#1" type="structured">
    <component name="nameSpace">0</component>
    <component name="volume">[DN reference - customer related]</component>
    <component name="path.xml">
    <ref>
    <src>UA</src>
    <id/>
    <param>{"ID":"[Some values]","ID2":"[Some Values - customer related]}</param>
    </ref>
    </component>
    </value>

    If I now try to read the value with '$current-node/component[@name=“path.xml”]', I do not get the complete text back, but only the values. I have also tried to work with XML-Serialize, then I get the whole “XML” back, but even if I pass this as a value, it does not delete the value.

    Does the Remove-Value in the Path component have to be 1:1, i.e. with line breaks and spaces?

    This is my current rule, I have built in a check so that only certain entitlements are checked, so the DN in “volume” must occur in the defined GCV (this part works)

    <rule>
    		<description>handle DirXML-EntitlementRef</description>
    		<conditions>
    			<and>
    				<if-class-name mode="nocase" op="equal">User</if-class-name>
    				<if-attr mode="nocase" name="CN" op="equal">Ez173155</if-attr>
    				<if-attr disabled="true" name="DirXML-EntitlementRef" op="available"/>
    			</and>
    		</conditions>
    		<actions>
    			<do-for-each>
    				<arg-node-set>
    					<token-split delimiter="#">
    						<token-global-variable name="drv.job.entitlementRef.list"/>
    					</token-split>
    				</arg-node-set>
    				<arg-actions>
    					<do-set-local-variable name="lv.relevantEntitlements.slash" scope="policy">
    						<arg-string>
    							<token-local-variable name="lv.relevantEntitlements.slash"/>
    							<token-text xml:space="preserve">#\</token-text>
    							<token-xpath expression="$dirxml.auto.treename"/>
    							<token-text xml:space="preserve">\</token-text>
    							<token-parse-dn dest-dn-format="slash" src-dn-format="ldap">
    								<token-local-variable name="current-node"/>
    							</token-parse-dn>
    						</arg-string>
    					</do-set-local-variable>
    				</arg-actions>
    			</do-for-each>
    			<do-set-local-variable name="lv.relevantEntitlements.slash" scope="policy">
    				<arg-string>
    					<token-local-variable name="lv.relevantEntitlements.slash"/>
    					<token-text xml:space="preserve">#</token-text>
    				</arg-string>
    			</do-set-local-variable>
    			<do-for-each>
    				<arg-node-set>
    					<token-attr name="DirXML-EntitlementRef"/>
    				</arg-node-set>
    				<arg-actions>
    					<do-set-local-variable name="lv.volume" scope="policy">
    						<arg-string>
    							<token-xpath expression='$current-node/component[@name="volume"]'/>
    						</arg-string>
    					</do-set-local-variable>
    					<do-set-local-variable name="lv.volume.regEscaped" scope="policy">
    						<arg-string>
    							<token-replace-all regex="\\" replace-with="\\\\">
    								<token-local-variable name="lv.volume"/>
    							</token-replace-all>
    						</arg-string>
    					</do-set-local-variable>
    					<do-set-local-variable name="lv.nameSpace" scope="policy">
    						<arg-string>
    							<token-xpath expression='$current-node/component[@name="nameSpace"]'/>
    						</arg-string>
    					</do-set-local-variable>
    					<do-set-local-variable name="lv.path" scope="policy">
    						<arg-string>
    							<token-xml-serialize>
    								<token-xpath expression='$current-node/component[@name="path.xml"]'/>
    							</token-xml-serialize>
    						</arg-string>
    					</do-set-local-variable>
    					<do-if>
    						<arg-conditions>
    							<and>
    								<if-local-variable mode="regex" name="lv.relevantEntitlements.slash" op="equal">.*#$lv.volume.regEscaped$#.*</if-local-variable>
    								<if-local-variable mode="nocase" name="lv.nameSpace" op="equal">0</if-local-variable>
    							</and>
    						</arg-conditions>
    						<arg-actions>
    							<do-set-local-variable disabled="true" name="lv.path" scope="policy">
    								<arg-string>
    									<token-text xml:space="preserve"><?xml version="1.0" encoding="UTF-8" standalone="no"?></token-text>
    									<token-replace-first regex='<component name="path.xml">' replace-with="">
    										<token-replace-first regex="<\/component>" replace-with="">
    											<token-local-variable name="lv.path"/>
    										</token-replace-first>
    									</token-replace-first>
    								</arg-string>
    							</do-set-local-variable>
    							<do-remove-src-attr-value name="DirXML-EntitlementRef">
    								<arg-value type="structured">
    									<arg-component name="nameSpace">
    										<token-local-variable name="lv.nameSpace"/>
    									</arg-component>
    									<arg-component name="volume">
    										<token-local-variable name="lv.volume"/>
    									</arg-component>
    									<arg-component name="path">
    										<token-text xml:space="preserve"><?xml version="1.0" encoding="UTF-8" standalone="no"?></token-text>
    										<token-replace-first regex='<component name="path.xml">' replace-with="">
    											<token-replace-first regex="<\/component>" replace-with="">
    												<token-xml-serialize>
    													<token-xpath expression='$current-node/component[@name="path.xml"]'/>
    												</token-xml-serialize>
    											</token-replace-first>
    										</token-replace-first>
    									</arg-component>
    								</arg-value>
    							</do-remove-src-attr-value>
    						</arg-actions>
    						<arg-actions/>
    					</do-if>
    				</arg-actions>
    			</do-for-each>
    		</actions>
    	</rule>

    Edit:
    My remove value event looks currently like this:

    <nds dtdversion="4.0" ndsversion="8.x">
      <source>
        <product edition="Advanced" version="4.8.6.0000">DirXML</product>
        <contact>NetIQ Corporation</contact>
      </source>
      <input>
        <modify class-name="User" dest-dn="[Customer- data]" dest-entry-id="368308" event-id="as13020#20240717063953#99#1:b9f47ab6-5599-485d-a78f-b67af4b99955">
          <modify-attr attr-name="DirXML-EntitlementRef">
            <remove-value>
              <value type="structured">
                <component name="nameSpace">0</component>
                <component name="volume">\[Tree-Name]\system\driverset1\AD\Group</component>
                <component name="path"><?xml version="1.0" encoding="UTF-8" standalone="no"?>
            <ref>
    <src>UA</src>
    <id/>
    <param>{"ID":"[Customer- data]","ID2":"[Customer- data]"}</param>
    </ref>
    </component>
              </value>
            </remove-value>
          </modify-attr>
        </modify>
      </input>
    </nds>
    

    I copied this out of the driver trace, so I assume that the "&lt;" are only in the trace file or are only a cosmetic thing

  • Verified Answer

    +1   in reply to   

    Does the Remove-Value in the Path component have to be 1:1, i.e. with line breaks and spaces?

    Yes, it needs to be a byte-exact copy of the original value and parsing and serializing XML will not necessarily return the original bytes. There have been a number of cases of DirXML-EntitlementResult not getting cleaned up properly because of this.

    I therefore prefer doing these operations outside of the engine and use LDAP directly.

  • 0   in reply to   

    Thank your for the clarification.

    We will probably solve the problem differently, without editing the “DirXML-EntitlementRef” attribute. I thought it would be as easy to solve as other structured attributes, probably because I have never had the case that the “path” part has this “complexity”.

    If we do have to delete the attribute via LDAP, I will make the logic available here (in case someone gets into a similar situation in the future)

    Thank you all for your support!

  • 0   in reply to   

    In your sample code, you set lv.path to a string and serialize. Don't do that.  Set it to a nodeset variable and use that nodeset in the remove.  (Norbert's valid point aside, this usually works).

    Don't do this:

    <do-set-local-variable name="lv.path" scope="policy">
    	<arg-string>
    		<token-xml-serialize>
    			<token-xpath expression='$current-node/component[@name="path.xml"]'/>
    		</token-xml-serialize>
    	</arg-string>
    </do-set-local-variable>

    Instead try something more like this:

    <do-set-local-variable name="lv.path" scope="policy">
    	<arg-nodeset>
    		<token-xpath expression='$current-node/component[@name="path.xml"]'/>
    	</arg-nodeset>
    </do-set-local-variable>