From 93b2bc34763b767a81e8d8106f03dd63a5d06a3e Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Tue, 21 Jun 2011 07:35:54 +0000
Subject: [PATCH] Draft chapter on virtual and collective attributes

---
 opendj3/src/main/docbkx/admin-guide/chap-virtual-attrs-collective-attrs.xml |  238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 236 insertions(+), 2 deletions(-)

diff --git a/opendj3/src/main/docbkx/admin-guide/chap-virtual-attrs-collective-attrs.xml b/opendj3/src/main/docbkx/admin-guide/chap-virtual-attrs-collective-attrs.xml
index 78ab41c..ce7fb16 100644
--- a/opendj3/src/main/docbkx/admin-guide/chap-virtual-attrs-collective-attrs.xml
+++ b/opendj3/src/main/docbkx/admin-guide/chap-virtual-attrs-collective-attrs.xml
@@ -43,7 +43,96 @@
  <section>
   <title>Virtual Attributes</title>
   
-  <para>TODO</para>
+  <para>OpenDJ defines a number of virtual attributes by default.</para>
+  
+  <variablelist>
+   <varlistentry>
+    <term><literal>entryDN</literal></term>
+    <listitem><para>The value is the DN of the entry.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>entryUUID</literal></term>
+    <listitem><para>Provides a universally unique identifier for the
+    entry.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>hasSubordinates</literal></term>
+    <listitem><para>Boolean. Whether the entry has children.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>numSubordinates</literal></term>
+    <listitem><para>Provides the number of direct child entries.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>isMemberOf</literal></term>
+    <listitem><para>Identifies groups the entry belongs to.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>member</literal></term>
+    <listitem><para>Generated for virtual static groups.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>uniqueMember</literal></term>
+    <listitem><para>Generated for virtual static groups.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>pwdPolicySubentry</literal></term>
+    <listitem><para>Identifies the password policy that applies to the
+    entry.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>subschemaSubentry</literal></term>
+    <listitem><para>References the schema definitions.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>collectiveAttributeSubentries</literal></term>
+    <listitem><para>References applicable collective attribute
+    definitions.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>governingStructureRule</literal></term>
+    <listitem><para>References the rule on what type of subordinates the entry
+    can have.</para></listitem>
+   </varlistentry>
+   <varlistentry>
+    <term><literal>structuralObjectClass</literal></term>
+    <listitem><para>References the structural object class for the
+    entry.</para></listitem>
+   </varlistentry>
+  </variablelist>
+  
+  <para>These virtual attributes are typically operational, so you get them
+  back from a search only when you request them.</para>
+  
+  <screen width="80">$ ldapsearch -p 1389 -b dc=example,dc=com dc=example
+dn: dc=example,dc=com
+dc: example
+objectClass: domain
+objectClass: top
+
+$ ldapsearch -p 1389 -b dc=example,dc=com dc=example numSubordinates
+dn: dc=example,dc=com
+numSubordinates: 4
+</screen>
+
+  <para>You can use the existing virtual attribute types to create your
+  own virtual attributes, and you can also use the
+  <literal>user-defined</literal> type to create your own. The virtual
+  attribute is defined by the server configuration, which is not
+  replicated.</para>
+  
+  <screen width="80">$ dsconfig -h `hostname` -p 4444 -D "cn=Directory Manager" -w password \
+&gt; create-virtual-attribute --name "Served By Description" \
+&gt; --type user-defined --set enabled:true \
+&gt; --set attribute-type:description --set base-dn:dc=example,dc=com \
+&gt; --set value:"Served by OpenDJ.Example.com" -X -n
+$ ldapsearch -p 1389 -b dc=example,dc=com uid=bjensen description
+dn: uid=bjensen,ou=People,dc=example,dc=com
+description: Served by OpenDJ.Example.com
+</screen>
+  
+  <para>Collective attributes cover many use cases better than virtual
+  attributes.</para>
  </section>
 
  <section>
@@ -64,6 +153,151 @@
   apply to all users who belong to an administrators group. Alternatively
   you can define attributes that specify services available for a user
   depending on that user's service level.</para>
+  
+  <example>
+   <title>Collective Attributes: Class of Service</title>
+   
+   <note>
+    <para>This example depends on the <literal>cos</literal> object class,
+    and the <literal>classOfService</literal> attribute type defined but
+    commented out in the <link xlink:href="http://mcraig.org/ldif/Example.ldif"
+    >Example.ldif</link> file imported as sample data. To try this example
+    for yourself, add the attribute type and object class definitions
+    in comments near the top of the file, and then uncomment the
+    <literal>objectClass: cos</literal> and <literal>classOfService</literal>
+    attribute lines in <filename>Example.ldif</filename> before importing
+    the data into OpenDJ.</para>
+   </note>
+   
+   <para>This example positions collective attributes that depend on the
+   <literal>classOfService</literal> attribute values.</para>
+   
+   <itemizedlist>
+    <listitem>
+     <para>For entries with <literal>classOfService: bronze</literal>,
+     <literal>mailQuota</literal> is set to 1 GB, and
+     <literal>diskQuota</literal> is set to 10 GB.</para>
+    </listitem>
+    <listitem>
+     <para>For entries with <literal>classOfService: silver</literal>,
+     <literal>mailQuota</literal> is set to 5 GB, and
+     <literal>diskQuota</literal> is set to 50 GB.</para>
+    </listitem>
+    <listitem>
+     <para>For entries with <literal>classOfService: gold</literal>,
+     <literal>mailQuota</literal> is set to 10 GB, and
+     <literal>diskQuota</literal> is set to 100 GB.</para>
+    </listitem>
+   </itemizedlist>
+   
+   <para>You define collective attributes in the user data using a subentry.
+   In other words, collective attributes can be replicated. Collective
+   attributes use attributes defined in the directory schema. First, add the
+   <literal>mailQuote</literal> and <literal>diskQuota</literal> attributes,
+   and adjust the definition of the <literal>cos</literal> object class to
+   allow the two quota attributes.</para>
+   
+   <screen width="80">$ cat quotas.ldif 
+dn: cn=schema
+changetype: modify
+add: attributeTypes
+attributeTypes: ( example-class-of-service-disk-quota NAME 'diskQuota
+ ' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR case
+ IgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-
+ VALUE USAGE userApplications X-ORIGIN 'OpenDJ Documentation Examples' )
+-
+add: attributeTypes
+attributeTypes: ( example-class-of-service-mail-quota NAME 'mailQuota
+ ' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR case
+ IgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-
+ VALUE USAGE userApplications X-ORIGIN 'OpenDJ Documentation Examples' )
+-
+delete: objectClasses
+objectClasses: ( example-class-of-service-object-class NAME 'cos' SUP top AUX
+ ILIARY MAY classOfService X-ORIGIN 'OpenDJ Doc
+ umentation Examples' )
+-
+add: objectClasses
+objectClasses: ( example-class-of-service-object-class NAME 'cos' SUP top AUX
+ ILIARY MAY ( classOfService $ diskQuota $ mailQuota ) X-ORIGIN 'OpenDJ Doc
+ umentation Examples' )
+
+$ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -f quotas.ldif 
+Processing MODIFY request for cn=schema
+MODIFY operation successful for DN cn=schema</screen>
+
+   <para>Use the following collective attribute definitions to set the quotas
+   depending on class of service.</para>
+
+   <programlisting language="ldif" width="80"># cos.ldif: quotas by class of service
+dn: cn=Bronze Class of Service,dc=example,dc=com
+objectClass: collectiveAttributeSubentry
+objectClass: extensibleObject
+objectClass: subentry
+objectClass: top
+cn: Bronze Class of Service
+diskQuota;collective: 10 GB
+mailQuota;collective: 1 GB
+subtreeSpecification: { base "ou=People", specificationFilter "(classOfService=
+ bronze)" }
+
+dn: cn=Silver Class of Service,dc=example,dc=com
+objectClass: collectiveAttributeSubentry
+objectClass: extensibleObject
+objectClass: subentry
+objectClass: top
+cn: Silver Class of Service
+diskQuota;collective: 50 GB
+mailQuota;collective: 5 GB
+subtreeSpecification: { base "ou=People", specificationFilter "(classOfService=
+ silver)" }
+
+dn: cn=Gold Class of Service,dc=example,dc=com
+objectClass: collectiveAttributeSubentry
+objectClass: extensibleObject
+objectClass: subentry
+objectClass: top
+cn: Gold Class of Service
+diskQuota;collective: 100 GB
+mailQuota;collective: 10 GB
+subtreeSpecification: { base "ou=People", specificationFilter "(classOfService=
+ gold)" }
+</programlisting>
+
+   <para>You can add the collective attribute subentries by using the
+   <command>ldapmodify</command> command.</para>
+   
+   <screen width="80">$ ldapmodify -p 1389 -D "cn=Directory Manager" -w password -a -f cos.ldif 
+Processing ADD request for cn=Bronze Class of Service,dc=example,dc=com
+ADD operation successful for DN cn=Bronze Class of Service,dc=example,dc=com
+Processing ADD request for cn=Silver Class of Service,dc=example,dc=com
+ADD operation successful for DN cn=Silver Class of Service,dc=example,dc=com
+Processing ADD request for cn=Gold Class of Service,dc=example,dc=com
+ADD operation successful for DN cn=Gold Class of Service,dc=example,dc=com</screen>
+
+   <para>With the collective attributes defined, you can see the results on
+   user entries.</para>
+   
+   <screen width="80">$ ldapsearch -p 1389 -b dc=example,dc=com uid=bjensen \
+&gt; classOfService mailQuota diskQuota
+dn: uid=bjensen,ou=People,dc=example,dc=com
+mailQuota: 1 GB
+classOfService: bronze
+diskQuota: 10 GB
+
+$ ldapsearch -p 1389 -b dc=example,dc=com uid=kvaughan \
+&gt; classOfService mailQuota diskQuota
+dn: uid=kvaughan,ou=People,dc=example,dc=com
+mailQuota: 5 GB
+classOfService: silver
+diskQuota: 50 GB
+
+$ ldapsearch -p 1389 -b dc=example,dc=com uid=scarter \
+&gt; classOfService mailQuota diskQuota
+dn: uid=scarter,ou=People,dc=example,dc=com
+mailQuota: 10 GB
+classOfService: gold
+diskQuota: 100 GB</screen>
+  </example>
  </section>
 </chapter>
-

--
Gitblit v1.10.0