Red Hat DIRECTORY SERVER 7.1 - PLUG-IN PROGRAMMERS, Directory Server 7.1 User Manual

Page 1
Plug-in Programmer’s Guide
Red Hat Directory Server
Version 7.1
May 2005
Page 2
Red Hat, Inc. 1801 Varsity Drive Raleigh NC 27606-2072 USA Phone: +1 919 754 3700 Phone: 888 733 4281 Fax: +1 919 754 3701 PO Box 13588
Research Triangle Park NC 27709 USA © 2001 Sun Microsystems, Inc. Used by permission. © 2005 by Red Hat, Inc. All rights reserved. This material may be distributed only subject to the
terms and conditions set forth in the Open Publication License, V1.0 or later (the latest version is presently available at http://www.opencontent.org/openpub/).
Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form for commercial purposes is prohibited unless prior permission is
obtained from the copyright holder. Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries. All other trademarks referenced herein are the property of their respective owners. The GPG fingerprint of the security@redhat.com key is: CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E
Page 3
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
What You Should Already Know . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Using Directory Server Plug-in APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Document Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Where to Find Directory Server Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Part 1 Introduction to Directory Server Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Chapter 1 An Overview of Directory Server Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
What Are Directory Server Plug-ins? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
How Directory Server Plug-ins Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Calling Directory Server Plug-in Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
The Directory Server Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Types of Directory Server Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Chapter 2 Writing and Compiling Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Writing a Plug-in Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Including the API Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Passing Data with Parameter Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Working with Parameter Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Getting Data from the Parameter Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Setting Data in the Parameter Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Calling Front-End Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Plug-in Return Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Writing Plug-in Initialization Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Specifying Directory Server Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Specifying Information about the Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Registering Your Plug-in Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Returning a Value to the Directory Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3
Page 4
Example of an Initialization Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Compiling a Directory Server Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Chapter 3 Configuring Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Creating a Plug-in Configuration File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Plug-in Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Specific Plug-in Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Plug-in Type Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Specifying the Order of Plug-in Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Summary of Plug-in Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Loading the Plug-in Configuration File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Passing Extra Arguments to Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Setting the Log Level of the Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Chapter 4 A Quick Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
An Example Pre-Operation Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Writing the Plug-in Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Compiling the Plug-in Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Registering the Plug-in Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Running the Plug-in Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Part 2 Basic Plug-in Programming Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Chapter 5 Front-End API Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Logging Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Adding Notes to Access Log Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Sending Data to the Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Determining If an Operation Was Abandoned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Working with Entries, Attributes, and Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Creating a New Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Converting between Entries and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Getting and Setting the DN of an Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Verifying Compliance with the Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Getting the Attributes and Values of an Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Iterating through the Attributes in an Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Finding a Specific Attribute in an Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Adding and Removing Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Working with DNs and RDNs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Determining If a DN Is the Root DN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Working with DN Suffixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Server Suffixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 5
Getting the Parent DN of a DN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Normalizing a DN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Working with Search Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Determining If an Entry Matches a Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Getting the Filter Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Getting the Search Criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Converting a String to a Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Creating Complex Filters by Combining Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Checking Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Chapter 6 Writing Pre/Post-Operation Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
How Pre/Post-Operation Plug-ins Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Types of Pre-Operation and Post-Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Types of Pre-Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Types of Post-Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Registering Pre/Post-Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Chapter 7 Defining Functions for LDAP Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Specifying Start and Close Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Processing an LDAP Bind Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Defining Functions for the Bind Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Getting and Setting Parameters for the Bind Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Processing an LDAP Unbind Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Processing an LDAP Search Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Getting the List of Candidates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Iterating through Candidates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Processing an LDAP Compare Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Processing an LDAP Add Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Processing an LDAP Modify Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Processing an LDAP Modify RDN Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Processing an LDAP Delete Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Processing an LDAP Abandon Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Chapter 8 Defining Functions for Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Understanding Authentication Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
How the Directory Server Identifies Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
How the Authentication Process Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Writing Your Own Authentication Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Writing a Pre-Operation Bind Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Defining Your Authentication Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Getting and Checking the Bind Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Getting the Entry and Checking the Credentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
5
Page 6
What to Do If Authentication Fails . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
What to Do If Authentication Succeeds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Registering the SASL Mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Example of a Pre-Operation Bind Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Example of a Pre-Operation Bind Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Example of an Initialization Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Registering the Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Using SASL with an LDAP Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Part 3 Advanced Programming Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Chapter 9 Writing Entry Store/Fetch Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
How Entry Store/Fetch Plug-ins Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Writing Entry Store/Fetch Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Registering Entry Store/Fetch Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Chapter 10 Writing Extended Operation Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
How Extended Operation Plug-ins Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Writing Extended Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Registering Extended Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Specifying Start and Close Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Chapter 11 Writing Matching Rule Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Understanding Matching Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Extensible Match Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Extensible Match Filters in the Directory Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Understanding Matching Rule Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Functions Defined in Matching Rule Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
How Matching Rules Are Identified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
How the Server Associates Plug-ins with OIDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Finding a Plug-in for Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Finding a Plug-in for Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
How the Server Uses Parameter Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Indexing Based on Matching Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
How the Server Sets Up the Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
How the Server Updates the Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Writing the Indexer Factory Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Getting and Setting Parameters in Indexer Factory Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Writing the Indexer Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Getting and Setting Parameters in Indexer Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Handling Extensible Match Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
6 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 7
How the Server Handles the Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Query Operators in Matching Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Writing a Filter Factory Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Getting and Setting Parameters in Filter Factory Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Writing a Filter Index Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Getting and Setting Parameters in Filter Index Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Writing a Filter Matching Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Handling Sorting by Matching Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Writing a Destructor Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Writing an Initialization Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Registering Matching Rule Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Specifying Start and Close Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Chapter 12 Using the Custom Distribution Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
About Distributing Flat Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Creating a Distribution Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Adding the Distribution Function to Your Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Adding Multiple Databases to a Single Suffix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Using the Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
From the Command-Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Adding Distribution Logic to a Suffix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Using the Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
From the Command-Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Using the Distribution Logic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Custom Distribution Checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Chapter 13 Using Data Interoperability Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Installing Directory Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Understanding Deployment Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Installing Two Instances of Directory Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Enabling the DIOP Feature in Directory Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Using the DIOP Feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Sample DIOP Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Debugging the Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Plug-in API Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Preserving the Default Behavior of the Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Bypassing Access Control Checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7
Page 8
Part 4 Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Chapter 14 Data Type and Structure Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Summary of Data Types and Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
berval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
computed_attr_context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
LDAPControl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
LDAPMod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
mrFilterMatchFn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
plugin_referral_entry_callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
plugin_result_callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
plugin_search_entry_callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
send_ldap_referral_fn_ptr_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
send_ldap_result_fn_ptr_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
send_ldap_search_entry_fn_ptr_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Slapi_Attr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Slapi_Backend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
slapi_backend_state_change_fnptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Slapi_ComponentID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
slapi_compute_callback_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
slapi_compute_output_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Slapi_Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Slapi_CondVar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Slapi_DN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Slapi_Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Slapi_Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Slapi_MatchingRuleEntry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Slapi_Mod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Slapi_Mods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Slapi_Mutex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
Slapi_Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Slapi_PBlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Slapi_PluginDesc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Slapi_RDN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Slapi_UniqueID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Slapi_Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Slapi_ValueSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Chapter 15 Function Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Distribution Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
distribution_plugin_entry_point() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Functions for Access Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
8 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 9
slapi_access_allowed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
slapi_acl_check_mods() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
slapi_acl_verify_aci_syntax() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Functions for Internal Operations and Plug-in Callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
slapi_add_internal_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
slapi_delete_internal_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
slapi_free_search_results_internal() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
slapi_modify_internal_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
slapi_modrdn_internal_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
slapi_search_internal_callback_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
slapi_search_internal_get_entry() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
slapi_search_internal_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Functions for Setting Internal Operation Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
slapi_add_entry_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
slapi_add_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
slapi_delete_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
slapi_modify_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
slapi_rename_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
slapi_search_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
slapi_seq_internal_callback_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
slapi_seq_internal_set_pb() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Functions for Handling Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
slapi_attr_add_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
slapi_attr_basetype() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
slapi_attr_dup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
slapi_attr_first_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
slapi_attr_flag_is_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
slapi_attr_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
slapi_attr_get_bervals_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
slapi_attr_get_flags() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
slapi_attr_get_numvalues() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
slapi_attr_get_oid_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
slapi_attr_get_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
slapi_attr_get_valueset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
slapi_attr_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
slapi_attr_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
slapi_attr_next_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
slapi_attr_set_valueset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
slapi_attr_syntax_normalize() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
slapi_attr_type2plugin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
slapi_attr_type_cmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
slapi_attr_types_equivalent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
slapi_attr_value_cmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
9
Page 10
slapi_attr_value_find() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
slapi_valueset_set_from_smod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Functions for Managing Backend Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
slapi_be_addsuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
slapi_be_delete_onexit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
slapi_be_exist() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
slapi_be_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
slapi_be_get_instance_info() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
slapi_be_get_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
slapi_be_get_readonly() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
slapi_be_getentrypoint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
slapi_be_getsuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
slapi_be_gettype() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
slapi_be_is_flag_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
slapi_be_issuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
slapi_be_logchanges() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
slapi_be_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
slapi_be_private() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
slapi_be_select() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
slapi_be_select_by_instance_name() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
slapi_be_set_flag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
slapi_be_set_instance_info() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
slapi_be_set_readonly() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
slapi_be_setentrypoint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
slapi_get_first_backend() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
slapi_get_first_suffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
slapi_get_next_backend() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
slapi_get_next_suffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
slapi_is_root_suffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
slapi_register_backend_state_change() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
slapi_unregister_backend_state_change() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Functions for Dealing with Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
slapi_build_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
slapi_build_control_from_berval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
slapi_control_present() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
slapi_dup_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
slapi_get_supported_controls_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
slapi_register_supported_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Functions for Syntax Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
slapi_call_syntax_assertion2keys_ava_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
slapi_call_syntax_assertion2keys_sub_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
slapi_call_syntax_values2keys_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Functions for Managing Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
10 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 11
slapi_ch_array_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
slapi_ch_bvdup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
slapi_ch_bvecdup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
slapi_ch_calloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
slapi_ch_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
slapi_ch_free_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
slapi_ch_malloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
slapi_ch_realloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
slapi_ch_smprintf() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
slapi_ch_strdup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
Functions for Managing DNs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
slapi_add_auth_response_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
slapi_dn_beparent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
slapi_dn_ignore_case() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
slapi_dn_isbesuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
slapi_dn_isparent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
slapi_dn_isroot() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
slapi_dn_issuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
slapi_dn_normalize() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
slapi_dn_normalize_case() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
slapi_dn_normalize_to_end() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
slapi_dn_parent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
slapi_dn_plus_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
slapi_rdn2typeval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Functions for Managing Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
slapi_entry2str() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
slapi_entry2str_with_options() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
slapi_entry_add_rdn_values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
slapi_entry_add_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
slapi_entry_add_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
slapi_entry_add_values_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
slapi_entry_add_valueset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
slapi_entry_alloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
slapi_entry_attr_delete() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
slapi_entry_attr_find() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
slapi_entry_attr_get_bool() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
slapi_entry_attr_get_charptr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
slapi_entry_attr_get_charray() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
slapi_entry_attr_get_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
slapi_entry_attr_get_long() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
slapi_entry_attr_get_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
slapi_entry_attr_get_ulong() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
slapi_entry_attr_has_syntax_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
11
Page 12
slapi_entry_attr_merge_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
slapi_entry_attr_replace_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
slapi_entry_attr_set_charptr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
slapi_entry_attr_set_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
slapi_entry_attr_set_long() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
slapi_entry_attr_set_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
slapi_entry_attr_set_ulong() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
slapi_entry_delete_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
slapi_entry_delete_values_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
slapi_entry_dup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
slapi_entry_first_attr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
slapi_entry_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
slapi_entry_get_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
slapi_entry_get_dn_const() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
slapi_entry_get_ndn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
slapi_entry_get_sdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
slapi_entry_get_sdn_const() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
slapi_entry_get_uniqueid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
slapi_entry_has_children() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
slapi_entry_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
slapi_entry_merge_values_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
slapi_entry_next_attr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
slapi_entry_rdn_values_present() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
slapi_entry_schema_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
slapi_entry_set_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
slapi_entry_set_sdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
slapi_entry_set_uniqueid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
slapi_entry_size() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
slapi_is_rootdse() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
slapi_str2entry() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Functions Related to Entry Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
slapi_entry_clear_flag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
slapi_entry_flag_is_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
slapi_entry_set_flag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Functions for Dealing with Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
slapi_filter_apply() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
slapi_filter_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
slapi_filter_dup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
slapi_filter_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
slapi_filter_get_attribute_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
slapi_filter_get_ava() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
slapi_filter_get_choice() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
slapi_filter_get_subfilt() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
12 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 13
slapi_filter_get_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
slapi_filter_join() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
slapi_filter_join_ex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
slapi_filter_list_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
slapi_filter_list_next() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
slapi_filter_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
slapi_filter_test_ext() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
slapi_filter_test_simple() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
slapi_find_matching_paren() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
slapi_str2filter() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
slapi_vattr_filter_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Functions Specific to Extended Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
slapi_get_supported_extended_ops_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Functions Specific to Bind Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
slapi_get_supported_saslmechanisms_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
slapi_register_supported_saslmechanism() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Functions for Thread-Safe LDAP Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
slapi_ldap_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
slapi_ldap_unbind() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Functions for Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
slapi_log_error() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
slapi_is_loglevel_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Functions for Handling Matching Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
slapi_berval_cmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
slapi_matchingrule_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
slapi_matchingrule_get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
slapi_matchingrule_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
slapi_matchingrule_register() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
slapi_matchingrule_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
slapi_matchingrule_unregister() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
slapi_mr_filter_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
slapi_mr_indexer_create() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
Functions for LDAPMod Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
slapi_entry2mods() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
slapi_mod_add_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
slapi_mod_done() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
slapi_mod_dump() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
slapi_mod_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
slapi_mod_get_first_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
slapi_mod_get_ldapmod_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
slapi_mod_get_ldapmod_passout() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
slapi_mod_get_next_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
slapi_mod_get_num_values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
13
Page 14
slapi_mod_get_operation() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
slapi_mod_get_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
slapi_mod_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
slapi_mod_init_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
slapi_mod_init_byval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
slapi_mod_init_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
slapi_mod_isvalid() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
slapi_mod_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
slapi_mod_remove_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
slapi_mod_set_operation() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
slapi_mod_set_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
slapi_mods2entry() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
slapi_mods_add() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
slapi_mods_add_ldapmod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
slapi_mods_add_mod_values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
slapi_mods_add_smod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
slapi_mods_add_modbvps() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
slapi_mods_add_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
slapi_mods_done() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
slapi_mods_dump() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
slapi_mods_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
slapi_mods_get_first_mod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
slapi_mods_get_first_smod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
slapi_mods_get_ldapmods_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
slapi_mods_get_ldapmods_passout() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
slapi_mods_get_next_mod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
slapi_mods_get_next_smod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
slapi_mods_get_num_mods() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
slapi_mods_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
slapi_mods_init_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
slapi_mods_init_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
slapi_mods_insert_after() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
slapi_mods_insert_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
slapi_mods_insert_before() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
slapi_mods_insert_smod_at() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
slapi_mods_insert_smod_before() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
slapi_mods_iterator_backbone() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
slapi_mods_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
slapi_mods_remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Functions for Monitoring Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
slapi_op_abandoned() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
slapi_op_get_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Functions for Managing Parameter Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
14 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 15
slapi_pblock_destroy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
slapi_pblock_get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
slapi_pblock_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
slapi_pblock_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Functions for Handling Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
slapi_pw_find_sv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
slapi_is_encoded() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
slapi_encode() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
slapi_add_pwd_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
slapi_pwpolicy_make_response_control() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
Functions for Managing RDN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
slapi_rdn_add() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
slapi_rdn_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
slapi_rdn_contains() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
slapi_rdn_contains_attr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
slapi_rdn_done() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
slapi_rdn_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
slapi_rdn_get_first() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
slapi_rdn_get_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
slapi_rdn_get_index_attr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
slapi_rdn_get_next() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
slapi_rdn_get_num_components() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
slapi_rdn_get_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
slapi_rdn_get_nrdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
slapi_rdn_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
slapi_rdn_init_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
slapi_rdn_init_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
slapi_rdn_init_sdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
slapi_rdn_isempty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
slapi_rdn_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
slapi_rdn_new_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
slapi_rdn_new_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
slapi_rdn_new_sdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459
slapi_rdn_remove() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
slapi_rdn_remove_attr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
slapi_rdn_remove_index() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
slapi_rdn_set_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
slapi_rdn_set_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
slapi_rdn_set_sdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
Functions for Managing Roles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
slapi_role_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
slapi_register_role_check() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Functions for Managing DNs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
15
Page 16
slapi_moddn_get_newdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
slapi_sdn_add_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
slapi_sdn_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
slapi_sdn_copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
slapi_sdn_done() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
slapi_sdn_dup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
slapi_sdn_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
slapi_sdn_get_backend_parent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
slapi_sdn_get_dn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
slapi_sdn_get_ndn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
slapi_sdn_get_ndn_len() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
slapi_sdn_get_parent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
slapi_sdn_get_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
slapi_sdn_is_rdn_component() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
slapi_sdn_isempty() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
slapi_sdn_isgrandparent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
slapi_sdn_isparent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
slapi_sdn_issuffix() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
slapi_sdn_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
slapi_sdn_new_dn_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
slapi_sdn_new_dn_byval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
slapi_sdn_new_dn_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
slapi_sdn_new_ndn_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
slapi_sdn_new_ndn_byval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
slapi_sdn_scope_test() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
slapi_sdn_set_dn_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
slapi_sdn_set_dn_byval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
slapi_sdn_set_dn_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
slapi_sdn_set_ndn_byref() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
slapi_sdn_set_ndn_byval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
slapi_sdn_set_parent() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
slapi_sdn_set_rdn() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
Functions for Sending Entries and Results to the Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
slapi_send_ldap_referral() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
slapi_send_ldap_result() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
slapi_send_ldap_search_entry() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
Functions Related to UTF-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
slapi_has8thBit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
slapi_utf8casecmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
slapi_UTF8CASECMP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
slapi_utf8ncasecmp() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
slapi_UTF8NCASECMP() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
slapi_utf8isLower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
16 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 17
slapi_UTF8ISLOWER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
slapi_utf8isUpper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
slapi_UTF8ISUPPER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
slapi_utf8StrToLower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
slapi_UTF8STRTOLOWER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
slapi_utf8StrToUpper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
slapi_UTF8STRTOUPPER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
slapi_utf8ToLower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
slapi_UTF8TOLOWER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
slapi_utf8ToUpper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
slapi_UTF8TOUPPER() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Functions for Handling Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
slapi_value_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
slapi_value_dup() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
slapi_value_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
slapi_value_get_berval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
slapi_value_get_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
slapi_value_get_length() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
slapi_value_get_long() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
slapi_value_get_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
slapi_value_get_uint() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
slapi_value_get_ulong() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
slapi_value_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
slapi_value_init_berval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
slapi_value_init_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
slapi_value_init_string_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
slapi_value_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
slapi_value_new_berval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
slapi_value_new_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
slapi_value_new_string_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
slapi_value_new_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
slapi_value_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
slapi_value_set_berval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
slapi_value_set_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
slapi_value_set_string() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
slapi_value_set_string_passin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
slapi_value_set_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
Functions for Handling Valueset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
slapi_valueset_add_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
slapi_valueset_add_value_ext() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
slapi_valueset_count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
slapi_valueset_done() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
slapi_valueset_find() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
17
Page 18
slapi_valueset_first_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
slapi_valueset_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
slapi_valueset_init() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
slapi_valueset_new() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
slapi_valueset_next_value() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
slapi_valueset_set_from_smod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
slapi_valueset_set_valueset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
Functions Specific to Virtual Attribute Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
slapi_vattr_list_attrs() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540
slapi_vattr_attrs_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
slapi_vattr_schema_check_type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
slapi_vattr_value_compare() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
slapi_vattr_values_free() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
slapi_vattr_values_get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
slapi_vattr_values_get_ex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
slapi_vattr_values_type_thang_get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
Functions for Managing Locks and Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
slapi_destroy_condvar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
slapi_destroy_mutex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
slapi_lock_mutex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
slapi_new_condvar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
slapi_new_mutex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
slapi_notify_condvar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
slapi_unlock_mutex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
slapi_wait_condvar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Functions for Managing Computed Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
slapi_compute_add_evaluator() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
slapi_compute_add_search_rewriter() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
compute_rewrite_search_filter() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
Functions for Manipulating Bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
slapi_isbitset_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556
slapi_isbitset_uchar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
slapi_setbit_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
slapi_setbit_uchar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
slapi_unsetbit_int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
slapi_unsetbit_uchar() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
Functions for Registering Object Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
slapi_get_object_extension() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
slapi_register_object_extension() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
slapi_set_object_extension() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
Functions Related to Data Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
slapi_op_reserved() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
slapi_operation_set_flag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565
18 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 19
slapi_operation_clear_flag() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566
slapi_is_flag_set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566
Functions for Registering Additional Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
slapi_register_plugin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
Chapter 16 Parameter Block Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
Parameters for Registering Plug-in Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
Pre-Operation/Data Validation Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
Post-Operation/Data Notification Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
Matching Rule Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
Entry Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
Parameters Accessible to All Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
Information about the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
Information about the Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
Information about the Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
Information about Extended Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Information about the Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 580
Information about Access Control Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Notes in the Access Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581
Information about the Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582
Types of Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Version Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Information about Command-Line Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Information about Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
Attribute Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
Attribute Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
Attribute Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Information about Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
Parameters for the Bind Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Parameters for the Search Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
Parameters Passed to the Search Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
Parameters for Executing the Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Parameters for the Search Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Parameters that Return Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
Parameters that Convert Strings to Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
Parameters for the Add Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
Parameters for the Compare Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
Parameters for the Delete Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
Parameters for the Modify Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
Parameters for the Modify RDN Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
Parameters for the Abandon Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Parameters for the Matching Rule Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
Query Operators in Extensible Match Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
19
Page 20
Parameters for LDBM Backend Pre- and Post-Operation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 597
Pre-Operation Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Post-Operation Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Parameters for the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Information about the Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Information about Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
Information about Backend State Change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
Parameters for LDAP Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
Parameters for LDAP Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601
Parameters for LDAP Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601
Parameters for Generating LDIF Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
Parameters for Error Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
Parameters for Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
Parameters for Comparison Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
Parameters for Filter Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
Parameters for Password Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606
Password Storage Plug-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606
Parameters for Password Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Parameters for Resource Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Parameter for Binder-Based Resource Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
Status Codes for Resource Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Parameters for the Virtual Attribute Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
20 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 21
Preface
This book describes how to write server plug-ins in order to customize and extend the capabilities of the Red Hat Directory Server (Directory Server).
What You Should Already Know (page 21)
Using Directory Server Plug-in APIs (page 21)
Document Conventions (page 23)
Where to Find Directory Server Information (page 24)
What You Should Already Know
This book assumes you have this basic background:
A general understanding of the Internet and the World Wide Web (WWW).
A general understanding of the Lightweight Directory Access Protocol (LDAP) and the Directory Server. This book does not duplicate basic information on server administration or LDAP concepts. For such information, refer to the documents listed in “Where to Find Directory Server Information,” on page 24.
Programming experience in C or C++.
Using Directory Server Plug-in APIs
Note the following:
When you install Directory Server, the plug-in related files are placed in this directory:
21
Page 22
Using Directory Server Plug-in APIs
The main header file is located here:
The location and syntax for you to add the plug-in directives are in the
dse.ldif /opt/redhat-ds/slapd-instance_id/config
the
Database plug-ins are not supported in this version of Directory Server. Be sure to use the pre-operation, post-operation, and/or extended operation API to register plug-in functions. Some code examples in this book are yet to be updated to reflect this change.
To comply with Internet Protocol version 6, Directory Server plug-ins can use the allow plug-ins to recognize the IP address of the LDAP client and server. These new parameters use the Netscape Portable Runtime (NSPR) structure for storing the IP addresses. Because of this, the NSPR files are shipped with Directory Server.
/opt/redhat-ds/plugins/slapd/slapi/
/opt/redhat-ds/plugins/slapd/slapi/include/slapi-plugin.h
file, which is located in the
directory. For guidelines, refer to
Readme
/opt/redhat-ds/plugins/slapd/slapi/examples/
SLAPI_CONN_CLIENTEDADDR
file located here:
and
SLAPI_CONNSERVERADDR
parameters to
PRNetADDr
The NSPR API allows compliant applications to use system facilities such as threads, thread synchronization, I/O, interval timing, atomic operations, and several other low-level services in a platform-independent manner.
Several functions have been deprecated in this release of the Directory Server Plug-in API. The deprecated functions are still supported for backward compatibility. They are, however, not documented in this release. The table below lists the deprecated functions and the functions you should use in their place. If you need additional information on functions that have been deprecated, check this file:
/opt/redhat-ds/plugins/slapd/slapi/include/slapi-plugin-compat4 .h
Table 0-1 Deprecated Functions and Their Suggested Replacements
Deprecated Function Suggested Replacement Function
The following functions that deal with bervals are deprecated and their use is not recommended. For each deprecated function, you will find in slapi-plugin.h a corresponding function with an _sv extension that uses Slapi_Values instead of bervals. The new functions are more efficient than the old ones.
slapi_entry_attr_merge() slapi_entry_attr_merge_sv()
slapi_entry_add_values() slapi_entry_add_values_sv()
22 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 23
Document Conventions
Table 0-1 Deprecated Functions and Their Suggested Replacements (Continued)
Deprecated Function Suggested Replacement Function
slapi_entry_delete_values() slapi_entry_delete_values_sv()
slapi_entry_attr_replace() slapi_entry_attr_replace_sv()
slapi_attr_get_values() slapi_attr_value_find()
slapi_attr_get_oid() slapi_attr_get_oid_copy()
slapi_pw_find() slapi_pw_find_sv()
slapi_call_syntax_values2keys() slapi_call_syntax_values2keys_sv()
slapi_call_syntax_assertion2keys_ava()slapi_call_syntax_assertion2keys_ava_sv()
slapi_call_syntax_assertion2keys_sub()slapi_call_syntax_assertion2keys_sub_sv()
slapi_entry_attr_hasvalue() slapi_entry_attr_has_syntax_value()
The following internal-operation calls are deprecated. The new internal operation functions that are defined in slapi-plugin.h take a Slapi_PBlock for extensibility and support the new plug-in configuration capabilities.
slapi_search_internal_callback() slapi_search_internal_callback_pb()
slapi_search_internal() slapi_search_internal_pb()
slapi_modify_internal() slapi_modify_internal_pb()
slapi_add_internal() slapi_add_internal_pb()
slapi_delete_internal() slapi_delete_internal_pb()
slapi_modrdn_internal() slapi_modrdn_internal_pb()
The following three functions are not multi-thread safe; they return a pointer to unprotected data. Use the new functions in slapi-plugin.h that end in _copy() instead.
slapi_get_supported_controls() slapi_get_supported_controls_copy()
slapi_get_supported_extended_ops() slapi_get_supported_extended_ops_copy()
slapi_get_supported_saslmechanism() slapi_get_supported_saslmechanisms_copy()
Document Conventions
The Directory Server runs on a number of different UNIX platforms; the information here applies to all versions.
This book uses Uniform Resource Locators (URLs) of this form:
Preface 23
Page 24
Where to Find Directory Server Information
http://server.domain/path/file.html
In these URLs, application (such as name (such as and
file.html
server
represents the name of the server on which you run your
research1
example.com
or
www
),
domain
),
path
represents the directory structure on the server,
represents an individual filename.
represents your Internet domain
If your server has Secure Sockets Layer (SSL) enabled, you would use instead of
http
in the URL.
This book uses the following font conventions:
The
monospace font
is used for sample code and code listings, API and language elements (such as function names and class names), filenames, pathnames, directory names, HTML tags, and any text that must be typed on the screen.
Italic type is used for book titles, emphasis, placeholders, glossary terms, variables, and words used in the literal sense.
Where to Find Directory Server Information
This book explains how to write your own server plug-ins to customize the Directory Server. You can write plug-ins that validate data before the data is stored in the directory, that notify users when data has changed, or that replace the standard database in the Directory Server with your own database.
https
The document set for Directory Server also contains the following guides:
Red Hat Directory Server Deployment Guide. Contains procedures for the day-to-day maintenance of your directory service. Includes information on configuring server-side plug-ins.
Red Hat Directory Server Installation Guide. Contains procedures for installing your Directory Server as well as procedures for migrating from a previous installation of Directory Server.
Red Hat Directory Server Administrator’s Guide. Contains procedures for the day-to-day maintenance of your directory service. Includes information on configuring server-side plug-ins.
Red Hat Directory Server Configuration, Command, and File Reference. Contains information about using the command-line scripts shipped with Directory Server.
24 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 25
Where to Find Directory Server Information
Red Hat Directory Server Schema Reference. Contains information about the Directory Server schema.
Red Hat Directory Server Gateway Customization Guide. Introduces Directory Server Gateway and explains how to implement a gateway instance with basic directory look-up functionality. Also contains information useful for implementing a more powerful gateway instance with directory authentication and administration capability.
Red Hat Directory Server Org Chart. Introduces the Red Hat Directory Server Org Chart application and explains how to integrate it with an instance of Directory Server.
Red Hat Directory Server DSML Gateway Guide. Introduces the Red Hat Directory Server DSML Gateway function and explains how to customize it for use as an independent gateway.
For a list of documentation installed with Directory Server, open the
/opt/redhat-ds/manual/en/slapd/index.htm
file.
For the latest information about Directory Server, including current release notes, complete product documentation, technical notes, and deployment information, check this site:
http://www.redhat.com/docs/manuals/dir-server/
For a list of LDAP standards-related documents, check this site:
http://www.mozilla.org/directory/standards.html
Preface 25
Page 26
Where to Find Directory Server Information
26 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 27
Introduction to Directory Server Plug-ins
Chapter 1, “An Overview of Directory Server Plug-ins”
Chapter 2, “Writing and Compiling Plug-ins”
Chapter 3, “Configuring Plug-ins”
Part 1
Chapter 4, “A Quick Example”
27
Page 28
28 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 29
Chapter 1
An Overview of Directory Server
Plug-ins
This chapter introduces you to Red Hat Directory Server (Directory Server) plug-ins and discusses the different types of plug-ins that you can write. The chapter covers the following topics:
What Are Directory Server Plug-ins? (page 29 )
How Directory Server Plug-ins Work (page 30)
Types of Directory Server Plug-ins (page 34)
If you have already written a plug-in for Directory Server, refer to “Using Directory Server Plug-in APIs,” on page 21, for information on migrating your plug-in to the latest version of the Directory Server.
What Are Directory Server Plug-ins?
If you want to extend the capabilities of the Directory Server, you can write your own Directory Server plug-in. A server plug-in is a shared object or library that contains custom functions that you write.
By writing your own plug-in functions, you can extend the functionality of the Directory Server. For example, here are some of the things you can do with Directory Server plug-ins:
You can design an action that the Directory Server performs before the server processes an LDAP action. For example, you can write a custom function to validate data before the server performs an LDAP operation on the data.
29
Page 30
How Directory Server Plug-ins Work
You can design an action that the Directory Server performs after the server successfully completes an LDAP operation. For example, you can send mail to a client after an LDAP operation is successfully completed.
You can define extended operations, as defined in the the LDAP v3 protocol.
You can provide alternate matching rules when comparing certain attribute values.
How Directory Server Plug-ins Work
When properly configured, the Directory Server will load your plug-in on startup. Once loaded, the Directory Server will resolve calls made to your plug-in functions as it processes the LDAP requests contained in your applications.
Internally, the Directory Server has hooks that allow you to register your own functions to be called when specific events occur. For example, the Directory Server has hooks to call a registered plug-in in the following situations:
Before preforming an LDAP operation (for example, before an entry is added to the directory).
When adding, modifying, removing, renaming, or searching for entries in the database.
After performing an LDAP operation (for example, after an entry is added to the directory).
Before writing an entry to the database.
After reading an entry from the database.
When processing an extended operation.
When indexing an attribute.
When filtering search result candidates based on an attribute.
When you register your plug-in functions, you specify the function type and the plug-in type. Together, these specifications indicate when the function is called. For more information on this topic, refer to the section “Types of Directory Server Plug-ins,” on page 34.
30 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 31
How Directory Server Plug-ins Work
Calling Directory Server Plug-in Functions
At specific LDAP events, the Directory Server calls all plug-in functions that are registered for that event. For example, before performing an LDAP add operation (an add event), the server calls all plug-in functions registered as pre-operation add functions. When the add operation is completed, the server will call all registered post-operation add functions.
In most plug-in function calls, the server passes a parameter block to the function. The parameter block contains data relevant to the operation. In most Directory Server plug-in functions you write, you access and modify the data in the parameter block.
For example, when the Directory Server receives an LDAP add request, the server does the following:
1.
Parses the request, and retrieves the new DN and the entry to be added.
2.
Places pointers to the DN and the entry in the parameter block.
3.
Calls any registered pre-operation add functions, passing the parameter block to these functions.
4.
Calls the registered database add function (which is responsible for adding the entry to the directory database), and passes to it the parameter block.
5.
Calls any registered post-operation add functions, passing the parameter block to these functions.
If you are writing a function that is invoked before an LDAP operation is performed, you can prevent the operation from being performed. For example, you can write a function that validates data before a new entry is added to the directory. If the data are not valid, you can prevent the LDAP add operation from occurring and return an error message to the LDAP client.
In some situations, you can also set the data that are used by the server to perform an operation. For example, in a pre-operation add function, you can change an entry before it is added to the directory.
The Directory Server Architecture
Internally, the Directory Server consists of two major subsections, the front-end and the backend.
Chapter 1 An Overview of Directory Server Plug-ins 31
Page 32
How Directory Server Plug-ins Work
The front-end receives LDAP requests from clients and processes those requests. When processing requests, the front-end calls functions in the backend to read and write data. The front-end then sends the results back to the client.
The backend reads and writes data to the database containing the directory entries. The backend abstracts the database from the front-end. The data stored in a backend is identified by the suffixes that the backend supports. For example, a backend that supports the that end with that suffix.
Figure 1-1 illustrates the Directory Server architecture.
dc=example,dc=com
suffix contains directory entries
32 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 33
Figure 1-1 Directory Server Architecture
How Directory Server Plug-ins Work
Chapter 1 An Overview of Directory Server Plug-ins 33
Page 34
Types of Directory Server Plug-ins
Types of Directory Server Plug-ins
You can write the following types of plug-ins for the Directory Server:
Pre-operation/data validation. The server calls a pre-operation/data validation plug-in function before performing an LDAP operation.
The main purpose of this type of plug-in is to validate data before the data is added to the directory or before it is used in an operation.
Post-operation/data notification. The server calls a post-operation/data notification plug-in function after performing an LDAP operation.
The main purpose of this type of plug-in is to invoke a function after a particular operation is executed. For example, you can write a plug-in that sends email to users if their entries are modified.
Entry storage and entry fetch. The server calls an entry storage plug-in function right before writing data to the database backend. The server calls entry fetch plug-in functions after retrieving an entry from the database backend.
For example, you can create an entry storage plug-in that encrypts an entry before it is saved to the database and an entry fetch plug-in that decrypts an entry after it is read from the database.
Extended operation. The server calls an extended operation plug-in function when the client requests an operation by OID. Extended operations are defined in LDAP v3 and are described in more detail in chapter 10, “Writing Extended Operation Plug-ins.”
Syntax. The server calls a syntax plug-in function when getting a list of possible candidates for a search. The server also calls these functions when adding or deleting values from certain attribute indexes.
Syntax plug-in functions can define the comparison operations used in searches. For example, you could use a syntax plug-in function to define how the “equals” comparison works for case-insensitive strings.
Matching rule. The server calls matching rule plug-in functions when the client sends a search request with an extensible matching search filter. You can also write matching rule plug-in functions that the server calls when indexing attributes for the backend database.
Figure 1-2 illustrates how some of these different plug-in types fit into the Directory Server architecture.
34 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 35
Types of Directory Server Plug-ins
Figure 1-2 Architecture of the Directory Server and Server Plug-ins
Chapter 1 An Overview of Directory Server Plug-ins 35
Page 36
Types of Directory Server Plug-ins
36 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 37
Chapter 2
Writing and Compiling Plug-ins
This chapter provides an introduction on how to write and compile Red Hat Directory Server (Directory Server) plug-ins. chapter 3, “Configuring Plug-ins,” describes how to load your plug-in into the Directory Server configuration once it is successfully compiled. This chapter covers the following topics:
Writing a Plug-in Function (page 37)
Writing Plug-in Initialization Functions (page 42)
Compiling a Directory Server Plug-in (page 46)
If you have already written a plug-in for the Directory Server, refer to the section “Using Directory Server Plug-in APIs,” on page 21, for information on migrating your plug-in to the latest version of the Directory Server.
Writing a Plug-in Function
To write a Directory Server plug-in, you must do the following in your plug-in code:
Include the API header file.
Set the function parameters using the parameter block.
Call the front-end.
Specify the function return value.
For additional information on writing specific plug-in types, refer to the following chapters:
chapter 6, “Writing Pre/Post-Operation Plug-ins”
chapter 9, “Writing Entry Store/Fetch Plug-ins”
37
Page 38
Writing a Plug-in Function
chapter 10, “Writing Extended Operation Plug-ins”
Including the API Header File
The interface to the Directory Server plug-in API is located in the
slapi-plugin.h
write. The following line of code shows an example of including this header file:
#include "slapi-plugin.h"
header file. You must include this header file in the plug-ins you
When you install the Directory Server,
plugins/
folder within the server’s root directory. For example:
/opt/redhat-ds/plugins/slapd/slapi/include
slapi-plugin.h
gets installed into the
Passing Data with Parameter Blocks
Often, plug-in functions make use of a parameter block, passing information to and from the Directory Server. The following plug-in function types pass a parameter block as a function argument:
Pre-operation plug-in functions.
Post-operation plug-in functions.
Matching rule functions for indexing.
Factory functions for matching rule index functions.
Factory functions for matching rule filter functions.
When invoking these types of plug-in functions, you pass to the Directory Server a single argument of type
Slapi_PBlock
. This argument contains the parameter values needed to complete the function request. Your plug-in function should have a prototype similar to the following:
Slapi_PBlock
, for
int myFunction( Slapi_PBlock pb );
In this prototype, pb is the parameter block that contains the parameters pertaining to the operation or function.
For example, the parameter block for an add operation will contain the target DN and the entry to be added; the parameter block for a bind operation will contain the DN of the user, the authentication method, and the user’s credentials.
38 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 39
Writing a Plug-in Function
Working with Parameter Blocks
In the functions you write, you set values in the parameter block that pertain to the operation you are performing. You can also get data from the parameter block which you can use within your functions. This process is described in the next section, “Getting Data from the Parameter Block,” on page 39.
You can also set values in the parameter block during the processing of your plug-in functions. The Directory Server can then use the new data values to complete an operation which it might be processing. For details on this, see “Setting Data in the Parameter Block,” on page 40.
Some of the data that you can retrieve from the parameter block include entries, attributes, search filters, and distinguished names (DNs). Once you retrieve a piece of data, you can manipulate it using the front-end API functions. For example, you can use front-end API functions to verify that an entry complies with the schema or you can split up a search filter into its individual components. For details, see “Calling Front-End Functions,” on page 41.
Getting Data from the Parameter Block
When the Directory Server calls your plug-in function, it passes any relevant data to your function in a parameter block. The parameter block is defined as a
Slapi_PBlock slapi_pblock_get()
NOTE Often,
In the following example, the the base DN for the LDAP search operation. It then normalizes the DN, converts all characters to lowercase, and writes the converted DN to the error log. The actual DN (not a copy of it) is normalized and converted to lowercase.
Code Example 2-1 Getting Data from the Parameter Block
#include <slapi-plugin.h> ... int searchdn_preop_search( Slapi_PBlock *pb ) {
char *dn;
data type. To access the data in a parameter block, call the
function.
slapi_pblock_get()
When you call your own functions to modify the value retrieved by
slapi_pblock_get()
, you are modifying the actual data in the
parameter block, not a copy of the data.
searchdn_preop_search()
returns a pointer to the actual data.
function gets the DN of
Chapter 2 Writing and Compiling Plug-ins 39
Page 40
Writing a Plug-in Function
Code Example 2-1 Getting Data from the Parameter Block (Continued)
/* Indicate the point when the plug-in starts executing */ slapi_log_error( SLAPI_LOG_PLUGIN, "searchdn_preop_search",
"*** PREOPERATION SEARCH PLUGIN ***\n");
/* Get the base DN of the search from the parameter block. */ slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &dn );
/* Normalize the DN (the actual DN, not a copy of it)
and convert it to lowercase */
slapi_dn_normalize_case( dn );
/* Log the normalized DN */ slapi_log_error( SLAPI_LOG_PLUGIN, "searchdn_preop_search",
"Normalized DN: %s\n", dn );
return( 0 );
}
In this code example,
SLAPI_SEARCH_TARGET
parameter block that contains the base DN of the search. For a complete listing of the parameter block IDs, see chapter 16, “Parameter Block Reference.”
Setting Data in the Parameter Block
To modify the value of a parameter in the parameter block, call the function
slapi_pblock_set()
the value of the plug-in.
In the following example, the
SLAPI_PRIVATE
Code Example 2-2 Setting Values in the Parameter Block
#include <slapi-plugin.h> ... int ldif_back_init( Slapi_PBlock *pb ) {
LDIF *db; /* context of the database */ ...
parameter to the context of the database.
. For example, you call can
SLAPI_PRIVATE
parameter, which stores private data for the
ldif_back_init()
identifies the parameter in the
slapi_pblock_set()
to change
function sets the value of the
/* Allocate space for the database context, which contains
information about the database and a pointer to the list of entries. */
if ( slapi_pblock_set( pb, SLAPI_PRIVATE, (void *) db ) == -1 )
{
slapi_log_error( SLAPI_LOG_PLUGIN, "ldif_back_init",
40 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 41
Code Example 2-2 Setting Values in the Parameter Block (Continued)
"Unable to store database information\n" );
} ... }
Writing a Plug-in Function
This example uses the function
slapi_log_error()
to notify the user if an error
occurred.
In this code example,
SLAPI_PRIVATE
identifies the parameter in the parameter block that contains private data for use in the database functions. For a complete listing of the parameter block IDs, see chapter 16, “Parameter Block Reference.”
Calling Front-End Functions
The types of data that you can get from a parameter block include entries, attributes, distinguished names, and search filters. If you want to manipulate these data items, you can call the associated front-end API functions provided with the Directory Server. For example, using the the front-end API functions, you can:
Write messages to the error log.
Get the attributes of an entry.
Get or set the DN of an entry.
Add or delete the values of an attribute.
Determine the OID of an attribute.
Determine the type of a search filter.
For more information on the front-end API, see chapter 5, “Front-End API Functions,” and chapter 15, “Function Reference.”
Plug-in Return Values
If your plug-in function is successful, it should return 0 to the front-end. If it is not successful, it should return a non-zero value, and you should call the front-end API function (“Logging Messages,” on page 65, details this process).
slapi_log_error()
to log an error message to describe the problem
Chapter 2 Writing and Compiling Plug-ins 41
Page 42
Writing Plug-in Initialization Functions
In some cases, you may need to send an LDAP result back to the client. For example, if you are writing a pre-operation bind function and an error occurs during the processing of the function, the function should return a non-zero value, log an error message, and send the appropriate LDAP result code back to the client. For information on the appropriate result code to return to the client, refer to the chapter that documents the type of plug-in you are writing.
Writing Plug-in Initialization Functions
Before the Directory Server can call your plug-in function, the function must be properly initialized. To do this, you must write an initialization function for your server plug-in. The initialization function should do the following:
1.
Specify the plug-in compatibility version.
2.
Register each of your plug-in functions.
3.
Return a value to the Directory Server.
NOTE
The initialization function should not do anything more than these three steps. If you need to perform additional configuration or initialization, use a start function. This function is specified by using slapi_pblock_set() with the SLAPI_PLUGIN_START_FN parameter in the initialization function.
Your initialization function should have a prototype similar to the following:
int my_init_function( Slapi_PBlock pb );
In the initialization function, the Directory Server passes a single argument of type
Slapi_PBlock
.
Specifying Directory Server Compatibility
You need to specify the compatibility version of your plug-in so that the Directory Server can determine whether it supports the plug-in.
To specify the plug-in compatibility version, call the function, and set the
SLAPI_PLUGIN_VERSION
parameter to the version number
associated with the plug-in. For example:
slapi_pblock_set()
42 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 43
slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, \
SLAPI_PLUGIN_VERSION_03);
Writing Plug-in Initialization Functions
Plug-in version 1 (
SLAPI_PLUGIN_VERSION_01
) is compatible with versions 3.x
and 4.x of the Directory Server.
Plug-in version 2 (
SLAPI_PLUGIN_VERSION_02
) is compatible with version 4.x
of the Directory Server.
Plug-in version 3 (
SLAPI_PLUGIN_VERSION_03
) is compatible with versions 6.x
and later of the Directory Server.
Specifying Information about the Plug-in
You specify information about your plug-in, such as a description of the plug-in, with the “Slapi_PluginDesc,” on page 215.
It is advised that you include a plug-in description since the Red Hat Console displays this information as part of the server configuration information.
To specify plug-in information, call the
SLAPI_PLUGIN_DESCRIPTION
Code Example 2-3 Specifying Plug-in Information
Slapi_PluginDesc
structure. For details on this data structure, see
slapi_pblock_set()
function, and set the
parameter to this structure. For example:
/* Specify information about the plug-in */ Slapi_PluginDesc mypdesc = { "test-plugin", "example.com",
"0.5", "sample pre-operation plugin" };
...
/* Set this information in the parameter block */ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&mypdesc );
This example code specifies the following plug-in information:
The unique identifier for the server plug-in is
The vendor of the server plug-in is
The version of the server plug-in is
example.com
0.5
.
test-plugin
.
.
Chapter 2 Writing and Compiling Plug-ins 43
Page 44
Writing Plug-in Initialization Functions
This version is intended to be used for your tracking purposes only; it is not the same as the server compatibility version number specified by the
SLAPI_PLUGIN_VERSION
Compatibility,” on page 42, for details on this parameter). As you make changes to your plug-in code, you can track the version distributed using the number contained in the
The description of the server plug-in is contained in the data structure value
sample pre-operation plug-in
Registering Your Plug-in Functions
Whether you register your plug-in through the initialization function depends upon the type of function you are registering.
For some plug-in types, you do not need to register the plug-in function from within the initialization function. For example, you register entry store and entry fetch plug-ins by specifying the function names in the
dse.ldif
file.
parameter (see “Specifying Directory Server
Slapi_PluginDesc
structure.
.
plugin
directive in the
For other plug-in types, such as pre-operation plug-ins and post-operation plug-ins, the Directory Server gets the pointer to your function from a parameter in the initialization function parameter block. In these cases, you use the
slapi_pblock_set()
function to specify the name of your plug-in function.
The full list parameters that you can use to register your plug-in functions are listed in “Parameters for Registering Plug-in Functions,” on page 570.
For example, if you want to register
searchdn_preop_search()
as a pre-operation search function, include the following code in your initialization function:
slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN, \
(void *) searchdn_preop_search )
SLAPI_PLUGIN_PRE_SEARCH_FN
is the parameter that specifies the pre-operation
plug-in function for the LDAP search operation.
NOTE If you do not register your plug-in functions, the Directory Server
will not call your plug-in functions. Make sure to register your plug-in functions.
44 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 45
Writing Plug-in Initialization Functions
You can register more than one plug-in function in your initialization function; you do not need to write an initialization function for each plug-in function that you need to register. You should, however, define a different initialization function for each type of plug-in that you are registering.
Returning a Value to the Directory Server
If the initialization function is successful, it should return 0. If an error occurs, it should return -1. If the initialization function returns -1, the Directory Server will exit.
Example of an Initialization Function
The following is an example of an initialization function that registers the pre-operation plug-in function function returns, the server will call search operation is executed.
searchdn_preop_search()
searchdn_preop_search()
. After the initialization
before each LDAP
Code Example 2-4 An Example Initialization Function
#include "slapi-plugin.h" ... #ifdef _WIN32 __declspec(dllexport) #endif
searchdn_preop_init( Slapi_PBlock *pb ) {
/* Specify the version of the plug-in (set this to "01")*/ if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
SLAPI_PLUGIN_VERSION_01 ) != 0 ||
/* Set up the server to call searchdn_preop_search()
before each LDAP search operation. */
slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
(void *) searchdn_preop_search ) !=0 ) {
/* If a problem occurs, log an error message, return -1.*/
slapi_log_error(SLAPI_LOG_PLUGIN,"searchdn_preop_init",
"Error registering function.\n" ); return( -1 ); }
/* If the plug-in was successfully registered, log a
message and return 0. */ slapi_log_error( SLAPI_LOG_PLUGIN, "searchdn_preop_init",
"Plug-in successfully registered.\n" );
Chapter 2 Writing and Compiling Plug-ins 45
Page 46
Compiling a Directory Server Plug-in
Code Example 2-4 An Example Initialization Function (Continued)
return( 0 );
}
Compiling a Directory Server Plug-in
Keep in mind the following tips when compiling your server plug-in:
You need to compile and link your code as a shared object or library. For example, on Solaris, specify command.
Some compilers require that you provide special flags when compiling code to be used in a shared object or DLL. For example, on Solaris, you must specify the
-Kpic
or
-KPIC
position-independent code. Consult the documentation for your platform compiler and linker for details.
ld -G objects -o shared_object
flag, which specifies that you want to generate
as your link
Make sure that the
/opt/redhat-ds/plugins/slapd/slapi/include
directory is in your include path.
If you want, you can compile all plug-in functions in a single library. Although you can include different types of plug-in functions in the same library, you need to write separate initialization functions for each type of plug-in function. Refer to chapter 3, “Configuring Plug-ins,” for details on how to specify each initialization function in a directive for a specific type of plug-in.
The following code shows a sample Makefile for Solaris. The example assumes that the source files are located in the following directory:
/opt/redhat-ds/plugins/slapd/slapi/examples
The server plug-in API header files are located in the relative path
Code Example 2-5 Example Solaris Makefile
# SOLARIS Makefile for Directory Server plug-in examples # CC = cc LD = ld INCLUDE_FLAGS = -I../include CFLAGS = $(INCLUDE_FLAGS) -D_REENTRANT -KPIC LDFLAGS = -G
../include
.
46 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 47
Compiling a Directory Server Plug-in
Code Example 2-5 Example Solaris Makefile (Continued)
OBJS = testsaslbind.o testextendedop.o testpreop.o testpostop.o testentry.o
all: libtest-plugin.so libtest-plugin.so: $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS)
.c.o:
$(CC) $(CFLAGS) -c $<
clean:
-rm -f $(OBJS) libtest-plugin.so
Chapter 2 Writing and Compiling Plug-ins 47
Page 48
Compiling a Directory Server Plug-in
48 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 49
Chapter 3
Configuring Plug-ins
After you compile your server plug-in, you need to configure the Red Hat Directory Server (Directory Server) so that it properly loads your plug-in. The following sections in this chapter show how this is done:
Creating a Plug-in Configuration File (page 47)
Loading the Plug-in Configuration File (page 52)
Passing Extra Arguments to Plug-ins (page 52)
Setting the Log Level of the Server (page 54)
Creating a Plug-in Configuration File
To add your plug-in to the Directory Server configuration, you need to create an LDIF representation of your plug-in entry, add the plug-in entry to the Directory Server configuration, and reload the server configuration. This section illustrates how to create your plug-in entry. The section “Loading the Plug-in Configuration File,” on page 52, explains how to add the plug-in entry to the Directory Server configuration and reload the server configuration.
The plug-in configuration file must be an LDIF file written in ASCII format. Code Example 3-1 shows the contents of an example plug-in configuration file. Line numbers have been added for ease of reference; do not number the lines in your own LDIF file.
Code Example 3-1 An Example Plug-in Configuration File
1. dn: cn=Example Plug-in,cn=plugins,cn=config
2. objectclass: top
3. objectclass: nsSlapdPlugin
4. objectclass: extensibleObject
47
Page 50
Creating a Plug-in Configuration File
Code Example 3-1 An Example Plug-in Configuration File (Continued)
5. cn: Example Plug-in
6. nsslapd-pluginpath: /servers/lib/test-plugin.so
7. nsslapd-plugininitfunc: searchdn_preop_init
8. nsslapd-plugintype: preoperation
9. nsslapd-pluginenabled: on
10. nsslapd-pluginid: Example Pre-operation Plug-in
11. nsslapd-pluginversion: 1.0
12. nsslapd-pluginvendor: Example Corporation
13. nsslapd-plugindescription: This plug-in does ...
This example plug-in configuration file defines an example plug-in as follows:
Line 1 sets the DN of the plug-in, which identifies the plug-in:
dn: cn=Example Plug-in,cn=plugins,cn=config
Here, the common name of the plug-in is set to the DN entry (
cn=plugins,cn=config
) places the entry in the database tree
Example Plug-in
. The rest of
that contains the configuration settings for plug-ins.
Lines 2-4 declare the object classes of the plug-in.
Line 5 sets the common name of the plug-in to
Example Plug-in
.
Line 6 defines the absolute path to the library that implements the plug-in:
nsslapd-pluginpath: /servers/lib/test-plugin.so
Line 7 identifies the initialization function that the server calls to register the plug-in. In this example, the initialization is set to
searchdn_preop_init
. For information on implementing initialization functions, see “Writing Plug-in Initialization Functions,” on page 42.
Line 8 sets the type of plug-in. In this case, it is a pre-operation plug-in. For a complete list of the types of plug-in you can declare, refer to the “Summary of Plug-in Directives,” on page 51.
Line 9 specifies whether the plug-in is active by default. The
nsslapd-pluginenabled
attribute can have a value of either on or
off
. The
following line specifies that the plug-in is active by default:
nsslapd-pluginenabled: on
You can also use the Directory Server Console to activate or deactivate the plug-in once the plug-in is loaded.
48 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 51
Creating a Plug-in Configuration File
Line 10 uses the
nsslapd-pluginid
attribute to set the name of the plug-in. The name that you specify here will show up in the Directory Server Console. In this example, the plug-in identification is set to
Plug-in
.
Example Pre-operation
Line 11 sets the version number of the plug-in. This version number will also show up in the Directory Server Console and is used to track the version of the distributed plug-in; it does not indicate the Directory Server compatibility, as is defined by the plug-in version number described in “Specifying Directory Server Compatibility,” on page 42.
Line 12 identifies the vendor/author of the plug-in. In the following line, the vendor is set to
nsslapd-pluginvendor: Example Corporation
Example Corporation
:
Finally, Line 13 sets the description of the plug-in. The description you set will be the plug-in description that is visible through the Directory Server Console.
Plug-in Dependencies
You can specify that your plug-in is dependent on one or more different plug-ins. If you do specify any plug-in dependencies, those plug-ins that you specify must properly start before your associated plug-in will start.
There are two attributes that you can use in the plug-in configuration file to specify the dependencies of your plug-in:
nsslapd-plugin-depends-on-named
nsslapd-plugin-depends-on-type
Each of these attributes can take multiple values, meaning that your plug-in depends on one or more other plug-ins.
Specific Plug-in Dependencies
If you specify the configuration file, set its value to the names of one or more plug-ins. For example, in your plug-in configuration file, you could specify the following:
nsslapd-plugin-depends-on-named: my_pluginA nsslapd-plugin-depends-on-named: vendor_pluginB
nsslapd-plugin-depends-on-named
attribute in your plug-in
Chapter 3 Configuring Plug-ins 49
Page 52
Creating a Plug-in Configuration File
In this example, the plug-in depends on two specifically named plug-ins:
my_pluginA
your plug-in can be loaded, the two specifically named plug-ins must be loaded. If either of these two plug-ins fail to load, the Directory Server will exit with a -1 error code.
Plug-in Type Dependencies
and
vendor_plugin
. This configuration line indicates that before
If you specify the
nsslapd-plugin-depends-on-type
attribute in your plug-in configuration file, set its value to one or more plug-in types. For example, in your plug-in configuration file, you could specify the following:
nsslapd-plugin-depends-on-type: syntax
This configuration line indicates that your plug-in depends on any plug-in of the type
syntax
. If there is a configured plug-in of type
syntax
, it must be successfully loaded before your plug-in can be loaded; otherwise, the Directory Server will exit with a -1 error code.
If you specify a plug-in type dependency, the Directory Server will search for any and all plug-ins of the type(s) specified. If none are found, processing will continue without errors. However, the Directory Server must load all plug-ins of the type(s) specified before it can load your plug-in. For a complete list of the supported plug-in types, refer to the “Summary of Plug-in Directives,” on page 51.
Specifying the Order of Plug-in Directives
You cannot in general rely on plug-ins being called in a certain order. For example, you cannot rely on a particular pre-operation plug-in to be called before another. You should ensure that your plug-in is written in such a way as to make it independent of the order in which it will be called.
If you must use ordering, you can make use of alphabetical order. The server loads the plug-ins in alphabetical order—that is, the loading order is determined by standard ASCII ordering of the cn value of the plug-in entry, which appears under
cn=plugins,cn=config
deprecated in a future version of the product, it is recommended that you write your plug-in not to rely on any specific loading order.
50 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
in the
dse.ldif
file. Because this feature may be
Page 53
Creating a Plug-in Configuration File
Summary of Plug-in Directives
The following table summarizes the different types of plug-ins that you can specify in the plug-in configuration file.
Table 3-1 Directives for Specifying Different Plug-in Types
Directive Description
entryfetch Declares an entry fetch plug-in, which is called by the server after retrieving an
entry from the default backend database.
Example of use: If you encrypt data with an entry store plug-in function before saving the data to the database, you can define an entry fetch function that decrypts data after reading it from the database.
entrystore Declares an entry store plug-in, which is called by the server before saving an
entry to the default backend database. (If you are writing your own database plug-in, you do not need to use this plug-in.)
Example of use: You can define an entry store function to encrypt data before saving the data to the database.
extendedop Declares an extended operation plug-in, which is called by the server when
receiving a request for an extended operation from a client.
matchingRule Declares a matching rule plug-in, which is called by the server when receiving a
search request with an extensible matching search filter from a client.
This type of plug-in is also called by the server when indexing attributes for the backend database.
postoperation Declares a post-operation/data notification plug-in, which is called by the
server after performing an LDAP operation.
Example of use: You can define a data notification function to send notification to the administrator if certain data have changed.
preoperation Declares a pre-operation/data validation plug-in, which is called by the server
before performing an LDAP operation. Example of use: You can define a data validation function to check new entries
before they are added to the directory.
syntax Declares a syntax plug-in, which is called by the server when getting a list of
possible candidates for a search, when determining how to compare values in searches, and when adding or deleting values from certain attribute indexes.
Example of use: You can define a function that specifies how the “equals” comparison works for case-insensitive strings.
Chapter 3 Configuring Plug-ins 51
Page 54
Loading the Plug-in Configuration File
Table 3-1 Directives for Specifying Different Plug-in Types (Continued)
Directive Description
object Declares an object plug-in. Object plug-ins can install
SLAPI_PLUGIN_START_FN, SLAPI_PLUGIN_CLOSE_FN, and SLAPI_PLUGIN_POSTSTART_FN functions. They can also use the slapi_register_plugin() call to register any kind of plug-in they like.
Object plug-ins are typically used to simplify configuration of a group of related plug-ins (one entry under cn=config instead of many).
Example of use: You can use this type when your plug-in doesn’t fit in any of the other types listed in this table. For example, if your plug-in does more than one thing, then you should use this directive. This type of plug-in will typically register the types of operations it wants to handle using the internal API.
pwdstoragescheme This directive will be supported in the future.
Loading the Plug-in Configuration File
After you have written the plug-in configuration file, you must load it into the
dse.ldif
file, which is located in the
/opt/redhat-ds/slapd-instance_id/config
directory. You can do this either by using an LDAP utility, such as by editing the file directly. If you choose to edit the file directly, be sure to shut down the Directory Server first.
The following line shows an example of an LDAP command that loads the plug-in defined in the configuration file
ldapmodify -h my_host -p 389 -a -D "cn= Directory Manager"
-w adminadmin -f example-plugin.ldif
example-plugin.ldif
Once the plug-in configuration is loaded, you must shut down the Directory Server and then restart it before you can make calls to your plug-in. There are various ways to shut down and restart the Directory Server; you can either use the Directory Server Console or use the
stop-slapd
and
Passing Extra Arguments to Plug-ins
The standard method for configuring plug-ins is to provide configuration parameters as attributes and values in the plug-in entry in the plug-ins use the added to that object class in the schema. A better alternative is to define a custom auxiliary object class which contains the custom plug-in configuration attributes.
extensibleObject
object class, so any custom attribute can be
:
start-slapd
dse.ldif
ldapmodify
scripts.
file. All
, or
52 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 55
Passing Extra Arguments to Plug-ins
Use the plug-in start function (registered in the initialization function with
slapi_pblock_set()
using
SLAPI_PLUGIN_START_FN
) to use the custom configuration. One of the pblock parameters passed to the start function is the plug-in entry, as the
SLAPI_ADD_TARGET
parameter. The
slapi_entry_attr_*
family of functions can be used to get and use these values.
Plug-ins can be dynamically configured at run-time by registering DSE callbacks for the plug-in entry with
slapi_config_register_callback()
.
Example 1:
dn: cn=Test ExtendedOp,cn=plugins,cn=config objectClass: top objectClass: nsSlapdPlugin objectClass: extensibleObject cn: Test ExtendedOp nsslapd-pluginPath: /opt/redhat-ds/servers/plugins/slapd/slapi/
examples/libtest-plugin.so nsslapd-pluginInitfunc: testexop_init nsslapd-pluginType: extendedop nsslapd-pluginEnabled: on nsslapd-plugin-depends-on-type: database nsslapd-pluginId: test-extendedop
nsslapd-pluginarg0: 1.2.3.4
Example 2:
dn: cn=PAM Pass Through Auth,cn=plugins,cn=config objectclass: top objectclass: nsSlapdPlugin objectclass: extensibleObject objectclass: pamConfig cn: PAM Pass Through Auth nsslapd-pluginpath: /opt/redhat-ds/lib/pam-passthru-plugin.so nsslapd-plugininitfunc: pam_passthruauth_init nsslapd-plugintype: preoperation nsslapd-pluginenabled: on nsslapd-pluginLoadGlobal: true nsslapd-plugin-depends-on-type: database pamMissingSuffix: ALLOW pamExcludeSuffix: o=NetscapeRoot pamExcludeSuffix: cn=config pamMapMethod: RDN pamFallback: FALSE pamSecure: TRUE pamService: ldapserver
Chapter 3 Configuring Plug-ins 53
Page 56
Setting the Log Level of the Server
This method allows for a much more descriptive configuration, which is easier to maintain. The attributes beginning with
pam
are specific to the plug-in and used for its configuration. The plug-in entry is provided to the plug-in start function as a
Slapi_Entry *
slapi_entry_attr_*
in the
SLAPI_ADD_TARGET
pblock parameter. Use the
family of functions to get the configuration values from
that entry.
For additional information, check the code samples provided here:
/opt/redhat-ds/plugins/slapd/slapi/examples
Setting the Log Level of the Server
If your functions call the
slapi_log_error()
function to write messages to the error log, you need to make sure that the Directory Server is configured to log messages with the severity level you’ve specified. The available severity levels are fully documented in the Reference section on page 550.
For example, suppose you call this function in your plug-in:
slapi_log_error( SLAPI_LOG_PLUGIN, "searchdn_preop_init",
"Plug-in successfully registered.\n" );
You need to make sure that the Directory Server is configured to log messages with the severity level
nsslapd-errorlog-level
SLAPI_LOG_PLUGIN
attribute in
cn=config
. Error logging is controlled with the
.
54 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 57
Chapter 4
A Quick Example
This chapter provides an example of a pre-operation Red Hat Directory Server (Directory Server) server plug-in that you can compile and run. Along with the source code to the example, the chapter provides a Solaris Makefile that you can use to build the plug-in.
You may not understand some of the functionality contained in the example program; however, all the concepts contained in the example code are explained in detail in chapters that follow.
An Example Pre-Operation Plug-in
The example shows how to create a pre-operation plug-in for the LDAP search operation. In other words, the Directory Server will process the registered plug-in functions before it processes each LDAP search operation. The example contains two primary functions:
The
The
These functions illustrate the data in the parameter block that is available to your function. You can get and manipulate the parameter block data by calling various front-end API functions.
test_preop_search()
including the base DN of the search, the search scope, and the type of filter used.
test_preop_init()
test_preop_search()
plug-in function for LDAP search operations.
function logs information about the search,
function is the initialization function that registers
as a
SLAPI_PLUGIN_PRE_SEARCH_FN
pre-operation
55
Page 58
An Example Pre-Operation Plug-in
Writing the Plug-in Example
The following example code includes the sample pre-operation search function and the sample initialization function.
Code Example 4-1 Sample Pre-Operation Search and Initialization Functions
#include <stdio.h> #include <string.h> #include "slapi-plugin.h"
/* function prototypes */ int test_preop_init( Slapi_PBlock *pb ); int test_preop_search( Slapi_PBlock *pb );
/* Description of the plug-in */ Slapi_PluginDesc srchpdesc = { "test-search", "example.com", "0.5",
"sample pre-operation search plugin" };
/* Initialization function This function registers your plug-in function as a pre-operation search function in the Directory Server. You need to specify this initialization function in the server configuration file so that the server calls this initialization function on startup. */ #ifdef _WIN32 __declspec(dllexport) #endif int test_preop_init( Slapi_PBlock *pb ) {
/* Specify the version of the plug-in ("01" in this release ) */ if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
SLAPI_PLUGIN_VERSION_01 ) != 0 || /* Specify the description of the plug-in */ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
(void *)&srchpdesc ) != 0 ||
/* Set test_preop_search() as the function to call before
executing LDAP search operations. */
slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
(void *) test_preop_search ) !=0 ) { /* Log an error message and return -1 if a problem occurred */ slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_init",
"Error registering the plug-in.\n" ); return( -1 );
} /* If successful, log a message and return 0 */ slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_init",
"Plug-in successfully registered.\n" );
return( 0 );
}
/* Pre-operation plug-in function for LDAP search operations This function is called by the server before processing an LDAP search operation. The function gets data about the search request
56 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 59
An Example Pre-Operation Plug-in
Code Example 4-1 Sample Pre-Operation Search and Initialization Functions (Continued)
from the parameter block and prints the data to the error log. */ int test_preop_search( Slapi_PBlock *pb ) {
char *base, *filter_str, *attr_type, *substr_init, *substr_final; char **substr_any; int scope, deref, filter_type, i; Slapi_Filter *filter; struct berval *bval; /* Log a message to indicate when the plug-in function starts */ slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_search",
"*** PREOPERATION SEARCH PLUGIN ***\n"); /* Get and log the base DN of the search criteria */ if ( slapi_pblock_get( pb, SLAPI_SEARCH_TARGET, &base ) == 0 )
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_TARGET",
"%s\n", base ); /* Get and log the search scope */ if ( slapi_pblock_get( pb, SLAPI_SEARCH_SCOPE, &scope ) == 0 ) {
switch( scope ) { case LDAP_SCOPE_BASE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_BASE\n" );
break;
case LDAP_SCOPE_ONELEVEL:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_ONELEVEL\n" );
break;
case LDAP_SCOPE_SUBTREE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"LDAP_SCOPE_SUBTREE\n" );
break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_SCOPE",
"unknown value specified: %d\n", scope );
break;
} } /* Get and log the alias dereferencing setting */ if ( slapi_pblock_get( pb, SLAPI_SEARCH_DEREF, &deref ) == 0 ) {
switch( deref ) {
case LDAP_DEREF_NEVER:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_NEVER\n" );
break;
case LDAP_DEREF_SEARCHING:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_SEARCHING\n" );
break;
case LDAP_DEREF_FINDING:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_FINDING\n" );
break;
case LDAP_DEREF_ALWAYS:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"LDAP_DEREF_ALWAYS\n" );
Chapter 4 A Quick Example 57
Page 60
An Example Pre-Operation Plug-in
Code Example 4-1 Sample Pre-Operation Search and Initialization Functions (Continued)
break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_DEREF",
"unknown value specified: %d\n", deref );
break;
} } /* Get and log the search filter information */ if ( slapi_pblock_get(pb,SLAPI_SEARCH_FILTER, &filter)==0 ) {
/* Get and log the filter type */
filter_type = slapi_filter_get_choice( filter );
switch( filter_type ) {
case LDAP_FILTER_AND:
case LDAP_FILTER_OR:
case LDAP_FILTER_NOT:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"Complex search filter. See value of
SLAPI_SEARCH_STRFILTER.\n" );
break;
case LDAP_FILTER_EQUALITY:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_EQUALITY\n" );
break;
case LDAP_FILTER_GE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_GE\n" );
break;
case LDAP_FILTER_LE:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_LE\n" );
break;
case LDAP_FILTER_APPROX:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_APPROX\n" );
break;
case LDAP_FILTER_SUBSTRINGS:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_SUBSTRINGS\n" );
/* For substring filters, get and log the attribute type and
the substrings in the filter */ slapi_filter_get_subfilt( filter, &attr_type, &substr_init,
&substr_any, &substr_final );
if ( attr_type != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute type",
"%s\n", attr_type );
if ( substr_init != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tInitial substring",
"%s\n", substr_init );
if ( substr_any != NULL ) {
for ( i = 0; substr_any[i] != NULL; i++ ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "\tSubstring",
"# %d: %s\n", i, substr_any[i] );
} } if ( substr_final != NULL )
58 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 61
An Example Pre-Operation Plug-in
Code Example 4-1 Sample Pre-Operation Search and Initialization Functions (Continued)
slapi_log_error( SLAPI_LOG_PLUGIN, "\tFinal substring",
"%s\n", substr_final );
break;
case LDAP_FILTER_PRESENT:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_PRESENT\n" ); /* For presence filters, get and log the attribute type */ slapi_filter_get_type( filter, &attr_type ); if ( attr_type != NULL )
slapi_log_error( SLAPI_LOG_PLUGIN, "\tSearch for presence of attr",
"%s\n", attr_type );
break;
case LDAP_FILTER_EXTENDED:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER",
"LDAP_FILTER_EXTENDED\n" ); break;
default:
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_FILTER", "Unknown filter type:
slapi_filter_get_choice returned %d\n", filter_type ); break;
} } /* For comparison filters, get and log the attribute type */ if ( filter_type == LDAP_FILTER_EQUALITY || LDAP_FILTER_GE ||
LDAP_FILTER_LE || LDAP_FILTER_APPROX ) { slapi_filter_get_ava( filter, &attr_type, &bval ); if ( ( attr_type != NULL ) && ( bval->bv_val != NULL ) ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute type",
"%s\n", attr_type );
slapi_log_error( SLAPI_LOG_PLUGIN, "\tAttribute value",
"%s\n", bval->bv_val );
}
} /* Get and log the string representation of the filter */ if ( slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &filter_str) == 0 )
slapi_log_error( SLAPI_LOG_PLUGIN, "SLAPI_SEARCH_STRFILTER",
"%s\n", filter_str );
slapi_log_error( SLAPI_LOG_PLUGIN, "test_preop_search",
"*** DONE ***\n\n" );
return( 0 );
}
Compiling the Plug-in Example
On Solaris, you can use the following Makefile to compile the example. (This sample Makefile assumes that the source code is stored in you are compiling a plug-in named
srchxmpl.so
srchxmpl.c
and that
.)
Chapter 4 A Quick Example 59
Page 62
An Example Pre-Operation Plug-in
Code Example 4-2 Example Solaris Makefile
# SOLARIS Makefile for Directory Server plug-in examples # CC = cc LD = ld INCLUDE_FLAGS = -I../include CFLAGS = $(INCLUDE_FLAGS) -D_REENTRANT -KPIC LDFLAGS = -G OBJS = srchxmpl.o all: srchxmpl.so srchxmpl.so: $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS)
.c.o:
$(CC) $(CFLAGS) -c $<
clean:
-rm -f $(OBJS) srchxmpl.so
Registering the Plug-in Example
To register this example plug-in, you should do the following:
1.
Create an LDIF configuration file in an ASCII text editor; see “Creating a Plug-in Configuration File,” on page 47.
2.
Load the plug-in configuration file; see “Loading the Plug-in Configuration File,” on page 52.
3.
Shut down the Directory Server.
4.
Restart the Directory Server.
When you restart the Directory Server, it will read the entries in the
dse.ldif
file, which contain the entry for you new plug-in. If all is done correctly, your plug-in will now be loaded. (You may want to check the plug-ins list in the Directory Server Console.)
Running the Plug-in Example
After compiling the plug-in and registering it with the Directory Server, you’re ready to make calls that are processed by the plug-in functions.
The first step is to restart the Directory Server and check the error log to see that the plug-in is properly registered. You should see the following line in the error log:
60 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 63
An Example Pre-Operation Plug-in
Error log messsage here!
Verify that the plug-ins log level is selected. Error logging is controlled with the
nsslapd-errorlog-level
this value to
65536
or set an OR the current value to
attribute in
cn=config
. For the plug-ins log level, set
65536
. (The sample source code
logs messages to the error log with the plug-ins log level.)
If the plug-in is properly registered, you can then perform a few searches against the directory. The pre-operation search plug-in function should write data about each search to the error log.
Chapter 4 A Quick Example 61
Page 64
An Example Pre-Operation Plug-in
62 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 65
Basic Plug-in Programming Techniques
Chapter 5, “Front-End API Functions
Chapter 6, “Writing Pre/Post-Operation Plug-ins”
Chapter 7, “Defining Functions for LDAP Operations”
Part 2
Chapter 8, “Defining Functions for Authentication”
63
Page 66
64 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 67
Chapter 5
Front-End API Functions
The Red Hat Directory Server (Directory Server) provides some general-purpose, front-end API functions that allow you to work with the entries in the Directory Server. This chapter explains how to use the front-end API functions to accomplish various tasks; you can call these functions in your plug-in to interact with the client (for example, send results or result codes), log messages, and work with entries, attributes, and filters. While all of the functions described here must be used in conjunction with other API functions, understanding how these functions work will help you understand how to program other plug-in API functions.
This chapter contains the following sections:
Logging Messages (page 65)
Adding Notes to Access Log Entries (page 66)
Sending Data to the Client (page 66)
Determining If an Operation Was Abandoned (page 67)
Working with Entries, Attributes, and Values (page 67)
Working with DNs and RDNs (page 71)
Working with Search Filters (page 74)
Checking Passwords (page 77)
The front-end functions are declared in the
Logging Messages
To write an error message to the error log, call the For example, the following function call writes a message in the error log:
slapi-plugin.h
slapi_log_error()
header file.
function.
65
Page 68
Adding Notes to Access Log Entries
slapi_log_error( SLAPI_LOG_PLUGIN, "searchdn_preop_search",
"*** PREOPERATION SEARCH PLUGIN ***\n");
This call will create the following message in the error log:
[01/Oct/1997:02:24:18 -0700] searchdn_preop_search \
- *** PREOPERATION SEARCH PLUGIN ***
Make sure that the Directory Server is configured to log messages that have the severity that you specify (for example,
SLAPI_LOG_PLUGIN
information, see “Setting the Log Level of the Server,” on page 54. The
slapi_log_error()
output, similar to the standard
function allows you to add parameters to and format the
printf()
function. This allows you to add your
own parameters and data to the log output.
Adding Notes to Access Log Entries
When the backend database processes a search operation, it attempts to use indexes to narrow down the list of candidates matching the search criteria. If the backend is unable to use indexes, it appends the following string to the access log entry for the search:
). For more
notes="U"
This note indicates that an unindexed search was performed.
If you are writing your own backend database search function, you can append this note to access log entries by setting the to the flag
SLAPI_OP_NOTE_UNINDEXED
need to be appended to access log entries. Currently,
SLAPI_OPERATION_NOTES
parameter
. This parameter identifies any notes that
SLAPI_OP_NOTE_UNINDEXED
is the only value that you can set for this parameter. In future releases, additional flags will be defined. You will be able to use bitwise OR combinations of flags to specify different combinations of notes.
The server appends these notes and writes out the access log entries whenever sending a result or search entry back to the client.
66 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 69
Sending Data to the Client
Sometimes you might need to communicate various information directly back to the client. For example, you might want to do this in the following situations:
If you need to send a result code back to the client (for example, to report an error or a successful result to an LDAP operation), call the
slapi_send_ldap_result()
If you are fulfilling a search request and need to send matching entries back to the client, call the
If you need to refer the LDAP request to a different LDAP server, call the
slapi_send_ldap_referral()
slapi_send_ldap_search_entry()
Sending Data to the Client
function.
function for each entry.
function.
For example, the following statement sends an
LDAP_SUCCESS
status code back to
the client.
slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, \
"The operation was processed successfully.\n", 0, NULL );
NOTE
It is important that you send only one result per operation back to the client.
Determining If an Operation Was Abandoned
At any point in time, the client can choose to abandon an LDAP operation. When writing database functions, keep in mind that you should periodically check to see if the operation has been abandoned.
To determine if an operation has been abandoned, call For example:
if ( slapi_op_abandoned( pb ) ) {
slapi_log_error( SLAPI_LOG_PLUGIN, "my_function",
"The operation was abandoned.\n" );
return 1;
}
slapi_op_abandoned()
.
Chapter 5 Front-End API Functions 67
Page 70
Working with Entries, Attributes, and Values
Working with Entries, Attributes, and Values
This section discusses how to create new entries in the directory and how to convert them to LDIF and back.
In certain situations, you will need to pass directory entries between the front-end and the client. For example, it you create a custom add function, the front-end passes to your function an entry in the parameter block. When you perform a search operation, you return each matching search entry to the client.
When working with entries, you use the
Slapi_Entry
value pairs. The front-end routines listed in Table 5-1 are designed to help you manipulate entries passed in parameter blocks. These functions are described in more detail in the sections that follow the table.
Table 5-1 Front-End Functions for Manipulating Entries and Attributes
Front-end function Description
slapi_entry_alloc() Allocate memory for a new entry. slapi_entry_init() Initialize the entry created with
slapi_entry_alloc().
This must be done before any other operation can occur on the entry. Otherwise, severe memory errors may occur.
slapi_entry_dup() Copy an entry. slapi_entry_free() Free an unused entry from memory.
slapi_entry2str() slapi_entry2str_with_options() slapi_str2entry()
slapi_entry_get_dn() slapi_entry_set_dn()
Convert an entry to an LDIF string representation and vice versa.
Get or set the DN for an entry.
datatype to get attribute
slapi_entry_schema_check() Verify that an entry complies with the
slapi_entry_first_attr() slapi_entry_next_attr()
slapi_entry_attr_find() Find the values for a specified attribute.
slapi_entry_attr_merge_sv() Merge an attribute and its values into an
slapi_entry_add_values_sv() Add values to an attribute in an entry.
68 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
schema.
Get the attributes of an entry.
entry.
Page 71
Working with Entries, Attributes, and Values
Table 5-1 Front-End Functions for Manipulating Entries and Attributes (Continued)
Front-end function Description
slapi_entry_delete_values_sv() Delete values from an attribute in an entry.
Creating a New Entry
In some situations, you might need to create a new entry. There are two basic ways to do this:
By allocating memory for a new entry
To allocate memory for a new entry, call the
slapi_entry_alloc()
function.
This function returns a pointer to a new entry of the opaque datatype
Slapi_Entry
. Then, call the
slapi_entry_init()
function to initialize the entry for use with the other slapi functions. Once you create and initialize a new entry, you should call other front-end routines to set the DN and attributes of the entry.
NOTE Failing to call
slapi_entry_init()
after
slapi_entry_alloc()
may cause severe memory problems.
By copying an existing entry
To make a copy of an existing entry, call the function returns a pointer to a new entry of the datatype
slapi_entry_dup()
Slapi_Entry
routine. This
that
contains the copied data.
When you are finished using the entry, you should free it from memory by calling the
slapi_entry_free()
function.
Converting between Entries and Strings
Entries can be stored in LDIF files. When stored in these files, entries are converted into a string representation. The following format is the LDIF string representation for a directory entry:
dn:[:] dn\n [attr:[:] value\n] [attr:[:] value\n] [space continuedvalue\n]* ...
Chapter 5 Front-End API Functions 69
Page 72
Working with Entries, Attributes, and Values
If you want to continue the specification of a value on additional lines (in other words, if the value wraps around to another line), use a single space (the ASCII 32 character) at the beginning of subsequent lines. For example:
dn: cn=Jane Doe
inski, ou=Accoun ting, dc=ex ample dc=com
Refer to the Red Hat Directory Server Administrator’s Guide for details on DN syntax.
If a double-colon is used after a data type, it signifies that the value after the double-colon is encoded as a base-64 string. Data is sometimes encoded as a base-64 string. For example, it might be encoded this way if the value contains a non-printing character or newline.
To get the LDIF string representation of an entry (and vice versa), call the following functions:
To convert an entry from the datatype representation, call the
slapi_entry2str_with_options()
slapi_entry2str()
Slapi_Entry
and
functions.
to its LDIF string
This function returns the LDIF string representation of the entry or NULL if an error occurs. When you no longer need to use the string, you should free it from memory by calling the
slapi_ch_free_string()
function.
To convert an LDIF string representation back to an entry of the datatype
Slapi_Entry
This function returns an entry of the datatype
, call the
slapi_str2entry()
function.
Slapi_Entry
. If an error
occurred during the conversion process, the function returns NULL instead.
When you are done working with the entry, you should call the
slapi_entry_free()
NOTE Calling
slapi_str2entry()
function.
modifies the value of the string argument passed into the function (not a copy). If you still want to use the string representation of the entry, make a copy of the string before calling this function.
70 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 73
Working with Entries, Attributes, and Values
Getting and Setting the DN of an Entry
You can call the following two front-end routines to get and set the DN for an entry:
To get the DN for an entry, call the
To set the DN for an entry, call the
slapi_entry_get_dn()
slapi_entry_set_dn()
function.
function.
Verifying Compliance with the Schema
Before you add or modify an entry in the database, you may want to verify that the new or changed entry still complies with the database schema.
To see if an entry complies with the schema, call the
slapi_entry_schema_check()
function.
Getting the Attributes and Values of an Entry
There are two basic ways to obtain the attributes and values of an entry:
You can iterate through the attributes of the entry, testing each one to see if it is the needed attribute.
You can use the specific attribute.
slapi_entry_attr_find()
function to see if an entry has a
Once you find the attribute you are looking for, use return the value of that attribute.
slapi_attr_value_find()
Iterating through the Attributes in an Entry
To iterate through the attributes associated with an entry, call the
slapi_entry_first_attr()
function returns a pointer to the first attribute in the entry. With a pointer to the attribute, you can test to see if it is the attribute in which you are interested.
To retrieve the subsequent attributes in the entry, call
slapi_entry_next_attr()
the
cookie
slapi_entry_next_attr()
Once you find the attribute you need, you can retrieve its value using
slapi_attr_value_find()
parameter of the function. Like
function to get the first attribute of the entry. This
, passing to it the pointer to the current attribute in
slapi_entry_first_attr()
returns a pointer to the current attribute.
.
Chapter 5 Front-End API Functions 71
,
to
Page 74
Working with DNs and RDNs
Finding a Specific Attribute in an Entry
To see if an entry contains a specific attribute, call This function returns 0 if the entry contains the attribute, -1 if it does not.
Adding and Removing Values
You can also call front-end routines to add or remove attributes and values in an entry. The front-end provides the following functionality:
To add new values to an entry, call the function .
To remove values from an entry, call
In certain situations, you may want to add an attribute and its values to an entry while not replacing any attribute values that already exist. To do this, call the
slapi_entry_attr_merge_sv()
Working with DNs and RDNs
In certain situations, the front-end passes DNs to the backend through the parameter block. For example, when calling the add function, the parameter block includes a parameter that specifies the DN of the new entry to be added.
slapi_entry_attr_find()
slapi_entry_add_values_sv()
slapi_entry_delete_values_sv()
function.
.
.
If you need to manipulate DNs within parameter blocks, you can call the following front-end routines:
Table 5-2 Front-End Functions for Manipulating DNs
Function Description
slapi_dn_isroot() Determines if a DN is the root DN (the DN of the
privileged superuser).
slapi_dn_parent() slapi_dn_beparent()
slapi_dn_issuffix() Determines if a DN is the child of another DN.
slapi_dn_isbesuffix() Determines if a DN is a suffix served by one of
slapi_dn_normalize() Normalizes a DN.
slapi_dn_ignore_case() Converts all characters in a DN to lowercase.
72 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Gets a copy of the parent DN.
the server’s back-ends.
Page 75
Table 5-2 Front-End Functions for Manipulating DNs (Continued)
Function Description
slapi_dn_normalize_case() Normalizes a DN and converts all characters to
lowercase.
Determining If a DN Is the Root DN
Working with DNs and RDNs
To determine if a DN is the root DN, call
slapi_dn_isroot()
. This function returns 1 if the specified DN is the root DN of the local database. It returns 0 if the DN is not the root DN.
Working with DN Suffixes
A suffix of a DN identifies a subtree in the directory tree where the DN is located. For example, consider the following DN:
cn=Babs Jensen,ou=Product Development,l=US, dc=example,dc=com
In this case, one of the suffixes is:
l=US, dc=example,dc=com
This suffix indicates that the
Corporation
subtree in the directory tree.
To determine if a value is a suffix for a DN, call determine if a DN is one of the suffixes served by the backend, call the
slapi_dn_isbesuffix()
For more information on suffixes and backend configuration, see the Red Hat Directory Server Administrator’s Guide.
Babs Jensen
function.
entry is located in the
slapi_dn_issuffix()
Example
. To
Getting the Parent DN of a DN
To get a copy of the parent DN for a DN, call the the
slapi_dn_beparent()
These functions return the parent DN of dn. If dn is a suffix served by the backend,
slapi_dn_beparent()
When you are done working with the parent DN, you should free it from memory by calling
function.
will return
slapi_ch_free_string()
NULL
slapi_dn_parent()
function or
.
.
Chapter 5 Front-End API Functions 73
Page 76
Working with Search Filters
Normalizing a DN
You can use the following front-end function to normalize and convert the case of a DN:
Use
Use
Use
slapi_dn_normalize()
slapi_dn_ignore_case()
slapi_dn_normalize_case()
to normalize a DN.
characters in the DN to lowercase.
NOTE These functions operate on the actual DN specified in the
argument, not a copy of the DN. If you want to modify a copy of the DN, call
slapi_ch_strdup()
To compare DNs (for example, to search the database for a particular DN), use the
slapi_sdn_compare()
function instead of normalizing and comparing the
DNs using string functions.
Working with Search Filters
When a client requests an LDAP search operation, the front-end passes the search filter to the backend as part of the parameter block. (The filter is passed through the
SLAPI_SEARCH_FILTER
available in the
SLAPI_SEARCH_STRFILTER
parameter. A string representation of the filter is also
to convert all characters in a DN to lowercase.
to both normalize the DN and convert all
to make a copy of the DN.
parameter.)
To manipulate search filters, call the following front-end routines:
Table 5-3 Front-End Functions for Manipulating Filters
Function Description
slapi_filter_test() Determine if an entry matches a filter’s criteria.
slapi_filter_get_choice() Get the filter type.
slapi_filter_get_ava() Get the attribute type and value used for
74 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
comparison in an attribute-value assertion filter (only applicable to the following searches:
LDAP_FILTER_EQUALITY, LDAP_FILTER_GE, LDAP_FILTER_LE, and LDAP_FILTER_APPROX).
Page 77
Table 5-3 Front-End Functions for Manipulating Filters (Continued)
Function Description
slapi_filter_get_type() Get the type of attribute that the filter is
searching for (only applicable to
LDAP_FILTER_PRESENT searches).
slapi_filter_get_subfilt() Get the substring pattern used for the filter
(applicable only to LDAP_FILTER_SUBSTRING searches).
slapi_str2filter() Convert a string representation of a filter to a
filter of the datatype Slapi_Filter.
slapi_filter_join() Construct a new LDAP_FILTER_AND,
LDAP_FILTER_OR, or LDAP_FILTER_NOT
filter from other filters.
Working with Search Filters
slapi_filter_list_first(), slapi_filter_list_next()
slapi_filter_free() Free a filter from memory.
Determining If an Entry Matches a Filter
After retrieving a filter from the parameter block, you can call the entries in your database match the filter.
Getting the Filter Type
To determine the type of filter you are using, call This function returns the filter type, which can be any one of the following values:
Table 5-4 Types of Filters
Filter Type Description
Get the components of a filter (only applicable to LDAP_FILTER_AND, LDAP_FILTER_OR, and LDAP_FILTER_NOT searches).
SLAPI_SEARCH_FILTER
slapi_filter_test()
slapi_filter_get_choice()
parameter of the
function to determine if
.
LDAP_FILTER_AND The search should find entries matching all filters that
LDAP_FILTER_OR The search should find entries matching any filter
are specified in this complex filter.
specified in this complex filter.
Chapter 5 Front-End API Functions 75
Page 78
Working with Search Filters
Table 5-4 Types of Filters (Continued)
Filter Type Description
LDAP_FILTER_NOT The search should find entries not matching the
LDAP_FILTER_EQUALITY The search should find entries that contain a value
LDAP_FILTER_SUBSTRINGS The search should find entries that contain a value
LDAP_FILTER_GE The search should find entries that contain a value
LDAP_FILTER_LE The search should find entries that contain a value less
LDAP_FILTER_PRESENT The search should find entries that contain the
LDAP_FILTER_APPROX The search should find entries that contain a value
specified filter.
equal to the specified attribute value.
matching the specified substrings.
greater than or equal to the specified attribute value.
than or equal to the specified attribute value.
specified attribute.
approximately matching the specified attribute value.
Getting the Search Criteria
To get the search criteria specified by a search filter, call one of the following functions:
If the filter type is
LDAP_FILTER_LE
value used in the filter by calling
If the filter type is
the filter is searching for by calling the
If the filter type is
that the filter searches for by calling
To get the components of a complex filter of the type
LDAP_FILTER_OR slapi_filter_list_first()
Both of these functions will return either a filter component of the complex filter or a NULL value, according to the following:
If
slapi_list_first()
type
LDAP_FILTER_AND, LDAP_FILTER_OR
LDAP_FILTER_EQUALITY, LDAP_FILTER_GE,
, or
LDAP_FILTER_APPROX
slapi_filter_get_ava()
LDAP_FILTER_PRESENT
LDAP_FILTER_SUBSTRINGS
slapi_filter_get_subfilt()
, or
LDAP_FILTER_NOT
and
slapi_filter_list_next()
, you can get the attribute and
, you can get the attribute type that
slapi_filter_get_type()
, you can get the attribute type
LDAP_FILTER_AND,
, call the
returns a NULL, the complex filter is not of the
, or
LDAP_FILTER_NOT
.
function.
.
functions.
.
76 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 79
If
slapi_list_next()
returns a NULL, the component returned by the
call is the last component in the complex filter.
NOTE You do not need to free the values returned by the
slapi_filter_get_ava(), slapi_filter_get_type() slapi_filter_get_subfilt()
functions.
Converting a String to a Filter
Working with Search Filters
, and
A search filter can be represented by either the datatype string. In a parameter block for a search operation, of the datatype
Slapi_Filter
and
SLAPI_SEARCH_STRFILTER
SLAPI_SEARCH_FILTER
Slapi_Filter
is the string
or as a
is a filter
representation of that filter. In general, it is easier to specify a filter as a string than it is to construct a filter from the type
Slapi_Filter
.
To convert the string representation of a filter into a filter of the datatype
Slapi_Filter
, call the
slapi_str2filter()
function.
When you are done working with the filter, you should free it by calling the
slapi_filter_free()
function.
Creating Complex Filters by Combining Filters
You can use AND, OR and NOT to combine different filters to create a complex filter. To do this, call the
The
slapi_filter_join()
When you are done using the complex filter, you should free it by calling
slapi_filter_free()
Filters of the type (
ftype
) is
LDAP_FILTER_NOT
when calling
LDAP_FILTER_NOT
slapi_filter_join()
slapi_filter_join()
function.
function returns the complex filter you’ve created.
.
can have only one component. If the filter type
, you must pass a NULL value for the second filter
.
Chapter 5 Front-End API Functions 77
Page 80
Checking Passwords
Checking Passwords
By default, Directory Server uses the
userPassword
attribute to store the credentials for an entry. The server encodes the password using the scheme specified in the attributes of the
nsslapd-rootpwstoragescheme
cn=config
entry contained in the
or
passwordStorageScheme
dse.ldif
file. The scheme can
be any of the following:
CLEAR clear-password-storage-scheme
CRYPT crypt-password-storage-scheme
SHA
sha
SSHA
the
To determine if a given password is one of the values of the attribute, call
— Means no encryption and can be defined using the
plug-in.
— Means Unix crypt algorithm and can be defined using the
plug-in.
— Means Secure Hashing Algorithm and can be defined using the
-password-storage-scheme
plug-in.
— Means Salted Secure Hashing Algorithm and can be defined using
ssha-password-storage-scheme
slapi_pw_find_sv()
. This function determines which password
plug-in.
userPassword
scheme was used to store the password and uses the appropriate comparison function to compare a given value against the encrypted values of the
userPassword
attribute.
78 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 81
Chapter 6
Writing Pre/Post-Operation Plug-ins
This chapter explains how to write functions that the Red Hat Directory Server (Directory Server) calls before and after executing an LDAP operation. These functions are called pre-operation and post-operation plug-in functions.
How Pre/Post-Operation Plug-ins Work (page 79)
Types of Pre-Operation and Post-Operation Functions (page 81)
Registering Pre/Post-Operation Functions (page 84)
How Pre/Post-Operation Plug-ins Work
The Directory Server can perform the following LDAP operations: bind, unbind, search, modify, add, delete, modifyRDN, compare, and abandon.
NOTE The Directory Server can also perform extended operations as
defined in the LDAPv3 protocol. For information on implementing plug-in functions to execute extended operations, see chapter 10, “Writing Extended Operation Plug-ins.”
You can configure the Directory Server to call your custom plug-in functions before and after executing any of these LDAP operations.
For example, you can write a pre-operation function that validates an entry before the server performs an LDAP add operation. An example of a post-operation plug-in function would be one that sends a notification to a user after their entry has been modified by an LDAP modify operation.
79
Page 82
How Pre/Post-Operation Plug-ins Work
You can also set up the Directory Server to call your own plug-in functions before and after:
Sending an LDAP entry back to the client.
Sending an LDAP result code back to the client.
Sending an LDAP referral back to the client.
Figure 6-1 illustrates how the Directory Server front-end calls pre-operation and post-operation functions before and after executing an LDAP operation.
When processing a request, the Directory Server will call all registered pre-operation functions before it calls the backend to service the request. All pre-operation functions must return before the front-end calls the associated backend function.
Figure 6-1 Calling Pre-Operation and Post-Operation Plug-in Functions
80 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 83
Types of Pre-Operation and Post-Operation Functions
Types of Pre-Operation and Post-Operation Functions
As is the case with other server plug-in functions, pre-operation functions and post-operation functions are specified in a parameter block that you can set on server startup. Each function corresponds to an ID in the parameter block. In your initialization function, you can call the the name of your function that corresponds to the pre-operation or post-operation function. For more information on the parameter block, see “Getting Data from the Parameter Block,” on page 39.
Types of Pre-Operation Functions
Table 6-1 lists the Directory Server pre-operation functions and the purpose of each function.
Table 6-1 Functions Called before the Directory Server Executes an Operation
ID in Parameter Block Description
slapi_pblock_set()
function to specify
SLAPI_PLUGIN_PRE_BIND_FN Specifies the function called before the Directory Server
executes an LDAP bind operation. For information on writing this type of function, see “Processing an LDAP Bind Operation,” on page 86.
SLAPI_PLUGIN_PRE_UNBIND_FN Specifies the function called before the Directory Server
executes an LDAP unbind operation. For information on writing this type of function, see “Processing an LDAP Unbind Operation,” on page 87.
SLAPI_PLUGIN_PRE_SEARCH_FN Specifies the function called before the Directory Server
executes an LDAP search operation. For information on writing this type of function, see “Processing an LDAP Search Operation,” on page 88.
SLAPI_PLUGIN_PRE_COMPARE_FN Specifies the function called before the Directory Server
executes an LDAP compare operation. For information on writing this type of function, see “Processing an LDAP Compare Operation,” on page 91.
SLAPI_PLUGIN_PRE_ADD_FN Specifies the function called before the Directory Server
executes an LDAP add operation. For information on writing this type of function, see “Processing an LDAP Add Operation,” on page 92.
Chapter 6 Writing Pre/Post-Operation Plug-ins 81
Page 84
Types of Pre-Operation and Post-Operation Functions
Table 6-1 Functions Called before the Directory Server Executes an Operation (Continued)
ID in Parameter Block Description
SLAPI_PLUGIN_PRE_MODIFY_FN Specifies the function called before the Directory Server
executes an LDAP modify operation. For information on writing this type of function, see “Processing an LDAP Modify Operation,” on page 93.
SLAPI_PLUGIN_PRE_MODRDN_FN Specifies the function called before the Directory Server
executes an LDAP modifyRDN operation. For information on writing this type of function, see “Processing an LDAP Modify RDN Operation,” on page 95.
SLAPI_PLUGIN_PRE_DELETE_FN Specifies the function called before the Directory Server
executes an LDAP delete operation. For information on writing this type of function, see “Processing an LDAP Delete Operation.
SLAPI_PLUGIN_PRE_ABANDON_FN Specifies the function called before the Directory Server
executes an LDAP abandon operation. For information on writing this type of function, see “Processing an LDAP Abandon Operation,” on page 97.
SLAPI_PLUGIN_PRE_ENTRY_FN Specifies the function called before the Directory Server sends
an entry back to the client (for example, when you call slapi_send_ldap_search_entry(), the pre-operation entry function is called before the entry is sent back to the client).
SLAPI_PLUGIN_PRE_REFERRAL_FN Specifies the function called before the Directory Server sends
a referral back to the client (for example, when you call slapi_send_ldap_referral(), the pre-operation referral function is called before the referral is sent back to the client).
SLAPI_PLUGIN_PRE_RESULT_FN Specifies the function called before the Directory Server sends
a result code back to the client (for example, when you call slapi_send_ldap_result(), the pre-operation result function is called before the result code is sent back to the client).
Types of Post-Operation Functions
Table 6-2 lists the Directory Server post-operation functions and the purpose of each function.
82 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 85
Types of Pre-Operation and Post-Operation Functions
Table 6-2 Functions Called after the Directory Server Executes an Operation
ID in Parameter Block Description
SLAPI_PLUGIN_POST_BIND_FN Specifies the function called after the Directory Server
executes an LDAP bind operation. For information on writing this type of function, see “Processing an LDAP Bind Operation,” on page 86.
SLAPI_PLUGIN_POST_UNBIND_FN Specifies the function called after the Directory Server
executes an LDAP unbind operation. For information on writing this type of function, see “Processing an LDAP Unbind Operation,” on page 87.
SLAPI_PLUGIN_POST_SEARCH_FN Specifies the function called after the Directory Server
executes an LDAP search operation. For information on writing this type of function, see “Processing an LDAP Search Operation,” on page 88.
SLAPI_PLUGIN_POST_COMPARE_FN Specifies the function called after the Directory Server
executes an LDAP compare operation. For information on writing this type of function, see “Processing an LDAP Compare Operation,” on page 91.
SLAPI_PLUGIN_POST_ADD_FN Specifies the function called after the Directory Server
executes an LDAP add operation. For information on writing this type of function, see “Processing an LDAP Add Operation,” on page 92.
SLAPI_PLUGIN_POST_MODIFY_FN Specifies the function called after the Directory Server
executes an LDAP modify operation. For information on writing this type of function, see “Processing an LDAP Modify Operation,” on page 93.
SLAPI_PLUGIN_POST_MODRDN_FN Specifies the function called after the Directory Server
executes an LDAP modifyRDN operation. For information on writing this type of function, see “Processing an LDAP Modify RDN Operation,” on page 95.
SLAPI_PLUGIN_POST_DELETE_FN Specifies the function called after the Directory Server
executes an LDAP delete operation. For information on writing this type of function, see “Processing an LDAP Delete Operation,” on page 96.
SLAPI_PLUGIN_POST_ABANDON_FN Specifies the function called after the Directory Server
executes an LDAP abandon operation. For information on writing this type of function, see “Processing an LDAP Abandon Operation,” on page 97.
Chapter 6 Writing Pre/Post-Operation Plug-ins 83
Page 86
Registering Pre/Post-Operation Functions
Table 6-2 Functions Called after the Directory Server Executes an Operation (Continued)
ID in Parameter Block Description
SLAPI_PLUGIN_POST_ENTRY_FN Specifies the function called after the Directory Server sends
an entry back to the client (for example, when you call slapi_send_ldap_search_entry(), the post-operation entry function is called after the entry is sent back to the client).
SLAPI_PLUGIN_POST_REFERRAL_FN Specifies the function called after the Directory Server sends
a referral back to the client (for example, when you call slapi_send_ldap_referral(), the post-operation referral function is called after the referral is sent back to the client).
SLAPI_PLUGIN_POST_RESULT_FN Specifies the function called after the Directory Server sends
a result code back to the client (for example, when you call slapi_send_ldap_result(), the post-operation result function is called after the result code is sent back to the client).
Registering Pre/Post-Operation Functions
To register your pre-operation and post-operation plug-in functions, you need to write an initialization function and then configure the server to load your plug-in. For details, follow the procedures outlined in “Writing Plug-in Initialization Functions,” on page 42, and “Configuring Plug-ins,” on page 47.
84 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 87
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 information on this, see “Passing Data with Parameter Blocks,” on page 38.
Slapi_PBlock
. For more
This chapter outlines how to define plug-in functions to do the following:
Specifying Start and Close Functions (page 85)
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 91)
Processing an LDAP Add Operation (page 92)
Processing an LDAP Modify Operation (page 93)
Processing an LDAP Modify RDN Operation (page 95)
Processing an LDAP Delete Operation (page 96)
Processing an LDAP Abandon Operation (page 97)
Specifying Start and Close Functions
For each pre-operation and post-operation plug-in, you can specify a function to be called after the server starts and before the server is shut down.
85
Page 88
Processing an LDAP Bind Operation
In the plug-in init function, use the following parameters with
slapi_pblock_set()
SLAPI_PLUGIN_START_FN Specifies the function called after the Directory Server
SLAPI_PLUGIN_CLOSE_FN Specifies the function called before the Directory Server
to specify these functions:
starts up.
shuts down.
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
The
You register your plug-in functions by calling 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.”
SLAPI_PLUGIN_PRE_BIND_FN
function.
SLAPI_PLUGIN_POST_BIND_FN
bind function.
parameter specifies the pre-operation bind
parameter specifies the post-operation
slapi_pblock_set()
to set these
86 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 89
Processing an LDAP Unbind Operation
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 *
SLAPI_BIND_RET_SASLCREDS struct
berval *
SLAPI_BIND_SASLMECHANISM char * SASL mechanism used; for example,
If the
SLAPI_BIND_SASLMECHANISM
Credentials from the bind request.
Credentials that you want sent back to the client. Set this before calling
slapi_send_ldap_result().
LDAP_SASL_EXTERNAL.
parameter is empty, simple authentication was
used, and simple credentials were provided.
Processing an LDAP Unbind Operation
When the Directory Server receives an LDAP front-end calls the
unbind
function for each backend. No operation-specific
parameters are placed in the parameter block that is passed to the
In the parameter block, the following parameters specify plug-in functions that are called in the process of executing an
unbind
unbind
operation:
request from a client, the
unbind
function.
The
The
SLAPI_PLUGIN_PRE_UNBIND_FN
unbind
SLAPI_PLUGIN_POST_UNBIND_FN
unbind
You set these parameters to the names of your functions by calling
slapi_pblock_set()
parameter specifies the pre-operation
function.
parameter specifies the post-operation
function.
.
Chapter 7 Defining Functions for LDAP Operations 87
Page 90
Processing an LDAP Search Operation
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 checks the index for the 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 88.
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 function for each candidate in the list. For details, see “Iterating through Candidates,” on page 90.
The rest of this section explains these stages in more detail.
mail
attribute (if the index exists), finds the keys that
mail=a*
next candidate
, the server
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 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.
slapi_dn_normalize()
function and
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
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.
88 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
function for that backend.
Page 91
Processing an LDAP Search Operation
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_ORIGINAL_TARGET_DN char * The original DN sent by the client
(this DN is normalized by SLAPI_SEARCH_TARGET); read-only parameter.
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.
Chapter 7 Defining Functions for LDAP Operations 89
Page 92
Processing an LDAP Search Operation
Parameter ID Data Type Description
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 function to assign the set of search results to the
SLAPI_SEARCH_RESULT_SET
slapi_pblock_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 90) 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 parameters (which are set by the front-end and the backend during the course of executing a search operation):
next entry
function has access to the following
Parameter ID Data Type Description
SLAPI_SEARCH_RESULT_SET void * Set of search results.
SLAPI_SEARCH_RESULT_ENTRY void * Entry returned from iterating
90 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
through the results set. This “next entry” function actually sets this parameter.
Page 93
Processing an LDAP Compare Operation
Parameter ID Data Type Description
SLAPI_SEARCH_RESULT_ENTRY_EXT void * 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 **
The
next entry
the parameter as the value of the
function should get the next result specified in the set of results in
SLAPI_SEARCH_RESULT_SET
SLAPI_SEARCH_RESULT_ENTRY
. The function should set this next entry
Array of the URLs to other
LDAP servers to which the
current server is referring the
client.
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
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
SLAPI_SEARCH_RESULT_ENTRY
parameter to NULL and return 0.
next entry
function should set the
parameter
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.
Chapter 7 Defining Functions for LDAP Operations 91
Page 94
Processing an LDAP Add Operation
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 *
The compare function should call
LDAP_COMPARE_TRUE
attribute or
LDAP_COMPARE_FALSE
if the specified value is equal to the value of the entry’s
slapi_send_ldap_result()
if the values are not equal.
Attribute value to use in the comparison
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.
to send
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
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()
the client. According to the LDAP protocol, the client does not expect a server response after an operation is abandoned.)
92 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
opaque Slapi_Entry datatype).
to send an LDAP error code to
Page 95
Processing an LDAP Modify Operation
If the entry already exists in the database, the function should call
slapi_send_ldap_result() LDAP_ALREADY_EXISTS
and should return -1.
to send an LDAP error code
If the parent entry (or the closest matching entry) is a referral entry (an entry
with the object class request, the function should call
ref
) and no
manageDSAIT
slapi_send_ldap_referral()
control is included with the
to send a
referral and return -1.
To determine if a get the value of the
manageDSAIT
SLAPI_MANAGEDSAIT
control is present, call
slapi_pblock_get()
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() LDAP_NO_SUCH_OBJECT
and return -1.
If the entry is not schema-compliant (call
determine this), the function should call the LDAP error code
LDAP_OBJECT_CLASS_VIOLATION
to send an LDAP error code
slapi_entry_schema_check()
slapi_send_ldap_result()
and should return -1.
If the requestor does not have permission to add the entry (call
slapi_access_allowed() slapi_send_ldap_result() LDAP_INSUFFICIENT_ACCESS
to determine this), the function should call
to send the LDAP error code and should return -1.
You should also verify that the ACI syntax for the entry is correct; call
slapi_acl_check_mods()
If the
add
function is successful, the function should call
slapi_send_ldap_result()
to determine this.
to send an
LDAP_SUCCESS
code back to the client
and should return 0.
to
to
to send
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.
Chapter 7 Defining Functions for LDAP Operations 93
Page 96
Processing an LDAP Modify Operation
Parameter ID Data Type Description
SLAPI_MODIFY_MODS LDAPMod ** A NULL-terminated array of LDAPMod
The
modify
If the operation has been abandoned, the function should return -1. (You do
not need to call the client. According to the LDAP protocol, the client does not expect a server response after an operation is abandoned.)
structures, which represent the modifications to be performed on the entry.
function should check the following:
slapi_send_ldap_result()
to send an LDAP error code to
If the entry is a referral entry (an entry with the object class
manageDSAIT slapi_send_ldap_referral()
To determine if a to get the value of the
control is included with the request, the function should call
to send a referral and return -1.
manageDSAIT
SLAPI_MANAGEDSAIT
control is present, call
parameter. If the value is 1, the
ref
) and no
slapi_pblock_get()
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()
Otherwise, the function should call an LDAP error code
LDAP_NO_SUCH_OBJECT
If the entry is not schema-compliant (call
determine this), the function should call the LDAP error code
LDAP_OBJECT_CLASS_VIOLATION
to send a referral and return -1.
slapi_send_ldap_result()
and return -1.
slapi_entry_schema_check()
slapi_send_ldap_result()
and should return -1.
to send
to
to send
If the RDN of the entry contains attribute values that are not part of the entry
(for example, if the RDN is has a different
slapi_send_ldap_result() LDAP_NOT_ALLOWED_ON_RDN
uid
value), the function should call
uid=bjensen
, but the entry has no
to send the LDAP error code
and should return -1.
uid
value or
If the requestor does not have permission to modify the entry (call
slapi_access_allowed() slapi_send_ldap_result() LDAP_INSUFFICIENT_ACCESS
94 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
to determine this), the function should call
to send the LDAP error code and should return -1.
Page 97
Processing an LDAP Modify RDN Operation
You should also verify that the ACI syntax for the entry is correct; call
slapi_acl_check_mods()
If the
modify
slapi_send_ldap_result()
function is successful, the function should call
to determine this.
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 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 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
manageDSAIT slapi_send_ldap_referral()
slapi_send_ldap_result()
to send an LDAP error code to
ref
) and no
control is included with the request, the function should call
to send a referral and return -1.
Chapter 7 Defining Functions for LDAP Operations 95
Page 98
Processing an LDAP Delete Operation
To determine if a to get the value of the
manageDSAIT
SLAPI_MANAGEDSAIT
control is present, call
slapi_pblock_get()
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()
Otherwise, the function should call an LDAP error code
LDAP_NO_SUCH_OBJECT
If the entry is not schema-compliant (call determine this), the function should call the LDAP error code
LDAP_OBJECT_CLASS_VIOLATION
to send a referral and return -1.
slapi_send_ldap_result()
and return -1.
slapi_entry_schema_check()
slapi_send_ldap_result()
and should return -1.
to send
to
to send
If the RDN of the entry contains attribute values that are not part of the entry (for example, if the RDN is has a different
slapi_send_ldap_result() LDAP_NOT_ALLOWED_ON_RDN
uid
value), the function should call
uid=bjensen
, but the entry has no
to send the LDAP error code
and should return -1.
uid
value or
If the requestor does not have permission to modify the entry (call
slapi_access_allowed() slapi_send_ldap_result() LDAP_INSUFFICIENT_ACCESS
to determine this), the function should call
to send the LDAP error code and should return -1.
You should also verify that the ACI syntax for the entry is correct; call
slapi_acl_check_mods()
If the
modifyRDN
slapi_send_ldap_result()
function is successful, the function should call
to determine this.
to send an
LDAP_SUCCESS
and should return 0.
Processing an LDAP Delete Operation
When the Directory Server receives an LDAP 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.
delete
code back to the client
request from a client, the
96 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Page 99
Processing an LDAP Abandon Operation
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.
Parameter ID Data Type Description
SLAPI_ABANDON_MSGID unsigned long Message ID of the operation to
abandon.
Chapter 7 Defining Functions for LDAP Operations 97
Page 100
Processing an LDAP Abandon Operation
98 Red Hat Directory Server Plug-in Programmer’s Guide • May 2005
Loading...