1.1 Context Handles

Most eDirectory functions have a context handle as the first parameter. A context handle is similar to a directory handle in that it points to a specific location, but it is different in that a directory handle points to a location in the file system and a context handle points to a location in the eDirectory tree. As with directory handles, applications can have multiple context handles.

A context handle knows its location in the eDirectory tree by maintaining the distinguished name of the location. In addition to the context name, the context handle maintains the following types of information:

This section describes the following aspects of context handles:

For step-by-step instructions, see

For sample code, see ndscontx.c.

1.1.1 Management of Context Handles

The following functions are used to manage context handles.

Function

Description

NWDSCreateContextHandle

Creates a context handle and initializes it with default values.

NWDSDuplicateContextHandle

Creates a copy of an existing context handle and initializes it with the values of the existing handle.

NWDSFreeContext

Frees a previously allocated context handle.

When a context handle is created, it is initialized to the following default values:

  • DCK_FLAGS (DCV_DEREF_ALIASES | DCV_XLATE_STRINGS | DCV_CANONICALIZE_NAMES). With these values, the eDirectory libraries dereference aliases, translate Unicode strings to the local code page, and append the name context to the object names. The libraries expect applications to submit partial names, relative to the name context, and in the character set of the local code page. The libraries return partial names, with the name context stripped off, and in the character set of the local code page.

  • DCV_NAME_CONTEXT. For workstation applications, the name context is the default eDirectory context used during login. For NLMs, this is the server's bindery context. If multiple contexts are listed, it is the first context in the list.

  • DCK_CONFIDENCE (DCV_LOW_CONF). The default value allows information to be obtained from all replica types (read-only, read-write, and master).

  • DCK_LAST_CONNECTION. This key is initialized to no connection (-1).

  • DCK TREE NAME. For workstation applications, this is the preferred tree of the workstation. For NLMs, this is the tree the server belongs to.

  • DCK_DSI_FLAGS (DSI_ENTRY_FLAGS | DSI_OUTPUT_FIELDS | DSI_SUBORDINATE_COUNT | DSI_MODIFICATION_TIME | DSI_BASE_CLASS | DSI_ENTRY_RDN | DSI_ENTRY_DN). This key determines the type of entry information that can be obtained about an object. The default value returns information about the type of object (for example, alias, partition, or container object), the number of objects subordinate to the specified object, the object's modification timestamp, the base class of the object, the name of the object (default format is partial name with partial dot form), and the distinguished name of the object (default format is partial dot form).

  • DCK_NAME_FORM (DCV_NF_PARTIAL_DOT). This key specifies the name form; the default is partial dot.

  • Name cache depth. This key specifies how many names will be stored in memory. The default is five.

These settings determine the format of the name that the eDirectory libraries expect eDirectory functions to use and the format of the name the functions return to the application.

For example, suppose a workstation logs in to the eDirectory tree with a default name context of “Clerks.Accouting.ACME” and a username of “JRoss.” With these default settings, the libraries would append “Clerks.Accouting.ACME” to any object name passed as a parameter in an eDirectory function.

If an “HPPrinter” object exists in a “Printer” container under “Clerks,” the function should use “HPPrinter.Printer” for the printer's name. A dot should be the delimiter because that is the default name form.

The following graphic illustrates how these keys interact with their flags, bit masks, or keys.

Figure 1-1 Context Keys Interacting with Flags, bit Masks, and Keys

Since all of these keys can be modified, the next section describes the functions that you use to manage the context handle settings.

1.1.2 Modification of Context Handle Settings

The following functions are used to modify the context handle keys and to obtain information about the context handle and its settings.

NWDSGetContext

Reads the information about the context.

NWDSSetContext

Modifies the information maintained by the context handle.

To read the context handle settings or to modify them, you need to understand the context keys. They are described in greater detail in the following sections.

1.1.3 DCK_FLAGS Key

The DCK_FLAGS key holds a bit mask of flags that can be ORed together. Each flag affects how the eDirectory libraries return object name information.

DCV_DEREF_ALIASES. This flag determines whether an object name, which references an alias, returns information about the alias object or the object that it references. The default is to return information about the referenced object. However, if your application needs to read the values of the alias's attributes, then this flag needs to be turned off (set to 0).

In search and list operations, this flag determines whether the object, that is submitted as the start point for the search, can be dereferenced. For example, the eDirectory tree in the figure below has an alias object, Eng Alias, that references the Engineering container.

Figure 1-2 DCV_DEREF_ALIASES Flag

If Eng Alias is submitted as the object for the start of the search or list, it will be dereferenced and return information about the Engineering container and its subordinate objects.

For search functions, another parameter, usually called searchAliases, determines whether subordinate objects are dereferenced.

DCV_XLATE_STRINGS. This flag determines the types of strings the eDirectory libraries return and expect to receive. Natively, eDirectory works in Unicode. However, if this flag is on (set to 1), the libraries expect strings in the local code page and translate between Unicode and the local code page.

If this flag is turned off (set to 0), the libraries do not translate and expect Unicode strings. This can improve performance.

DCV_TYPELESS_NAMES. This flag determines whether the libraries return names in typeless (JRoss.HR.ACME) or typeful (CN=JRoss.OU=HR.O=ACME) format. When this flag is off (which is the default value), the libraries return typeful names. You can either set this flag to the way you want to display eDirectory names to your user, or you can use name functions to modify the name before displaying it.

The following functions manipulate the form of the name.

NWDSAbbreviateName

Converts a name to its shortest, typeless form relative to a specified name context.

NWDSCanonicalizeName

Converts an abbreviated name to the canonical form (fully distinguished, with types).

NWDSRemoveAllTypes

Removes all attribute types from a distinguished name.

Be aware that the NWDSCanonicalizeName function adds types to the name if the DCV_TYPELESS_NAME flag is off. To add types, it must use the default typing rule that makes some assumptions about the containers in the eDirectory tree. When applying types, the libraries make the following assignments:

  • The most significant (right-most) component is an Organization (O).

  • The least significant (left-most) component is a Common Name (CN).

  • All intervening components are Organizational Units (OU).

For example, if you pass in a name such as “JRoss” with a name context of “Engineering.ACME” to the NWDSCanonicalizeName function, the function returns “CN=JRoss.OU=Engineering.O=ACME”. The library does not know the correct types to apply to the container names and cannot look them up; it simply follows the default typing rules.

If the eDirectory tree contains Tree Root, Country, or Locality containers, the types will be inaccurate. To have the server resolve a typeless name and return a correctly typed distinguished name, use the NWDSReadObjectDSIInfo function and set the DSI flags to return only the distinguished name.

DCV_CANONICALIZE_NAMES. A name in canonical form is a name that is fully distinguished; it can have types, but it isn't required to. eDirectory does all of its name processing with fully distinguished names.

When this flag is clear, the libraries expect input of fully distinguished names and return fully distinguished names. When this flag is set, the libraries expect input of partial names and append the name context to the partial name to create a distinguished name. On return values, the libraries strip off the name context and return partial names. For example:

Name passed in:

JRoss

Current Context:

HR.ACME

Resulting Name:

JRoss.HR.ACME

The libraries use the following rules when determining how to expand a name:

  • A period preceding a name prevents the libraries from appending the context to the name. The libraries assume that such a name is a distinguished name.

  • For each trailing period, the libraries remove one component from the name context before appending it to the name.

If you place a period at the beginning of the name passed in, the libraries treat it as a distinguished name and do not append the context to the end. Here is an example:

Name passed in:

.Ppearson.Engineering.Pub.ACME

Current Context:

Payroll.HR.Pub.ACME

Resulting Name:

Ppearson.Engineering.Pub.ACME

For each period you place at the end of a name, the libraries remove a naming component from the context before appending the context to the name you passed in. For example:

Name passed in:

Ppearson.Engineering..

Current Context:

Payroll.HR.Pub.ACME

Resulting Name:

Ppearson.Engineering.Pub.ACME

Note that in the two examples the same person is being referenced and both examples use the same context. Also note that in the first example the name passed in was 30 characters and the second name passed in was only 22 characters. Both examples resulted in the same name, but they used different rules to achieve that name.

DCV_DEREF_BASE_CLASS. This flag allows eDirectory to return the base class of the object the alias references. When this flag is turned off, eDirectory returns the base class of the alias, which is always the Alias class.

DCV_DISALLOW_REFERRALS. This flag allows eDirectory to refer a request to another server and the request will follow such referrals until the information is found. If this flag is turned on, the request must be answered by the first eDirectory agent it is sent to. If this agent does not have a replica with the information, the request fails.

1.1.4 DCK_CONFIDENCE Key

The DCK_CONFIDENCE key determines where the libraries can obtain eDirectory information. Most of the time, eDirectory information can be obtained from any type of replica. However, a few operations, especially partition operations, must be performed on the master replica. You can force eDirectory to obtain information from the master replica by setting the DCK_CONFIDENCE key to DCV_HIGH_CONF. Since eDirectory cannot use the first replica that it finds, requesting information to come only from master replicas can slow down performance.

1.1.5 DCK_NAME_CONTEXT Key

This key determines the NDS context that is added to partial names to make them distinguished names when the DCV_CANONICALIZE_NAME flag is set. If your application changes context, you need to set this key to the new context.

1.1.6 DCK_LAST_CONNECTION Key

This key contains the connection that was last used to service an eDirectory request. Since an eDirectory request can require connections to a server other than the server that first receives the request, this value changes during the processing of the request.

1.1.7 DCK_TREE_NAME Key

This key contains the name of the eDirectory tree. If your application allows logins to multiple trees, you should create a context handle for each tree and set this key to that tree's name.

1.1.8 DCK_DSI_FLAGS Key

The DCK_DSI_FLAGS key is a bit mask that determines what entry information is returned about objects. Some information types, such as DSI_CREATION_TIMESTAMP or DSI_PARENT ID, apply to all object types, but some are particular to an object type, such as DSI_REPLICA_TYPE, which applies only to Partition objects. Each of these DSI flags are described in the following sections.

DSI_OUTPUT_FIELDS. This flag determines what is returned. It is a bit mask of all the other DSI flags. Only those flags ORed into the bit mask have information returned. The information is returned in the same order that flags were ORed together.

Not all versions of eDirectory can supply the requested information. If the request goes to an eDirectory server that cannot supply the information, the server clears the corresponding bit in the DSI_OUTPUT_FIELDS flag.

Before attempting to read DSI information, you should always read the DSI_OUTPUT_FIELDS flag to determine what was actually returned.

DSI_ENTRY_ID. This flag returns the entry ID of the object. All objects in the server's local eDirectory database have an entry ID that is specific to that database.

DSI_ENTRY_FLAGS. This flag returns information about the state of entry. These identify significant characteristics about the entry, such as whether the entry is an alias object, a partition root, a container, a container alias, or an audited entry. All that apply to the entry are ORed together. For a complete list, see Section 5.12, DSI_ENTRY_FLAGS Values.

DSI_MODIFICATION_TIME. This flag returns the time of the last modification to the entry. The time is returned as the number of seconds since 12:00 midnight, 1 January 1970. If the modification time is unknown, returns 0.

DSI_MODIFICATION_TIMESTAMP. This flag returns the timestamp of the last modification of the entry. A timestamp includes the number of seconds since 12:00 midnight, 1 January 1970 as well as the replica number where the modification took place and the eDirectory event type that identifies the type of modification. If the timestamp is unknown, it returns 0.

DSI_REVISION_COUNT. This flag returns the number of times the entry has been modified.

DSI_CREATION_TIMESTAMP. This flag returns the timestamp that indicates when the entry was created. The timestamp includes the number of seconds since 12:00 midnight, 1 January 1970 as well as the replica number where the creation occurred and an eDirectory event type that indicates that this is a creation event. If the creation timestamp is unknown, it returns 0.

DSI_BASE_CLASS. This flag returns the base class, or object class, that was used to create the entry. Although Object Class is an attribute of every class and the eDirectory libraries include functions to read attribute information, this flag can be used to obtain base class information without the overhead of a special request to read the Object Class attribute.

DSI_ENTRY_RDN. This flag returns the partial name of the entry, in the format specified by the DCK_FLAGS and the DCK_NAME_FORM keys. The default values for these keys would return the name of the entry with the name context stripped, in dot form, and without types.

DSI_ENTRY_DN. This flag returns the distinguished name of the entry in the format specified by the DCK_FLAGS and DCK_NAME_FORM keys. The default value for these keys would return the name in dot form and without types.

DSI_PARENT_ID. This flag returns the entry ID of the entry's parent object.

DSI_PARENT_DN. This flag returns the distinguished name of the entry's parent object in the format specified by the DCK_FLAGS and DCK_NAME_FORM keys. The default value for these keys would return the name in dot form and without types.

DSI_DEREFERENCE_BASE_CLASS. This flag returns the base class of the object an alias references if the DCV_DEREF_BASE_CLASS flag is set. If this flag is not set, it returns the base class of the Alias entry, which is always the Alias object class.

DSI_SUBORDINATE_COUNT This flag returns the number of objects that are subordinate to the entry. If this number is unknown, it returns 0.

DSI_PARTITION_ROOT_ID. This flag returns the entry ID of the partitions' root container.

DSI_PARTITION_ROOT_DN. This flag returns the distinguished name of the partition's root container in the format specified by the DCK_FLAGS and DCK_NAME_FORM keys. The default value for these keys would return the name in dot form and without types.

DSI_PURGE_TIME. This flag returns the oldest purge time for a Partition object. The time is the number of seconds since 12:00 midnight, 1 January 1970.

DSI_REPLICA_TYPE. This flag returns the replica's type. See Section 5.23, Replica Types for a list.

DSI_REPLICA_NUMBER. This flag returns the number the replica was assigned when it was created. This number is unique among the replicas of the partition and is used to identify the replica where an eDirectory event occurred.

DSI_REPLICA_STATE. This flag returns the current state of the replica. See Section 5.24, Replica States for a list.

1.1.9 DCK_NAME_FORM Key

The eDirectory libraries support two name forms: partial dots and slashes. The partial dot form uses dots as delimiters, with the root-most object at the right, and does not include the tree name. For example, the following name uses the default, partial dot form:

     JRoss.HR.ACME
  

The slash form uses back slashes as delimiters, with the root-most object at the left, and includes the tree name. For example, the same name in the XYZ_tree could be displayed as

     \XYZ_tree\ACME\HR\JRoss
  

The DCK_NAME_FORM key determines the input and output form for the eDirectory libraries:

  • If slash form is turned on, names are always returned as fully distinguished and must be entered as fully distinguished. Since slash form names are always distinguished, the libraries ignore the setting of the DCV_CANONICALIZE_NAMES flag.

  • If partial dot form is turned on, names can be either partial or fully distinguished, depending on the setting of the DCV_CANONICALIZE_NAMES flag. If this flag is turned on, partial names can be entered.

The following figure summarizes the interaction of the DCK_NAME_FORM key with the DCV_CANNOICALIZE_NAMES flag and the DCV_TYPELESS_NAMES flag.

Figure 1-3 The DCK_NAME_FORM Key Interacts with the DCV_CANNOICALIZE_NAMES Flag and the DCV_TYPLESS_NAMES Flag

This key also affects a number of the DSI flags that specify the return of the object's RDN, the object's DN, the DN of the object's parent, and the DN of the partition root.

1.1.10 DCK_NAME_CACHE_DEPTH Key

Name caching is a feature that allows a context handle to store a specified number of names in memory. This enhancement was made to increase performance of the resolve name operations. When the cache is full, the oldest name is dropped to add a new name.

To clear the name cache, set the depth of the cache to zero by calling NWDSSetContext (context, DCK_NAME_CACHE_DEPTH, &0). To reinitialize name cache, set the cache depth to the desired value by calling NWDSSetContext (context, DCK_NAME_CACHE_DEPTH, &5) again.

Currently, the default depth of the name cache is five. To set the depth to a lower value than the current setting, you must clear the cache and then set it to the desired depth.

1.1.11 Multi-Threaded Applications

Context handles are designed to enable the NWDS functions to operate correctly in a multi-threaded application. The library stores persistent state information for eDirectory operations in the context handle. As a result, the functions are thread-safe as long as threads do not share context handles. If an application shares context handles among threads, the application is responsible for providing proper concurrency locks for shared resource.