Plug-in Programmer’s Guide Red Hat Directory Server |
Previous |
Contents |
Index |
Next |
Chapter 7
Defining Functions for LDAP Operations
This chapter explains how to write pre-operation and post-operation functions for specific LDAP operations. In general, the functions outlined here use a parameter block to pass information between the plug-in and the Red Hat Directory Server (Directory Server). Because of this, these plug-in functions will pass a single argument, a parameter block defined by the data type Slapi_PBlock. For more information on this, see "Passing Data with Parameter Blocks," on page 38.
This chapter outlines how to define plug-in functions to do the following:
- Specifying Start and Close Functions (page 86)
- Processing an LDAP Bind Operation (page 86)
- Processing an LDAP Unbind Operation (page 87)
- Processing an LDAP Search Operation (page 88)
- Processing an LDAP Compare Operation (page 92)
- Processing an LDAP Add Operation (page 92)
- Processing an LDAP Modify Operation (page 94)
- Processing an LDAP Modify RDN Operation (page 95)
- Processing an LDAP Delete Operation (page 97)
- Processing an LDAP Abandon Operation (page 97)
Specifying Start and Close Functions
For each pre-operation and post-operation plug-in, you can specify the name of a function to be called after the server starts and before the server is shut down.
Use the following parameters to specify these functions:
SLAPI_PLUGIN_START_FN Specifies the function called after the Directory Server starts up. SLAPI_PLUGIN_CLOSE_FN Specifies the function called before the Directory Server shuts down.
If you register multiple plug-ins with different start and close functions, the functions are called in the order that the plug-ins are registered (in other words, in the order that the plugin directives appear in the server configuration file).
Processing an LDAP Bind Operation
When the Directory Server receives an LDAP bind request from a client, the front-end determines the DN as which the client is attempting to bind and the authentication method being used. The front-end also gets the credentials used for authentication and, if SASL is used for authentication, the SASL mechanism used.
Defining Functions for the Bind Operation
In the parameter block, the following parameters specify plug-in functions that are called in the process of executing a bind operation:
- The SLAPI_PLUGIN_PRE_BIND_FN parameter specifies the pre-operation bind function.
- The SLAPI_PLUGIN_POST_BIND_FN parameter specifies the post-operation bind function.
You register your plug-in functions by calling slapi_pblock_set() to set these parameters in your initialization function. (For details, see "Registering Your Plug-in Functions," on page 44.)
Your pre-operation and post-operation bind functions should return 0 if successful. If the pre-operation function returns a non-zero value, the post-operation bind function is never called.
For information on defining a function that handles authentication, see Chapter 8, "Defining Functions for Authentication."
Getting and Setting Parameters for the Bind Operation
The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
Parameter ID Data Type Description SLAPI_BIND_TARGET char * DN of the entry as which to bind. SLAPI_BIND_METHOD int Authentication method used; for example, LDAP_AUTH_SIMPLE or LDAP_AUTH_SASL. SLAPI_BIND_CREDENTIALS struct berval * Credentials from the bind request. SLAPI_BIND_RET_SASLCREDS struct berval * Credentials that you want sent back to the client. Set this before calling slapi_send_ldap_result(). SLAPI_BIND_SASLMECHANISM char * SASL mechanism used; for example, LDAP_SASL_EXTERNAL.
If the SLAPI_BIND_SASLMECHANISM parameter is empty, simple authentication was used, and simple credentials were provided.
Processing an LDAP Unbind Operation
When the Directory Server receives an LDAP unbind request from a client, the front-end calls the unbind function for each backend. No operation-specific parameters are placed in the parameter block that is passed to the unbind function.
In the parameter block, the following parameters specify plug-in functions that are called in the process of executing an unbind operation:
- The SLAPI_PLUGIN_PRE_UNBIND_FN parameter specifies the pre-operation unbind function.
- The SLAPI_PLUGIN_POST_UNBIND_FN parameter specifies the post-operation unbind function.
You set these parameters to the names of your functions by calling slapi_pblock_set().
Your plug-in functions should return 0 if successful. If the pre-operation function returns a non-zero value, the post-operation unbind function is never called.
Processing an LDAP Search Operation
The server processes an LDAP search operation in two stages:
- For example, for a search filter that finds entries where mail=a*, the server checks the index for the mail attribute (if the index exists), finds the keys that start with a, and generates a list of matching entries.
- If no applicable index exists, all entries are considered to be candidates.
- To get the list of candidates, the server calls the backend search function. For details, see "Getting the List of Candidates," on page 89.
- Next, the server iterates through each candidate in the list and determines if the candidate matches the search criteria.
- If an entry matches the criteria, the server sends the entry to the client.
- To check each candidate, the server calls the backend next candidate function for each candidate in the list. For details, see "Iterating through Candidates," on page 91.
The rest of this section explains these stages in more detail.
Getting the List of Candidates
When the Directory Server receives an LDAP search request, the front-end gets information about the search (such as the scope and base DN). The front-end normalizes the base DN by calling the slapi_dn_normalize() function and determines if the base DN identifies a DSA-specific entry (DSE). If so, the front-end handles the search request directly and does not pass it to the backend search function.
If the base DN is not a DSE, the front-end finds the backend that services the suffix specified in the base DN. The front-end then passes the search criteria to the search function for that backend.
The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
Your search function should return 0 if successful. Call the slapi_pblock_set() function to assign the set of search results to the SLAPI_SEARCH_RESULT_SET parameter in the parameter block.
The front-end then uses this function in conjunction with the "next entry" function (see "Iterating through Candidates," on page 91) to iterate through the result set. The front-end sends each result back to the client and continues updates the SLAPI_NENTRIES parameter with the current number of entries sent back to the client.
If a result is actually a referral, the front-end sends the referral back to the client and updates the SLAPI_SEARCH_REFERRALS parameter with the list of referral URLs.
Finally, after sending the last entry to the client, the front-end sends an LDAP result message specifying the number of entries found.
Iterating through Candidates
In addition to the parameters specified in "Processing an LDAP Search Operation," on page 88, the next entry function has access to the following parameters (which are set by the front-end and the backend during the course of executing a search operation):
The next entry function should get the next result specified in the set of results in the parameter SLAPI_SEARCH_RESULT_SET. The function should set this next entry as the value of the SLAPI_SEARCH_RESULT_ENTRY parameter in the parameter block, and the "next entry" function should return 0 if successful.
The next entry function should set the SLAPI_SEARCH_RESULT_ENTRY parameter to NULL and return -1 if one of the following situations occurs:
- The operation is abandoned (you can check this by calling the slapi_op_abandoned() function).
- The time limit has been exceeded.
- The maximum number of entries has been exceeded.
If no more entries exist in the set of results, the next entry function should set the SLAPI_SEARCH_RESULT_ENTRY parameter to NULL and return 0.
Processing an LDAP Compare Operation
When the Directory Server receives an LDAP compare request from a client, the front-end gets the DN of the entry being compared and the attribute and value being used in the comparison.
The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
The compare function should call slapi_send_ldap_result() to send LDAP_COMPARE_TRUE if the specified value is equal to the value of the entry's attribute or LDAP_COMPARE_FALSE if the values are not equal.
If successful, the compare function should return 0. If an error occurs (for example, if the specified attribute doesn't exist), the compare function should call slapi_send_ldap_result() to send an LDAP error code and should return 1.
Processing an LDAP Add Operation
When the Directory Server receives an LDAP add request from a client, the front-end normalizes the DN of the new entry. The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
Parameter ID Data Type Description SLAPI_ADD_TARGET char * DN of the entry to be added. SLAPI_ADD_ENTRY Slapi_Entry * The entry to be added (specified as the opaque Slapi_Entry datatype).
The add function should check the following:
- If the operation has been abandoned, the function should return -1. (You do not need to call slapi_send_ldap_result() to send an LDAP error code to the client. According to the LDAP protocol, the client does not expect a server response after an operation is abandoned.)
- If the entry already exists in the database, the function should call slapi_send_ldap_result() to send an LDAP error code LDAP_ALREADY_EXISTS and should return -1.
- If the parent entry (or the closest matching entry) is a referral entry (an entry with the object class ref) and no manageDSAIT control is included with the request, the function should call slapi_str2filter() to send a referral and return -1.
- To determine if a manageDSAIT control is present, call slapi_pblock_get() to get the value of the SLAPI_MANAGEDSAIT parameter. If the value is 1, the control is included in the request. If 0, the control is not included in the request.
- If the parent entry does not exist, the function should call slapi_send_ldap_result() to send an LDAP error code LDAP_NO_SUCH_OBJECT and return -1.
- If the entry is not schema-compliant (call slapi_entry_schema_check() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_OBJECT_CLASS_VIOLATION and should return -1.
- If the requestor does not have permission to add the entry (call slapi_access_allowed() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_INSUFFICIENT_ACCESS and should return -1.
- You should also verify that the ACI syntax for the entry is correct; call slapi_acl_check_mods() to determine this.
If the add function is successful, the function should call slapi_send_ldap_result() to send an LDAP_SUCCESS code back to the client and should return 0.
Processing an LDAP Modify Operation
When the Directory Server receives an LDAP modify request from a client, the front-end gets the DN of the entry to be modified and the modifications to be made. The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
The modify function should check the following:
- If the operation has been abandoned, the function should return -1. (You do not need to call slapi_send_ldap_result() to send an LDAP error code to the client. According to the LDAP protocol, the client does not expect a server response after an operation is abandoned.)
- If the entry is a referral entry (an entry with the object class ref) and no manageDSAIT control is included with the request, the function should call slapi_str2filter() to send a referral and return -1.
- To determine if a manageDSAIT control is present, call slapi_pblock_get() to get the value of the SLAPI_MANAGEDSAIT parameter. If the value is 1, the control is included in the request. If 0, the control is not included in the request.
- If the entry does not exist, check the following:
- If the closest matching entry is a referral entry and if no manageDSAIT control is included in the request, the function should call slapi_send_ldap_referral() to send a referral and return -1.
- Otherwise, the function should call slapi_send_ldap_result() to send an LDAP error code LDAP_NO_SUCH_OBJECT and return -1.
- If the entry is not schema-compliant (call slapi_entry_schema_check() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_OBJECT_CLASS_VIOLATION and should return -1.
- If the RDN of the entry contains attribute values that are not part of the entry (for example, if the RDN is uid=bjensen, but the entry has no uid value or has a different uid value), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_NOT_ALLOWED_ON_RDN and should return -1.
- If the requestor does not have permission to modify the entry (call slapi_access_allowed() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_INSUFFICIENT_ACCESS and should return -1.
- You should also verify that the ACI syntax for the entry is correct; call slapi_acl_check_mods() to determine this.
If the modify function is successful, the function should call slapi_send_ldap_result() to send an LDAP_SUCCESS code back to the client and should return 0.
Processing an LDAP Modify RDN Operation
When the Directory Server receives an LDAP modifyRDN request from a client, the front-end gets the original DN of the entry; the new RDN; and, if the entry is moving to a different location in the directory tree, the DN of the new parent of the entry.
The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
The modify RDN function should check the following:
- If the operation has been abandoned, the function should return -1. (You do not need to call slapi_send_ldap_result() to send an LDAP error code to the client. According to the LDAP protocol, the client does not expect a server response after an operation is abandoned.)
- If the entry is a referral entry (an entry with the object class ref) and no manageDSAIT control is included with the request, the function should call slapi_str2filter() to send a referral and return -1.
- To determine if a manageDSAIT control is present, call slapi_pblock_get() to get the value of the SLAPI_MANAGEDSAIT parameter. If the value is 1, the control is included in the request. If 0, the control is not included in the request.
- If the entry does not exist, check the following:
- If the closest matching entry is a referral entry and if no manageDSAIT control is included in the request, the function should call slapi_send_ldap_referral() to send a referral and return -1.
- Otherwise, the function should call slapi_send_ldap_result() to send an LDAP error code LDAP_NO_SUCH_OBJECT and return -1.
- If the entry is not schema-compliant (call slapi_entry_schema_check() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_OBJECT_CLASS_VIOLATION and should return -1.
- If the RDN of the entry contains attribute values that are not part of the entry (for example, if the RDN is uid=bjensen, but the entry has no uid value or has a different uid value), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_NOT_ALLOWED_ON_RDN and should return -1.
- If the requestor does not have permission to modify the entry (call slapi_access_allowed() to determine this), the function should call slapi_send_ldap_result() to send the LDAP error code LDAP_INSUFFICIENT_ACCESS and should return -1.
- You should also verify that the ACI syntax for the entry is correct; call slapi_acl_check_mods() to determine this.
If the modifyRDN function is successful, the function should call slapi_send_ldap_result() to send an LDAP_SUCCESS code back to the client and should return 0.
Processing an LDAP Delete Operation
When the Directory Server receives an LDAP delete request from a client, the front-end gets the DN of the entry to be removed from the directory. The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
If the delete function is successful, it should return 0.
Processing an LDAP Abandon Operation
When the Directory Server receives an LDAP abandon request from a client, the front-end gets the message ID of the operation that should be abandoned. The front-end makes this information available to pre-operation and post-operation plug-in functions in the form of parameters in a parameter block.
Previous |
Contents |
Index |
Next |