Oracle® Fusion Middleware Administrator's Guide for Oracle Virtual Directory 11g Release 1 (11.1.1) E10046-06 |
|
![]() Previous |
![]() Next |
This chapter describes Oracle Virtual Directory mapping and includes the following topics:
Note: The mapping information in this chapter is included for historical purposes. While existing default mapping scripts are supported, any new customization should be done using the Java plug-in API. This is because the Java API supports full access to all Oracle Virtual Directory functionality and it is also a generally easier environment to develop in. |
Oracle Virtual Directory includes a bidirectional mapping system based on the Python scripting language. A Mapping is a special Python script, file type .mpy, that processes inbound and outbound transactional data flow and allows Oracle Virtual Directory administrators to manipulate and map data as it passes through the Oracle Virtual Directory server. Based on the popular Python scripting language, Oracle Virtual Directory's mapping system enables you to perform complex data manipulation without learning a new, proprietary, or complicated programming language. Oracle Virtual Directory's mapping system provides enterprises with additional flexibility in supporting identity access from applications. Oracle Virtual Directory compiles mappings into executable byte code and runs it inline for maximum performance.
Integrators can develop easy-to-use mapping scripts that perform custom transformations when mapping information from one data source to another. These scripts can be installed on a running server and deployed without resetting the server. A mapping script can adjust requests as they enter the system on the way to data sources and transform responses on the return path to the client. For example, you can use a mapping to normalize schema, such as making Active Directory look like InetOrgPerson; attach data-type, such as {sha} to a hashed password; or create a virtual attribute based on values of attributes retrieved from a data store.
When you create a Mapping you can use a predefined mapping template to simplify its configuration or you can create a new custom mapping (refer to "Understanding Mapping Templates" for more information on mapping templates). Typically, a Mapping is deployed to the Oracle Virtual Directory server as compiled Java code and runs inside a special type of plug-in known as a Mapper. As with Plug-ins, a Mapping may run globally or at an adapter level. Multiple mappings and adapters can be combined as a set of discrete functions performing an overall conversion service. Figure 5-1 shows a typical scenario where one Mapping is running on multiple adapters, while another Mapping is running only on a specific adapter.
Each Mapping has an inbound and outbound flow, allowing it to translate one way as a request is received and reverse that translation as results are returned to the requesting application. This programmatic reversal is important because it is not usually possible for the server to guess intent.
Oracle Virtual Directory provides a lot of flexibility in determining whether a Mapping should be executed globally or within the context of a single adapter. In some situations, you may have to further restrict the locations in the virtual tree where a Mapping is applied. For example, an adapter is set-up to proxy a Microsoft Active Directory domain and points to DC=VAN,DC=Oracle,DC=com. Under that point in the directory tree, there is a CN=Users container and a CN=Groups container. You can add a namespace filter to any Mapping to apply it to only one part of the tree.
The following is a list of notes to consider regarding Oracle Virtual Directory Mappings:
Oracle Virtual Directory mappings make extensive use of the Python language with additional Oracle provided functions for LDAP data manipulation. For more information about Python, refer to the Python Programming Language Official Web site at:
If you rename attributes with Mappings, Oracle Virtual Directory supports search on the renamed attribute/value only if the custom code overrides the incoming filter object, as is in the DB_Groups Mapping. For example:
During outbound processing, a Mapping renames the givenname attribute to cn. During inbound processing, an incoming LDAP search filter, such as cn=John must be converted to givenname=John by the Mapping custom code.
If you deploy a Mapping and then run an ldapsearch command against Oracle Virtual Directory, the search base must be the namespace configured for the Mapping or any child of that namespace.
Most customers who use mappings use default mappings shipped with Oracle Virtual Directory to meet an application requirement. For customization needs, the Java plug-in API is typically used because the Mapper API only handles a subset of Java plug-in functionality and more developers know Java than Python, thus reducing time needed to develop the code.
The following is an overview of the process for deploying Mappings at an adapter level and at a global server level:
Construct the Mapping using Mapping templates, compile it into a script, and deploy it to the Oracle Virtual Directory server so that it can be activated at either the global server level or at the adapter level.
Configure the Mapping at the global server level or at the adapter level by naming it, identifying its Mapping script file, determining the namespaces in the virtual directory tree where you want it to execute, and then activating it.
See:
|
This topic describes each of the Oracle Virtual Directory Mapping templates and includes the following sections:
Maps Microsoft Active Directory user and group objects to the inetOrgPerson and groupOfUniquenames objects (respectively).
Creates a virtual common name attribute by combining values from two attributes, default sn and givenname. The Common_Name_to_Given_Name mapping is typically used with the Database Adapter, which may have only a first and last name, but no full name.
Note: This mapping does not support substring filters for common name attributes. |
Removes the attributes specified if the conditional value in another attribute is met. The ConditionalPublish mapping is useful to hide FERPA protected attributes in a higher education environment.
Use this template to map a table that describes a group into a valid LDAP group. The first column is assumed to be cn, that is, the name of the group. The second column is assumed to be the uniquemember. With uniquemember, the DN is stripped so that only the RDN value is used inside the table. For example, converting: (uniqueMember=cn=XXX,ou=testusers) to (uniqeMember=XXX).
Maps inbound binary syntax passwords to IA5String passwords compatible with the database.
Note: If you associate the Map_DB_Password Mapping with a Database Adapter, then perform an LDAP modify with changetype Add and a binary attribute such as UserPassword with its value already existing in Oracle Virtual Directory, a duplicate row is added in the database if the primary key constraint is not present in the database table. |
This topic provides two examples for common mapping deployments and contains the following sections:
This example explains how to create a common name (cn) from a givenname and a surname (sn). This type of mapping deployment is useful when using a Database Adapter to provide an LDAP interface to a user data stored in a database. While LDAP directories generally store a cn, databases tend to store only a first name and last name. When performing a search, it could become very complicated when filtering on common name. For example, the filter (cn=Marc Boorshtein) would have to read (&(givenName=Marc)(sn=Boorshtein)).
The following is a list of hypothetical requirements for this example mapping:
When data is retrieved from the adapter, you want to form a cn by combining givenname with sn.
On the inbound side, you want to split cn into givenname and sn. If cn is present in the attribute request list, the list is changed to include givenname and sn.
If the inbound operation is a search operation, you want to check the search filter and convert the cn appropriately.
def parceCN(val): return split(val,' ',2) def inbound(): #map the "cn" filters if operation == 'get': if haveAttribute('cn'): addAttribute('givenName') addAttribute('sn') cnFilters = findFilters('cn') for filter in cnFilters: target,op,val = filter.contents givenNameVal, snVal = parceCN(val) givenNameFilter = createFilter('givenName',op,givenNameVal) snFilter = createFilter('sn',op,snVal) filter.contents = createAndFilter([givenNameFilter,snFilter]) def outbound(): #outbound stuff addAttributeValue('cn',getAttributeValue('givenName') + ' ' + getAttributeValue('sn'))
In the inbound()
function you want to convert any cn into separate givenname and sn attributes. For a search, you want to convert search filters for cn into a combined filter for givenname and sn so you create a new function, parceCN()
.
On the first line of the mapping, the split function is imported from the Python string module. The parseCN()
Python function is defined to take a cn and split it into a first and last name based on detecting a space.
Note: In reality, this is more complex, for example, when middle names are used. For the purposes of this example, consider this simple case to get started. Contact your Oracle Support representative for help with advanced mapping situations. |
Next, you define the inbound()
function. The inbound function could deal with any LDAP operation, but in this case, you are interested in looking at search operations. The first line after inbound is therefore an if
block that tests the value of operation. The variable operation contains either add, bind, delete, get, modify, or rename.
If operation = get
, the mapping proceeds by determining if the search request had cn in the attribute request list(). Because cn can only be formed by combining givenname and sn, you must add givenname and sn to the search list using the addAttribute()
function.
To process filter requests for cn, the mapping retrieves all filter elements whose target is the cn attribute(). For each filter, the mapping parses it, calculates the corresponding givenname and sn values by calling parseCN
, and creates new givenName and sn filters. Lastly, the inbound function of the mapping replaces the filter term with cn with a combined filter including the givenName and sn.
The outbound function handles all transactions that are flowing from the adapter to the client. In this example, you want to form a cn from two other values and you use the addAttributeValue
function to create a cn value by combining givenname, a space, and the sn value. Notice how existing values are retrieved using the getAttributeValue
function, which retrieves a specific attribute from the current entry returned to the client.
Frequently applications require the use of an LDAP directory using inetorgperson and groupofuniquenames schema objects. However, many organizations use Microsoft Active Directory which supports only user and group objects. This example mapping deployment illustrates how to use a mapping to make an Active Directory schema look like inetorg style schema using inetorgperson or groupofuniquenames.
The following is a list of the translation and mapping requirements for this example mapping:
Bidirectional mapping of attributes names. For example uniquemember = member
, uid = samaccountname
, and so on.
Conversion of objectclass names. Not only do the basic objectclass names have to change, but you must also consider that Microsoft Active Directory does not use auxiliary objectclasses. For example, objectclass values of interorgperson
, organizationalperson
, or person
must be collapsed to just user
.
Adding special attribute values. Microsoft requires the use of additional object type codes such as groupType
or userAccountControl
. Depending on the operation, special tags must be added to the request.
RDN conversion. Microsoft typically uses cn as the relative distinguished name of user accounts. Many applications expect the use of uid.
Using the following small script, an inetOrg application may use a Microsoft Active Directory:
def inbound(): #first rename the attributes rename({'uniqueMember':'member','uid':'samaccountname','userpassword': 'unicodepwd','ntgrouptype':'grouptype'}) #map nessasary object class values if haveAttributeValue('objectclass','groupifuniquenames'): removeAttributeValue('objectclass','groupofuniquenames') addAttributeValue('objectclass','group') if haveAttributeValue('objectclass','organizationalPerson'): removeAttributeValue('objectclass','organizationalPerson') addAttributeValue('objectclass','user') if haveAttributeValue('objectclass','inetOrgPerson'): removeAttributeValue('objectclass','inetOrgPerson') addAttributeValue('objectclass','user') #when adding an entry, certain values need to be added if operation == 'add': if haveAttributeValue('objectClass','group'): addAttributeValue('groupType','-2147483646') if not haveAttribute('samaccountname'): copy('cn','samaccountname') if haveAttributeValue('objectClass','user'): addAttributeValue('userAccountControl','66048') #collapse aux classes removeAttributeValue('objectClass','person') removeAttributeValue('objectClass','organizationalPerson') #set the rdn setRDN('samaccountname','cn') def outbound(): #first rename the attributes rename({'member':'uniqueMember','samaccountname':'uid','unicodepwd': 'userpassword','grouptype':'ntgrouptype'}) #map nessasary object class values if haveAttributeValue('objectclass','group'): removeAttributeValue('objectclass','group') addAttributeValue('objectclass','groupofuniquenames') if haveAttributeValue('objectclass','user'): removeAttributeValue('objectclass','user') addAttributeValue('objectclass','organizationalPerson')
The first line of the inbound()
function renames all inetorg attributes to Active Directory attributes. The rename function is called for all operations. For example, if the operation is a search, then all requested attributes and all attributes in the filter are renamed. If the operation is an add or modify, then all attributes effected are renamed.
The second section of the inbound function replaces inetOrg object classes with InetAD object classes. Notice that you can use conditional statements to determine what actions should be performed.
The third section of the inbound function checks to see if the operation is an add, and if so, it adds the specific attribute information required by Active Directory.
In the fourth section of the inbound function all auxiliary object classes are removed because Active Directory does not allow for an auxiliary object class to be directly specified during an add.
In the last section of the inbound function the RDN is changed from uid to cn. Notice that the code converts samaccountname
to cn
because uid
was already renamed to samaccountname
. This does more than just change the rdn from a uid to cn, but it deals with locating the cn if it is not specified (for example, in a modify or a search).
The outbound()
function executes after a response is returned from Active Directory. The outbound()
function reverses the inbound function by first renaming all applicable attributes, then mapping the object class names, and then changing the rdn of any results.
Oracle Virtual Directory Mappings are based on the Python language and can use any functions or subroutines available in Python. In addition to the Python functions supported by Oracle Virtual Directory, Oracle provides the library functions described in the following sections:
The following is a list of the methods available for Oracle Virtual Directory Mappings in addition to those of the Python language:
Note: Methods specifyingMap xxxxx indicates that you can specify a list of values in the form:
{'uniqueMember':'member','uid':'samaccountname',[…] } This is essentially an array of one or more mapped values. Use this construct for those methods that support it when a particular method is to be used multiple times for different named pair relationships (for example, |
operations: add, modify, get, entry
The appendAttribute
function adds the values of the source attribute to the destination attribute. The source attribute remains in place. This function effects a search filter.
Example: appendAttribute('sn','givenName') add/entry: dn: cn=User objectClass: person cn: User givenName: User sn: name becomes: dn: cn=User objectClass: person cn: User givenName: User givenName: name sn: name modify: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First becomes: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First givenName: Last get: (&(givenName=first)(sn=last)) becomes: (&(|(sn=last)(givenName=last))(givenName=first))
operations: add, modify, get, entry
The copyAttribute
function copies attribute values from the source attribute to the destination attribute, overwriting the destination attribute if it already exists.
Example: copyAttribute('sn','givenName') add/entry: dn: cn=User objectClass: person cn: User givenName: User sn: name becomes: dn: cn=User objectClass: person cn: User givenName: User givenName: name sn: name modify: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First becomes: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First givenName: Last get: (&(givenName=first)(sn=last)) becomes: (|(sn=last)(givenName=last))
operations: add, modify, get, entry
Renames the source attribute to the destination attribute. If the destination attribute already exists, it is overwritten. If the source attribute does not exist, but the destination attribute does, the destination attribute is removed.
Example: renameAttribute('sn','givenName') add/entry: dn: cn=User objectClass: person cn: User givenName: User sn: name becomes: dn: cn=User objectClass: person cn: User givenName: name modify: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First becomes: dn: cn=User changetype: modify add: givenName givenName: Last get: (&(givenName=first)(sn=last)) becomes: (givenName=last)
operations: add, modify, get, entry
Removes the named attribute, returning its values in a list. If the attribute is a part of an entry, the values are returned. If the value is part of a changelist, the EntryChange object is returned.
Example: removeAttribute('sn') add/entry: dn: cn=User objectClass: person cn: User givenName: User sn: name becomes: dn: cn=User objectClass: person cn: User givenName: User modify: dn: cn=User changetype: modify add: sn sn: Last - add: givenName givenName: First becomes: dn: cn=User changetype: modify add: givenName givenName: First givenName: Last get: (&(givenName=first)(sn=last)) becomes: (givenName=last)
operations: add, modify, entry, get
Example: revalueAttribute('sn','name','newname') add/entry: dn: cn=User objectClass: person cn: User givenName: User sn: name becomes: dn: cn=User objectClass: person cn: User givenName: User sn: newname modify: dn: cn=User changetype: modify add: sn sn: name - add: givenName givenName: First becomes: dn: cn=User changetype: modify add: sn sn: newname - add: givenName givenName: First givenName: Last get: (&(givenName=first)(sn=name)) becomes: (&(givenName=last)(sn=newname))
operations: add, modify, entry
Maps a syntax value to a new syntax. If the first argument is a Syntax
object, the function returns an instance of Syntax
as named by newSyntax
. Valid syntaxes are: DirectoryString, IA5String, BinarySyntax, and BinarySyntax.
operations: add, modify, entry
Maps an attribute value to a new syntax. If the first argument is the name of an attribute, all instances of that attribute are mapped to the new syntax. Valid syntaxes are: DirectoryString, IA5String, BinarySyntax, and BinarySyntax.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
parseFunction: An optional parameter that identifies the function for parsing data if a parsing rule different than space is needed.
index: For multi-valued attributes, this parameter identifies which value to split.
remove: If true (1), the original data from the autoboot in the result is removed and source is left alone.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
parseFunction: An optional parameter that identifies the function for parsing data if a parsing rule different than space is needed.
index: For multi-valued attributes, this parameter identifies which value to split.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
parseFunction: An optional parameter that identifies the function for parsing data if a parsing rule different than space is needed.
remove: If true (1), the original data from the autoboot in the result is removed and source is left alone.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
parseFunction: An optional parameter that identifies the function for parsing data if a parsing rule different than space is needed.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
index: For multi-valued attributes, this parameter identifies which value to split.
remove: If true (1), the original data from the autoboot in the result is removed and source is left alone.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
index: For multi-valued attributes, this parameter identifies which value to split.
Splits the existing values in an attribute and the result of the split is added to the listed attributes in the newNames
parameter. An example of when the splitValue functions are useful is if you encounter an adapter that only has cn values but you want to create givenname and sn values from the cn value. By default, the first value found is taken if the attribute is multi-valued, the split is based on space, and the initial values are left alone. The following is a list and explanation for the parameters for this method:
newNames: An array of attributes that are created from the split values.
currentName: The existing attribute to create the value from.
remove: If true (1), the original data from the autoboot in the result is removed and source is left alone.
operations: add, modify, entry
Example: splitValue(['givenName','sn','cn',1) add/entry: dn: uid=User objectClass: person cn: First Last uid: User becomes: dn: uid=User objectClass: person givenName: First sn: Last uid: User modify: dn: uid=User changeType: modify replace: cn cn: First1 Last1 becomes: dn: uid=User changeType: modify replace: givenName givenName: First1 - replace: sn sn: :Last1 get: (cn=First Last) becomes: (&(givenName=First)(sn=last))
operations: add, modify, entry
Adds a value to the names attribute, or creates it if it does not exist. For modify, if the attribute does not exist, then an Add
modification item is created.
Example: addAttributeValue('myattrib','myval') Example: addAttributeValue('noattrib','hasvalue') add/entry: dn: uid=User objectClass: person cn: First Last uid: User myattrib: noval becomes: dn: uid=User objectClass: person givenName: First sn: Last uid: User myattrib: noval myattrib: myval noattrib: hasValue modify: dn: uid=User changeType: modify delete: myattrib myattrib: someval becomes: dn: uid=User changeType: modify delete: myattrib myattrib: someval myattrib: myval - changetype: add add: noattrib noattrib: hasValue
operations: add, modify, entry, get
Returns 1 (true) or 0 (false) if the named attribute exists.
operations: add, modify, entry, get
Returns 1 (true) or 0 (false) if the named attribute exists. If fetchFromServer
is 1, then the entry is fetched from the server.
operations: add, modify, entry, get
Returns 1 (true) or 0 (false) if the named attribute and associated value exists.
operations: add, modify, entry, get
Returns 1 (true) or 0 (false) if the named attribute and associated value exists. If fetchFromServer
is 1, then the entry is retrieved from the server for comparison.
operations: add, modify, get, entry
Removes an attribute value, returning true if the value was removed.
Example: removeAttributeValue('myattribute','myvalue') add/entry: dn: cn=user objectClass: person cn: user myattribute: myvalue myattribute: myvalue2 becomes: dn: cn=user objectClass: person cn: user myattribute: myvalue2 modify: dn: cn=User changetype: modify replace: myattribute myattribute: myvalue - add: sn sn: last becomes: dn: cn=User changetype: modify add: sn sn: last get: (&(sn=last)(myattribute=myvalue)) becomes: (sn=last)
operations: add, modify, delete, bind, rename, entry
Changes the RDN of the current name (base for get) from the old RDN to a new RDN attribute.
Example: setRDN('cn','uid') add/entry: dn: cn=user objectClass: inetOrgPerson uid: userid cn: user becomes: dn: uid=userid cn: user objectClass: inetOrgPerson modify: dn: cn=user changetype: modify add: sn sn: last becomes: dn: uid=userid changetype: modify add: sn sn: last bind/get/delete: dn: cn=user becomes: dn: uid=userid
operations: get
Adds an attribute to the return attribute list during a search.
operations: get
Returns a list of all filters that involve the specified attribute.
operations: get
Creates a new filter object, where the target is the attribute being tested, the operation is one possible comparator, and value is the value on which to filter.
operations: get
Creates an and filter from a list of filters
operations: get
Creates an or filter from a list of filters
operations: add, entry
Returns the first value of the named attribute
operations: any
Retrieves that values of the named attribute from the supplied entry.
operations: modify
Creates and returns a new EntryChange
object.
operations: modify
Adds en
entry change to the list of entry changes.
operations: any
Returns the named entry.
operations: add, modify, entry, get
Replaces the oldBase
with the newBase
for the values of the named attribute.
operations: add,modify,get,entry
Removes an attribute and returns its values if it exists (or EntryChange's if it is during a modify operation).
Example: removeAttributeValue('myattribute') add/entry: dn: cn=user objectClass: person cn: user myattribute: myvalue myattribute: myvalue2 becomes: dn: cn=user objectClass: person cn: user modify: dn: cn=User changetype: modify replace: myattribute myattribute: myvalue - add: sn sn: last becomes: dn: cn=User changetype: modify add: sn sn: last get: (&(sn=last)(myattribute=myvalue)) becomes: (sn=last)
Data objects are variables that are made available from Oracle Virtual Directory to you in the Python environment. Use these variables to get handles to Oracle Virtual Directory data structures and to interpret various objects and status items.
The current operation. Possible values are: add, modify, delete, rename, get, entry, and bind.
Retrieve a handle to Virtual Services Interface (VSI).
Attributes requested to be returned. Operations: get
The current search base. Operations: get
Returns and sets the filter in the form of a tuple (target, operation, value).
Returns TRUE if filter is an AND filter.
Returns TRUE if filter is an OR filter.
Returns TRUE if filter is a NOT filter.
Set of changes for a modify operation. Operations: modify
The current credentials (DN) of the user. Operations: All
The entry to be added or returned from a search. Operations: get, add
The current search filter. Operations: get
The entry to be added, bound, modified or deleted. Available for all operations.
Retrieve a Value(s): val = request([String name])
Store a Value(s): request(['myname'])='myvalue'
Returns and sets the current request information object attribute specified. This object is used as a method for passing arbitrary information between different mappings or plug-ins that exist for the duration of a specific transaction. For example, during an inbound operation, you can store information that can be used for processing later during the outbound request.
Returns and sets result code if an error occurs. Operations: add, delete, modify
The current search scope in the form of 0 (base), 1 (onelevel), or 2 (subtree). Operations: get
Whether the server is returning only types and not values. Operations: get