Configure Class of Service (CoS) in 389 Directory Server

Configure pointer, indirect, and classic Class of Service (CoS) in 389 Directory Server with tested LDIF examples, qualifiers, verification, and cleanup.

Published

Updated

Read time 16 min read

Reviewed byDeepak Prasad

389 Directory Server Class of Service workflow with CoS definition entry, cosTemplate, and virtual employeeType returned to LDAP clients

Class of Service, usually shortened to CoS, lets 389 Directory Server return an attribute as though it were stored on every matching entry. The value actually comes from a CoS definition entry and a template or referenced entry.

In this guide, we'll configure and test pointer, indirect, and classic CoS on instance ldap1 under dc=example,dc=com. You'll also see how stored values interact with generated values, why CoS attributes should not be indexed, and how to remove the configuration safely.

text
User entry
uid=user1,ou=people,dc=example,dc=com
        |
        | CoS-generated value
        v
employeeType: standard

Before you start:

IMPORTANT
This guide configures CoS definition and template entries with ldapadd and ldapmodify. It does not repeat group creation, general LDIF syntax, custom schema, dsctl test-data generation, or Account Policy plug-in setup.

Tested on: Rocky Linux 10.2; 389 Directory Server 3.2.0.


How Class of Service works

CoS combines a definition entry with one or more template entries. When a client reads a target entry, the server evaluates the CoS rules and may add generated attributes to the result.

Component Purpose
CoS definition entry Defines the CoS type, scope, and one or more generated attributes (cosAttribute is multi-valued)
CoS template entry Stores the attribute value returned to matching target entries (pointer and classic CoS)
Target entry Receives the generated value when read—often without storing it locally
text
Target entry
   |
CoS definition (ldapSubentry under the effective subtree)
   |
Template selection (pointer, indirect, or classic rules)
   |
Generated attribute returned to LDAP client

In this guide, each CoS definition also uses ldapSubentry so that the administrative entry is excluded from ordinary subtree searches. The CoS behaviour itself is defined by cosSuperDefinition together with cosPointerDefinition, cosIndirectDefinition, or cosClassicDefinition. Normal searches exclude entries marked as LDAP subentries unless the search explicitly selects them.

CoS definition and template changes take effect without restarting the server. After ldapadd or ldapmodify, the next read or search against a target entry evaluates the updated rules.


Pointer vs indirect vs classic CoS

CoS type How the template is selected Suitable use case
Pointer CoS One fixed template DN (cosTemplateDn) Same value for all entries in a subtree
Indirect CoS DN stored in a target-entry attribute (cosIndirectSpecifier) Inherit a value from a related entry
Classic CoS Template base DN plus a target-entry attribute (cosSpecifier) Different templates based on categories

Prepare the test directory

WARNING
Use disposable test entries for this lab. Some commands replace the existing manager and businessCategory values, while the cleanup section deletes user2, manager1, and ou=CosTemplates. Do not run these commands against production entries or pre-existing test entries unless you record and restore their original values.

This lab uses two users, a templates container, and one manager entry for the indirect example:

text
dc=example,dc=com
├── ou=People
│   ├── uid=user1
│   ├── uid=user2
│   └── uid=manager1
└── ou=CosTemplates
    └── cn=cosTemplates (classic templates container)

I'll create ou=CosTemplates for pointer and classic template entries:

bash
dsidm ldap1 ou create --ou CosTemplates
output
Successfully created CosTemplates

The templates container is ready for pointer and classic CoS template entries in the sections below.

bash
dsidm ldap1 user create --uid user2 --cn "User Two" --displayName "User Two" --uidNumber 3002 --gidNumber 3002 --homeDirectory /home/user2
output
Successfully created user2

user2 gives you a second target entry for pointer and classic CoS checks. user1 should already exist from manage users and groups.

This lab keeps only one definition for employeeType active at a time so that the output remains easy to verify. Directory Server can combine overlapping CoS definitions, but production configurations must use predictable cosPriority values or compatible merge rules. Later sections remove the previous definition before adding the next example.


Configure a pointer CoS

I'll start with pointer CoS when every entry below a branch should receive the same generated value. Pointer CoS always refers to one fixed template DN. This lab generates employeeType: standard for every entry under ou=People.

The first LDIF block will create the template (cosTemplate + employeeType: standard) and the pointer definition subentry under ou=People.

bash
cat > /tmp/cos-pointer.ldif << 'EOF'
dn: cn=std-template,ou=CosTemplates,dc=example,dc=com
objectClass: top
objectClass: cosTemplate
objectClass: extensibleObject
cn: std-template
employeeType: standard

dn: cn=pointer-employeeType,ou=People,dc=example,dc=com
objectClass: top
objectClass: ldapSubentry
objectClass: cosSuperDefinition
objectClass: cosPointerDefinition
cn: pointer-employeeType
description: Pointer CoS - employeeType for all People entries
cosTemplateDn: cn=std-template,ou=CosTemplates,dc=example,dc=com
cosAttribute: employeeType
EOF

Load the pointer CoS entries into the directory with ldapadd:

bash
ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -f /tmp/cos-pointer.ldif
output
adding new entry "cn=std-template,ou=CosTemplates,dc=example,dc=com"

adding new entry "cn=pointer-employeeType,ou=People,dc=example,dc=com"

Both adding new entry lines mean the template and pointer definition were accepted. CoS takes effect on the next read against target entries.

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user1)" employeeType
output
dn: uid=user1,ou=people,dc=example,dc=com
employeeType: standard

I'll repeat the same read for user2 to confirm pointer CoS applies to every entry under ou=People:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user2)" employeeType
output
dn: uid=user2,ou=people,dc=example,dc=com
employeeType: standard

Both searches should return employeeType: standard even though neither user entry stored that attribute before CoS was added. The new definition is active immediately. No instance restart is required.


Control stored and generated attribute values

The cosAttribute line accepts qualifiers that control how CoS interacts with physically stored values:

Qualifier Behaviour
default Returns the generated value only when the target entry has no physically stored value. This is the default when no qualifier is specified.
override Returns the CoS-generated value instead of a physically stored value.
operational Treats the generated value as operational and gives it override behaviour. The attribute must be defined as operational in the schema and normally must be requested explicitly.
operational-default Treats the generated value as operational but returns it only when no physical value exists.
WARNING
Do not add operational to an ordinary user attribute merely to hide it from normal searches. The attribute itself must be defined as operational in the directory schema. Values generated with override or operational cannot be changed by directly modifying the target entry.

Store a physical value on user1 while the pointer CoS uses the default qualifier:

bash
dsidm ldap1 user modify user1 replace:employeeType:permanent
output
Successfully modified uid=user1,ou=people,dc=example,dc=com

Confirm the stored value wins over CoS while the default qualifier is active:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user1)" employeeType
output
dn: uid=user1,ou=people,dc=example,dc=com
employeeType: permanent

The stored value wins. user2 still receives standard from CoS.

Switch the definition to override on the CoS definition entry:

bash
ldapmodify -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket <<'EOF'
dn: cn=pointer-employeeType,ou=People,dc=example,dc=com
changetype: modify
replace: cosAttribute
cosAttribute: employeeType override
EOF

Sample output:

output
modifying entry "cn=pointer-employeeType,ou=People,dc=example,dc=com"

Re-read user1 to confirm CoS now wins:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user1)" employeeType
output
dn: uid=user1,ou=people,dc=example,dc=com
employeeType: standard

CoS now overrides the stored permanent value. Tear down the pointer CoS before the indirect example so employeeType is free for classic CoS later. ldapdelete succeeds silently when the entry exists:

bash
ldapdelete -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket "cn=pointer-employeeType,ou=People,dc=example,dc=com"

I'll remove the template entry next. In production, definitions should outlive templates during normal retirement, but this lab removes both before switching CoS type:

bash
ldapdelete -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket "cn=std-template,ou=CosTemplates,dc=example,dc=com"

Clear the physical test value from user1:

bash
dsidm ldap1 user modify user1 delete:employeeType:permanent
output
Successfully modified uid=user1,ou=people,dc=example,dc=com

Configure an indirect CoS

Use indirect CoS when the value should come from a related directory entry, such as a user's manager. Indirect CoS reads a single-valued DN attribute on the target entry and uses that entry as the template source. The lab copies departmentNumber from each user's manager entry.

I'll create manager1 with a department number. The indirect CoS copies this value to users that reference the entry:

bash
dsidm ldap1 user create --uid manager1 --cn "Manager One" --displayName "Manager One" --uidNumber 3100 --gidNumber 3100 --homeDirectory /home/manager1
output
Successfully created manager1

I'll set a department number on the manager entry because indirect CoS copies that value to users that reference it:

bash
dsidm ldap1 user modify manager1 replace:departmentNumber:1000
output
Successfully modified uid=manager1,ou=people,dc=example,dc=com

Unlike pointer and classic CoS templates, the entry referenced by an indirect CoS does not need the cosTemplate object class. Here, manager1 is an ordinary user entry whose departmentNumber value is reused for the managed users.

Add the indirect CoS definition and manager references on both users with ldapmodify. One LDIF file adds the subentry and updates both user entries:

bash
cat > /tmp/cos-indirect.ldif << 'EOF'
dn: cn=indirect-dept,ou=People,dc=example,dc=com
changetype: add
objectClass: top
objectClass: ldapSubentry
objectClass: cosSuperDefinition
objectClass: cosIndirectDefinition
cn: indirect-dept
description: Indirect CoS - departmentNumber from manager entry
cosIndirectSpecifier: manager
cosAttribute: departmentNumber

dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
replace: manager
manager: uid=manager1,ou=people,dc=example,dc=com

dn: uid=user2,ou=people,dc=example,dc=com
changetype: modify
replace: manager
manager: uid=manager1,ou=people,dc=example,dc=com
EOF

Apply the indirect definition and manager references with one ldapmodify transaction:

bash
ldapmodify -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -f /tmp/cos-indirect.ldif

Sample output:

output
adding new entry "cn=indirect-dept,ou=People,dc=example,dc=com"
modifying entry "uid=user1,ou=people,dc=example,dc=com"
modifying entry "uid=user2,ou=people,dc=example,dc=com"

The attribute named by cosIndirectSpecifier must resolve to one valid DN. A missing value, malformed DN, or multiple values prevents the server from selecting a single referenced entry.

Query the generated value:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user1)" departmentNumber manager
output
dn: uid=user1,ou=people,dc=example,dc=com
departmentNumber: 1000
manager: uid=manager1,ou=people,dc=example,dc=com

user1 shows departmentNumber: 1000 from manager1 without storing that attribute locally on the user entry. Remove the indirect definition before configuring classic CoS on the same subtree:

bash
ldapdelete -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket "cn=indirect-dept,ou=People,dc=example,dc=com"

Deleting the indirect definition stops the generated departmentNumber immediately, but it does not remove the physical manager attribute from the users.


Configure a classic CoS

Use classic CoS when a stored category on each user should select one of several templates. Classic CoS combines a template base DN with a specifier attribute on the target entry. The specifier value forms the cn RDN under the template container: cn=<specifierValue>,<cosTemplateDn>.

The lab maps a physical businessCategory on each user to a generated employeeType:

User businessCategory (stored) Generated employeeType
user1 developer developer
user2 contractor contractor

Add the template container, category templates, and classic definition with ldapadd. Template cn values (developer, contractor) must match the businessCategory you set on each user:

bash
cat > /tmp/cos-classic-add.ldif << 'EOF'
dn: cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
objectClass: top
objectClass: nsContainer
cn: cosTemplates

dn: cn=developer,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
objectClass: top
objectClass: cosTemplate
objectClass: extensibleObject
cn: developer
employeeType: developer

dn: cn=contractor,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
objectClass: top
objectClass: cosTemplate
objectClass: extensibleObject
cn: contractor
employeeType: contractor

dn: cn=classic-employeeType,ou=People,dc=example,dc=com
objectClass: top
objectClass: ldapSubentry
objectClass: cosSuperDefinition
objectClass: cosClassicDefinition
cn: classic-employeeType
description: Classic CoS - employeeType from businessCategory
cosTemplateDn: cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
cosSpecifier: businessCategory
cosAttribute: employeeType
EOF

Load the classic templates and definition subentry into the directory:

bash
ldapadd -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -f /tmp/cos-classic-add.ldif
output
adding new entry "cn=cosTemplates,ou=CosTemplates,dc=example,dc=com"

adding new entry "cn=developer,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com"

adding new entry "cn=contractor,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com"

adding new entry "cn=classic-employeeType,ou=People,dc=example,dc=com"

Next I'll set the category attribute on each user. The specifier value must match the template cn:

bash
cat > /tmp/cos-classic-users.ldif << 'EOF'
dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
replace: businessCategory
businessCategory: developer

dn: uid=user2,ou=people,dc=example,dc=com
changetype: modify
replace: businessCategory
businessCategory: contractor
EOF

Apply the category values that classic CoS will use to select each template:

bash
ldapmodify -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -f /tmp/cos-classic-users.ldif

Sample output:

output
modifying entry "uid=user1,ou=people,dc=example,dc=com"
modifying entry "uid=user2,ou=people,dc=example,dc=com"

Verify each user receives the template that matches its category:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user*)" employeeType businessCategory
output
dn: uid=user1,ou=people,dc=example,dc=com
employeeType: developer
businessCategory: developer

dn: uid=user2,ou=people,dc=example,dc=com
employeeType: contractor
businessCategory: contractor

businessCategory is stored on the entry. employeeType is generated from the matching template under cn=cosTemplates,ou=CosTemplates,dc=example,dc=com.

Role-based CoS uses the computed nsRole attribute as the cosSpecifier in a classic CoS definition. Because an entry can possess multiple roles, configure cosPriority on the corresponding templates when more than one role can generate the same attribute. See roles vs groups for role definitions before combining roles with CoS.


CoS priority and multi-valued attributes

When multiple pointer or classic templates can generate the same value, assign distinct cosPriority values on each cosTemplate entry. A lower number has higher priority, and zero is the highest supported value. Do not use negative cosPriority values. Their behaviour is undefined. Templates with equal priorities, or no priority at all, can produce an arbitrary winner.

text
cosPriority: 10   <- wins over 20
cosPriority: 20

Templates closer to the target entry in the DIT can also take precedence over distant definitions, which can override a cosPriority setting in some layouts.

Indirect CoS resolves one referenced entry through the indirect specifier and does not use cosPriority.

A single CoS definition can list multiple cosAttribute values when one template selection should generate more than one attribute. For example, you can set cosAttribute: postalCode and cosAttribute: st on the same definition.

For a multi-valued generated attribute, use a consistent merge-schemes qualifier across every definition that participates in the merge. Without distinct priorities or compatible merge rules, overlapping CoS definitions can return unpredictable values.


Inspect CoS definitions and templates

List CoS definition subentries. They are hidden from ordinary searches unless you filter for ldapSubentry:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" -s sub "(objectClass=ldapSubentry)" dn objectClass
output
dn: cn=classic-employeeType,ou=People,dc=example,dc=com
objectClass: top
objectClass: ldapSubentry
objectClass: cosSuperDefinition
objectClass: cosClassicDefinition

The cosClassicDefinition object class confirms this subentry is the active classic CoS definition for the lab.

List template entries under ou=CosTemplates:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=CosTemplates,dc=example,dc=com" "(objectClass=cosTemplate)" dn employeeType
output
dn: cn=developer,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
employeeType: developer

dn: cn=contractor,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com
employeeType: contractor

Each template stores the employeeType value that classic CoS returns when the user's businessCategory matches the template cn.

Review virtual-attribute indexing with the instance health check. Run this after configuring or changing indexes on attributes that CoS might generate:

bash
dsctl ldap1 healthcheck

A clean lab reports no DSVIRTLE0001 lines. When the check flags a virtual attribute index, remove that index and search on stored selectors such as businessCategory instead. Do not index employeeType while it is generated by CoS. An unindexed filter such as (employeeType=developer) can work, but it requires an expensive scan; an index can instead produce incomplete results.

Request operational CoS attributes explicitly when definitions use the operational qualifier. Those values do not appear in a normal attribute list.


Understand search and ACI limitations

ACIs can control whether clients may access an attribute, but do not reference a CoS-generated virtual attribute in the targetfilter, targattrfilters, or userattr ACI keywords. Directory Server does not support virtual attributes in these parts of an ACI.

Avoid designing directory authorization rules that select entries based on a generated CoS value. Filter or authorize using a physically stored attribute such as businessCategory, or retrieve the generated value after the entry has already been selected.

Subtree filters on CoS-generated attributes are unreliable when the attribute is indexed; an unindexed filter can include entries whose value comes from CoS, but it requires an unindexed scan and does not scale well. If the generated attribute is indexed, entries that possess only the virtual value can be omitted from the results. Prefer filters on stored selectors such as (businessCategory=developer) rather than (employeeType=developer) when employeeType is virtual. CoS is most suitable for attributes that applications retrieve after locating an entry, rather than attributes used for indexed entry selection or directory-side ACI conditions. See index design and maintenance for backend index planning.


Modify or remove a CoS safely

Follow this order when retiring CoS:

  1. Identify affected target entries and note which attributes were generated.
  2. Remove or disable the CoS definition entry.
  3. Confirm generated values no longer appear in searches.
  4. Delete unused template entries and containers.
  5. Remove obsolete specifier attributes on target entries when they exist only for CoS selection.

Deleting a template before its definition can leave targets without expected generated values. Remove the definition first, verify client behaviour, then delete templates.

Remove the classic CoS from this lab, starting with the definition subentry:

bash
ldapdelete -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket "cn=classic-employeeType,ou=People,dc=example,dc=com"

Delete the category templates and their container in one step:

bash
ldapdelete -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket "cn=developer,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com" "cn=contractor,cn=cosTemplates,ou=CosTemplates,dc=example,dc=com" "cn=cosTemplates,ou=CosTemplates,dc=example,dc=com"

Confirm the generated attribute no longer appears on read:

bash
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "ou=people,dc=example,dc=com" "(uid=user1)" employeeType
output
dn: uid=user1,ou=people,dc=example,dc=com

The entry is returned, but employeeType is absent because CoS no longer supplies it and nothing is stored locally.

Restore target entries and remove lab-only objects. The steps below delete physical selector and reference attributes (businessCategory, manager) in addition to CoS definitions and templates:

bash
ldapmodify -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket <<'EOF'
dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
delete: businessCategory
-
delete: manager
-

dn: uid=user2,ou=people,dc=example,dc=com
changetype: modify
delete: businessCategory
-
delete: manager
EOF

Sample output:

output
modifying entry "uid=user1,ou=people,dc=example,dc=com"
modifying entry "uid=user2,ou=people,dc=example,dc=com"

The modify removes businessCategory and manager from both users when those attributes were set during the lab.

Run the following deletion commands only when these entries were created exclusively for this lab. Do not delete an existing user or organizational unit that you reused for testing.

bash
echo "Yes I am sure" | dsidm ldap1 user delete "uid=manager1,ou=people,dc=example,dc=com"
output
Successfully deleted uid=manager1,ou=people,dc=example,dc=com

Remove the disposable second user created only for CoS verification:

bash
echo "Yes I am sure" | dsidm ldap1 user delete "uid=user2,ou=people,dc=example,dc=com"
output
Successfully deleted uid=user2,ou=people,dc=example,dc=com

Delete the templates organizational unit when it was created solely for this lab:

bash
dsidm ldap1 ou delete "ou=CosTemplates,dc=example,dc=com"
output
Successfully deleted ou=CosTemplates,dc=example,dc=com

Deleting a CoS definition stops generated values immediately. The ldapmodify step above removes physical attributes that existed only for CoS selection or indirect references. After cleanup, the lab-generated CoS values and selector attributes are removed. Any manager or businessCategory values that existed before the lab must be restored manually.


Troubleshoot Class of Service

Symptom Likely cause Fix
No generated attributes appear for any target entry Definition is outside the effective subtree, template DN is wrong, or the CoS plug-in was manually disabled Inspect the definition and template first. If the configuration was customized, verify nsslapd-pluginEnabled under cn=Class of Service,cn=plugins,cn=config
Wrong value for every entry Incorrect pointer cosTemplateDn Query the template entry; fix the DN on the definition
Indirect CoS returns nothing Specifier empty, not a DN, or multi-valued Ensure cosIndirectSpecifier points to a single-valued DN attribute with a valid referenced entry
Classic CoS selects wrong template cosSpecifier value does not match template cn Template DN must be cn=<specifierValue>,<cosTemplateDn>
Physical value shown instead of CoS Default qualifier and stored value present Use override on cosAttribute or remove the stored value
Attribute appears only when explicitly requested operational qualifier on cosAttribute Request the attribute by name or switch qualifiers
Competing values from multiple templates Overlapping definitions without distinct priorities Assign cosPriority on pointer or classic templates; use compatible merge-schemes for multi-valued attributes
Schema error on target modify Generated attribute not allowed by object classes Extend schema or choose an attribute permitted on the entry's classes
Filter on generated attribute returns missing or incorrect entries Indexed virtual attribute Run dsctl INSTANCE healthcheck and fix DSVIRTLE0001; filter on stored specifier fields instead

Summary

  1. Pointer CoS uses one fixed template DN for every entry in the subtree.
  2. Indirect CoS follows a single-valued DN attribute on the target entry to the referenced entry.
  3. Classic CoS selects among multiple templates using cosSpecifier and cosTemplateDn.
  4. cosAttribute qualifiers control whether stored or generated values win.
  5. Test reads, access controls, and search behaviour before relying on CoS in production.

What's Next


References


Frequently Asked Questions

1. What is Class of Service in 389 Directory Server?

Class of Service (CoS) generates virtual attribute values on target entries at read time. A CoS definition entry names the attribute and selection rules; template entries store the values returned to LDAP clients.

2. When should I use pointer CoS instead of classic CoS?

Use pointer CoS when every entry in a subtree should receive the same generated value from one fixed template. Use classic CoS when the value depends on a category attribute stored on each target entry.

3. Can I index a CoS-generated attribute for fast searches?

Do not index a CoS-generated virtual attribute. Directory Server health checks can report this as DSVIRTLE0001, because indexed virtual attributes can cause missing or incorrect search results. Run dsctl <instance_name> healthcheck after configuring or changing indexes.

4. Why can''t I find a CoS-generated attribute with an LDAP filter?

A filter can match a CoS-generated attribute when the attribute is not indexed, but Directory Server must perform an unindexed search, which can be expensive on a large suffix. If the attribute is indexed, entries that receive only a virtual CoS value can be omitted from the results. Prefer filtering on a physically stored selector—for example, (businessCategory=developer) instead of (employeeType=developer) in this lab.

5. Does an indirect CoS referenced entry need the cosTemplate object class?

No. The DN in the indirect specifier can point to an ordinary entry that already contains the attribute you want to reuse, such as a manager entry with departmentNumber.

6. Does CoS replace roles or groups?

No. CoS generates attribute values, groups store membership, and roles calculate the nsRole attribute. A role-based CoS can use nsRole as the specifier in a classic CoS definition.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …