 |
Plug-in
Programmer's Guide
Netscape
Directory Server
|
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 Netscape
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.
This chapter outlines how to define plug-in
functions to do the following:
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.)
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:
- First, the server
gets a list of
candidate entries, using an index (if applicable).
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.
- 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.
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.
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_SEARCH_TARGET
|
char *
|
DN of the base
entry in the search operation (the starting point of the search).
|
|
SLAPI_SEARCH_SCOPE
|
int
|
The scope of the
search. The scope can be one of the following values:
- LDAP_SCOPE_BASE
- LDAP_SCOPE_ONELEVEL
- LDAP_SCOPE_SUBTREE
|
|
SLAPI_SEARCH_DEREF
|
int
|
Method for
handling aliases in a search. This method can be one of the following
values:
- LDAP_DEREF_NEVER
- LDAP_DEREF_SEARCHING
- LDAP_DEREF_FINDING
- LDAP_DEREF_ALWAYS
|
|
SLAPI_SEARCH_SIZELIMIT
|
int
|
Maximum number of
entries to return in the search results.
|
|
SLAPI_SEARCH_TIMELIMIT
|
int
|
Maximum amount of
time (in seconds) allowed for the search operation.
|
|
SLAPI_SEARCH_FILTER
|
Slapi_Filter *
|
Slapi_Filter
struct (an opaque data structure) representing the filter to be used in
the search.
|
|
SLAPI_SEARCH_STRFILTER
|
char *
|
String
representation of the filter to be used in the search.
|
|
SLAPI_SEARCH_ATTRS
|
char **
|
Array of attribute
types to be returned in the search results.
|
|
SLAPI_SEARCH_ATTRSONLY
|
int
|
Specifies whether
the search results return attribute types only or attribute types and
values. (0
means return both attributes and values; 1 means
return attribute types only).
|
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)
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, 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):
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_SEARCH_RESULT_SET
|
void *
|
Set of search
results.
|
|
SLAPI_SEARCH_RESULT_ENTRY
|
void *
|
Entry returned
from iterating through the results set. This "next entry" function
actually sets this parameter.
|
|
SLAPI_SEARCH_RESULT_ENTRY_EXT
|
void *
|
(Netscape
Directory Server 4.x) Reserved for future use.
The context
identifying the last result
sent in the results set. This "next entry" function actually sets this
parameter.
|
|
SLAPI_NENTRIES
|
int
|
Number of search
results found.
|
|
SLAPI_SEARCH_REFERRALS
|
struct berval **
|
Array of the URLs
to other LDAP servers to which the current server is referring the
client.
|
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.
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_COMPARE_TARGET
|
char *
|
DN of the entry to
be compared.
|
|
SLAPI_COMPARE_TYPE
|
char *
|
Attribute type to
use in the comparison.
|
|
SLAPI_COMPARE_VALUE
|
struct berval *
|
Attribute value to
use in the comparison
|
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 See
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.
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_MODIFY_TARGET
|
char *
|
DN of the entry to
be modified.
|
|
SLAPI_MODIFY_MODS
|
LDAPMod **
|
A NULL-terminated
array of
LDAPMod structures, which represent the modifications to be
performed on the entry.
|
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.
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_MODRDN_TARGET
|
char *
|
DN of the entry
that you want to rename.
|
|
SLAPI_MODRDN_NEWRDN
|
char *
|
New RDN to assign
to the entry.
|
|
SLAPI_MODRDN_DELOLDRDN
|
int
|
Specifies whether
or not you want to delete the old RDN. (0 means
don't delete the old
RDN; 1
means delete the old RDN)
|
|
SLAPI_MODRDN_NEWSUPERIOR
|
char *
|
DN of the new
parent of the entry, if the entry is being moved to a new location in
the directory tree.
|
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 See 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.
|
Parameter ID
|
Data Type
|
Description
|
|
SLAPI_DELETE_TARGET
|
char *
|
DN of the entry to
delete.
|
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.