Novell Home

Assigning Selective Read Rights with IDM

Novell Cool Solutions: AppNote
By Raymon Epping

Digg This - Slashdot This

Posted: 20 Sep 2006
 

Overview

A customer has a white-pages application that reads eDirectory for user attribute values. A specific user object is used for authentication purposes. The customer wants to make sure the authenticated user has attribute "read" rights to all user attributes, except for all "private" details such as telephone number, postal address, etc.

The solution was to give the authenticating user "read" rights for all needed user attributes, such as Internet email address, title, telephone number, etc., and set the specified the attributes when needed. The need in this case was based on a request made by the user. The User can specify per attribute whether or not to make the attribute publicly available. Therefore we created an attribute, per so called "private" attribute. For instance:

Telephone Number -> publishTelephone Number

These attributes are Boolean-based and can be set to true or false. When set to true, the required ACL is set; when set to false, the ACL is revoked. The rest of this document explains in detail how this was accomplished using Novell IDM3, Designer, and IDM connector tracing.

To view the Dynamic ACL Driver Configuration for this solution, click here.

Process

1. Create a normal user that can be used by the white-pages application for LDAP purposes.

Figure 1 - Creating a normal user

2. Create Normal user + password, there is no need for specific options, unless desired:

Figure 2 - Creating a user and password

Figure 3 - Successful user creation

3. Give the user specific read rights to read the directory. In this case it's only the employees section of the directory, so we need to modify the trustees of this object:

Figure 4 - Modifying Trustees

4. Add the ldapProxy as a trustee:

Figure 5 - ldapProxy trustee

The user is now a trustee of the Employees object:

Figure 6 - User Trustee

5. View its assigned rights:

Figure 7 - Assigned rights for Trustee

In this case we determined that the ldapProxy user can read a select set of attributes from the user object class:

  • Given Name (open by default)
  • Surname (open by default)
  • Internet Email Address
  • Telephone + Fax number
  • Other attributes, as you determine ...

In this case, the ldapProxy is not allowed to read the user description unless permission is given by the user!

6. To accomplish this, remove the "read" from the [All Attributes Rights]. This will block all attributes for the ldapProxy user. Then add the specific attributes that are "open" separately.

Figure 8 - Removing Read rights

7. Click Apply.

Figure 9 - Applying changes

8. Click OK to finish.

Figure 10 - Finishing rights assignment

Testing

1. In order to test what you've accomplished, create a user:

Figure 11 - Creating a test user

2. Test with an ldapBrowser:

Figure 12 - ldapBrowser test

3. You can't see the description yet, so open the trustees for user Thomas' object and modify the trustees for TvVooren:

Figure 13 - Modifying Trustees

As we can see, the ldapProxy account is missing, which is expected.

4. Add it and modify the rights.

Figure 14 - Adding the ldapProxy account

Figure 15 - ldapProxy account as Trustee

5. Remove the read by [All Attribute Rights], because we want to read only the public attributes + the description attribute:

Figure 16 - Removing Read for All Attributes

6. Click Done, then Apply.

7. Click OK twice.

8. Verify it in the ldapBrowser:

Figure 17 - Verifying the changes

Cool! So now we know that we can set rights and revoke them with a web interface. Well, it would be more interesting if a user could give permission himself for the LDAP application to read the specified attribute, right? Let's call it self-provisioning, or enhanced ACL support. How do you accomplish this? Easy - Novell Identity Manager takes care of this for you.

Setting ACL rights Automatically with an IDM Connector

Here's what you need:

  • Novell eDirectory
  • An installation of Novell IDM; version 2 or 3 will do
  • An installation of Novell Designer or Novell iManager (Designer is preferred)
  • One additional attribute per attribute you want to give permission to
  • The IDM loopback connector

You should already have eDirectory running with an IDM installation on top of it, and iManager or Designer activated.

1. Start Designer.

2. Add the loopback connector, located in the service section, to your driver-set.

Figure 18 - Adding the Loopback connector

3. Set the IP address, port and data flow options now. The rest will be modified in a later stage.

Figure 19 - Setting import options

4. Set something for the groups (not needed, but required by the connector).

Figure 20 - Setting group information

Now the driver is imported, but a lot of unwanted policies are also added.

5. Delete the unnecessary policies.

Figure 21 - Deleting unneeded policies

Nice - now let's clean it up even more.

6. Open the filter and remove every object class except the user; then add the ACL and publishDescription attributes.

Figure 22 - Deleting unneeded object classes

The publishDescription is a Boolean attribute that enables an administrator or user to specify whether the attribute can be published. I included the ACL attribute in order to make life easier for developing. He who can read a trace rules the world - you'll know why in a few minutes.

7. Make sure that the trace option is set in the driver:

Figure 23 - Setting the Trace attributes

Now we enter the world of magic ...

8. Deploy the driver, make sure it's running, and open your trace.

Figure 24 - Driver Trace

Remember how we modified the trustees for user Thomas? Let's do the same for user Raymon, watching the trace closely.

9. Add the ldapProxy as a trustee to the user, without the description specified:

Figure 25 - ldapProxy as a trustee

10. This shows us exactly what we need to know, how to set the specific [All Attribute Rights] and [Entry Rights] for this object:

Figure 26 - Setting object rights

11. Add the description attribute with the correct information, which can be seen in the trace:

Figure 27 - Trace, with description attribute

Figure 28 - Modify Trustees screen

Setting ACL Attributes

Now we must decide on how the driver should react; based on that, we set the ACL attribute with the specific rights we just collected through our tracing.

The value we need to set is:

<add-value> <value timestamp="1157908678#1" type="structured"> <component name="protectedName">[Entry Rights]</component> <component name="trustee">\STYX-TREE\services\admins\ldapProxy</component> <component name="privileges">1</component> </value> </add-value> <add-value> <value timestamp="1157908678#2" type="structured"> <component name="protectedName">[All Attributes Rights]</component> <component name="trustee">\STYX-TREE\services\admins\ldapProxy</component> <component name="privileges">1</component> </value> </add-value> <add-value> <value timestamp="1157908708#1" type="structured"> <component name="protectedName">Description</component> <component name="trustee">\STYX-TREE\services\admins\ldapProxy</component> <component name="privileges">3</component> </value> </add-value>

Let's build this in the Event Transformation section of the Subscriber. That's because the driver needs to react on outgoing events of the connector, and we don't need further processing.

Here's the policy that's needed:

Figure 29 - Designer policy for setting ACL's

Let's test and see if the force is with us on this one.

1. Set the publishDescription attribute (mentioned earlier) to true for your user.

Figure 30 - Setting the publishDescription attribute

2. Now monitor your trace, with this incoming event:

Figure 31 - Monitoring the event with a trace

Figure 32 - Applied policy

The policy result is displayed in a nice, readable format:

Figure 33 - Policy result

3. View it in the ldapBrowser utility:

Figure 34 - ldapBrowser view of policy result

To summarize:

  • Create a user with specific "read" rights to the
  • directory.
  • Determine the attributes you want to have specific access on.
  • Exclude those attributes for the proxy user.
  • Collect the correct ACL values by using an IDM trace.
  • Quickly build an IDM connector based on the loopback driver which will set the correct ACL values optional replace the hard-coded values by global config values.

Done! Happy coding.

User Policy code, excerpt:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd" "C:\Novell\Designer\eclipse\plugins\com.novell.designer.idm.policybuilder_1.2.0.200609050340\DTD\dirxmlscript.dtd"><policy>
	<description>This policy will set the ACL's correctly for a user object.</description>
	<rule>
		<description>Grant ACL to user object when attribute was set to true</description>
		<comment xml:space="preserve">Grant ACL to user object when attribute was set to true</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
				<if-op-attr mode="nocase" name="publishDescription" op="changing-to">true</if-op-attr>
			</and>
		</conditions>
		<actions>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[Entry Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[All Attributes Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>

 
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">Description</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">3</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
		</actions>
	</rule>
	<rule>
		<description>Revoke ACL to user object when attribute was set to true</description>
		<comment xml:space="preserve">Revoke ACL to user object when attribute was set to true</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
				<if-op-attr mode="nocase" name="publishDescription" op="changing-to">false</if-op-attr>
			</and>
		</conditions>
		<actions>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[Entry Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>

 
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[All Attributes Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">Description</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-text xml:space="preserve">\STYX-TREE\services\admins\ldapProxy</token-text>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
		</actions>
	</rule>
	<rule>
		<description>Veto events in order to stop processing!</description>
		<comment xml:space="preserve">Veto events in order to stop processing!</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
			</and>
		</conditions>
		<actions>
			<do-veto/>
		</actions>
	</rule>
</policy>

Optional Global Config Value:

<?xml version="1.0" encoding="UTF-8"?><configuration-values>
	<definitions>
		<definition display-name="Connected System or Driver Name" name="ConnectedSystemName" type="string">
			<description>The name of the connected system, application or Identity Manager driver. This value is used by the e-mail notification templates.</description>
			<value xml:space="preserve">ACL</value>
		</definition>
		<definition display-name="ldapProxyUser" dn-space="dirxml" dn-type="slash" name="ldapProxyUser" type="dn">
			<description>ldapProxyUser</description>
			<value>\STYX-TREE\services\admins\ldapProxy</value>
		</definition>
	</definitions>
</configuration-values>
Policy code, based on Global Config Values:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd" "C:\Novell\Designer\eclipse\plugins\com.novell.designer.idm.policybuilder_1.2.0.200609050340\DTD\dirxmlscript.dtd"><policy>
	<description>This policy will set the ACL's correctly for a user object.</description>
	<rule>
		<description>Grant ACL to user object when attribute was set to true</description>
		<comment xml:space="preserve">Grant ACL to user object when attribute was set to true</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
				<if-op-attr mode="nocase" name="publishDescription" op="changing-to">true</if-op-attr>
			</and>
		</conditions>
		<actions>

 
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[Entry Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[All Attributes Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">Description</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">3</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
		</actions>
	</rule>

 
	<rule>
		<description>Revoke ACL to user object when attribute was set to true</description>
		<comment xml:space="preserve">Revoke ACL to user object when attribute was set to true</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
				<if-op-attr mode="nocase" name="publishDescription" op="changing-to">false</if-op-attr>
			</and>
		</conditions>
		<actions>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[Entry Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">[All Attributes Rights]</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>

 
			<do-add-src-attr-value class-name="User" name="ACL">
				<arg-value type="structured">
					<arg-component name="protectedName">
						<token-text xml:space="preserve">Description</token-text>
					</arg-component>
					<arg-component name="trustee">
						<token-global-variable name="ldapProxyUser"/>
					</arg-component>
					<arg-component name="privileges">
						<token-text xml:space="preserve">1</token-text>
					</arg-component>
				</arg-value>
			</do-add-src-attr-value>
		</actions>
	</rule>
	<rule>
		<description>Veto events in order to stop processing!</description>
		<comment xml:space="preserve">Veto events in order to stop processing!</comment>
		<conditions>
			<and>
				<if-class-name mode="nocase" op="equal">User</if-class-name>
			</and>
		</conditions>
		<actions>
			<do-veto/>
		</actions>
	</rule>
</policy>


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell