JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Oracle Directory Server Enterprise Edition Developer's Guide 11 g Release 1 (11.1.1.5.0)
search filter icon
search icon

Document Information

Preface

Part I Directory Server Plug-In API Guide

1.  Before You Start Writing Plug-Ins

2.  Changes to the Plug-In API Since Directory Server 5.2

3.  Getting Started With Directory Server Plug-Ins

4.  Working With Entries Using Plug-Ins

5.  Extending Client Request Handling Using Plug-Ins

6.  Handling Authentication Using Plug-Ins

7.  Performing Internal Operations With Plug-Ins

8.  Writing Entry Store and Entry Fetch Plug-Ins

9.  Writing Extended Operation Plug-Ins

10.  Writing Matching Rule Plug-Ins

11.  Writing Password Storage Scheme Plug-Ins

12.  Writing Password Quality Check Plug-Ins

How Directory Server Uses Password Quality Check Plug-Ins

Password Policy to Check Password Quality

Whether to Implement a Password Check Plug-In

What a Password Check Plug-In Must Do

Writing a Custom Password Quality Check Plug-In

Checking Password Values

Initializing the Password Check Plug-In

Testing the Password Check Plug-In

To Set Up an Example Suffix

To Register the Plug-In

To Use the Password Check Plug-In

13.  Writing Computed Attribute Plug-Ins

Part II Directory Server Plug-In API Reference

14.  Data Type and Structure Reference

15.  Function Reference, Part I

16.  Function Reference, Part II

17.  Parameter Block Reference

A.  NameFinder Application

Prerequisite Software

Deploying NameFinder

Configuring NameFinder to Access Your Directory

Customizing NameFinder

Index

Writing a Custom Password Quality Check Plug-In

This section demonstrates how to write a plug-in that performs a simple password quality check.

Only code excerpts are shown in this chapter. The complete code example can be found where you installed Directory Server, install-path/examples/pwdcheck.c.

Checking Password Values

When Directory Server receives a request to add or modify a userPassword value, the server calls the registered passwordcheck plug-in. The server passes one or more values as a set of Slapi_Value structures in the parameter block. You can retrieve these values with slapi_pblock_get().

#include "slapi-plugin.h"

static int
check_pwd(Slapi_PBlock * pb)
{
    Slapi_Value ** pwdvals = NULL;
    slapi_pblock_get(pb, SLAPI_PASSWDCHECK_VALS, &pwdvals;);
}

Your code must then return zero, 0, when password values are acceptable. Your code must return nonzero when password values are unacceptable. In the simple case where bad password values are only those equal to secret12, the code is a quick strcmp.

#include "slapi-plugin.h"

/* Reject password values equal to secret12.               */
static int
check_pwd(Slapi_PBlock * pb)
{
    Slapi_Value ** pwdvals = NULL;

…

    /* Do not check values if none exist. */
    if (pwdvals == NULL) return 0;

    for (i=0 ; pwdvals[i] != NULL; i++) {
        const char * password = slapi_value_get_string(pwdvals[i]);
        if (strcmp("secret12", password) == 0) {
            slapi_pblock_set(pb, SLAPI_RESULT_TEXT,
               slapi_ch_strdup("invalid password syntax: Bad password!"));
            return 1;
        }
    }
    return 0;
}

Here, the code has Directory Server reject a password only when its value is secret12.

Initializing the Password Check Plug-In

Password check plug-ins register a password checking function, SLAPI_PLUGIN_PASSWDCHECK_FN, during initialization with the server.

#include "slapi-plugin.h"

int
pwdcheck_init(Slapi_PBlock * pb)
{
    int rc = 0;
    rc |=   slapi_pblock_set(
                pb,
                SLAPI_PLUGIN_VERSION,
                SLAPI_PLUGIN_CURRENT_VERSION
            );

    rc |=   slapi_pblock_set(
                pb,
                SLAPI_PLUGIN_DESCRIPTION,
                (void *) &pwd_desc; /* See the code for pwd_desc. */
            );

    rc |=   slapi_pblock_set(
                pb,
                SLAPI_PLUGIN_PASSWDCHECK_FN,
                (void *) check_pwd
            );
    return rc;
}

You can implement your own dictionary check that caches the dictionary content from a large file. In this case, load the dictionary as part of a plug-in start function rather than part of plug-in initialization. Thus, you avoid blocking startup of the server while the cache is constructed.

Testing the Password Check Plug-In

You test the plug-in using sample data delivered with Directory Server You use command-line tools to setup and register the plug-in.

To Set Up an Example Suffix

If you have not done so already, set up a directory instance with a suffix, dc=example,dc=com, containing data loaded from a sample LDIF file, install-path/resources/ldif/Example.ldif.

  1. Create a new Directory Server instance.

    For example:

    $ dsadm create -h localhost -p 1389 /local/ds
    Choose the Directory Manager password:
    Confirm the Directory Manager password:
    $ 
  2. Start the new Directory Server instance.

    For example:

    $ dsadm start /local/ds
    Server started: pid=4705
    $ 
  3. Create a suffix called dc=example,dc=com.

    For example, with long lines folded for the printed page:

    $ dsconf create-suffix -h localhost -p 1389 dc=example,dc=com
    Enter "cn=directory manager" password: 
    Certificate "CN=defaultCert, CN=hostname:1636" presented by the
     server is not trusted.
    Type "Y" to accept, "y" to accept just once,
     "n" to refuse, "d" for more details: Y
    $ 
  4. Load the sample LDIF.

    For example, with long lines folded for the printed page:

    $ dsconf import -h localhost -p 1389 \
     install-path/resources/ldif/Example.ldif dc=example,dc=com
    Enter "cn=directory manager" password:  
    New data will override existing data of the suffix
     "dc=example,dc=com".
    Initialization will have to be performed on replicated suffixes. 
    Do you want to continue [y/n] ? y
    
    ## Index buffering enabled with bucket size 16
    ## Beginning import job...
    ## Processing file "install-path/resources/ldif/Example.ldif"
    ## Finished scanning file "install-path/resources/ldif/Example.ldif" (160 entries)
    ## Workers finished; cleaning up...
    ## Workers cleaned up.
    ## Cleaning up producer thread...
    ## Indexing complete.
    ## Starting numsubordinates attribute generation.
     This may take a while, please wait for further activity reports.
    ## Numsubordinates attribute generation complete. Flushing caches...
    ## Closing files...
    ## Import complete. Processed 160 entries in 5 seconds.
     (32.00 entries/sec)
    
    Task completed (slapd exit code: 0).
    $ 

See Also

You can use Directory Service Control Center to perform this task. For more information, see the Directory Service Control Center online help.

To Register the Plug-In

If you have not already done so, build the example plug-in library and activate both plug-in informational logging and the example plug-in.

  1. Build the plug-in.

    Hint Use install-path/examples/Makefile or install-path/examples/Makefile64.

  2. Configure Directory Server to log plug-in informational messages and load the plug-in.
     $ dsconf create-plugin -F custom-plugin-init-function -G custom-plugin-argument -H lib-path \
    -Y custom-plugin-type "Custom Plugin"
    $ dsconf enable-plugin "Custom Plugin"

    Hint For more information, use the commands specified in the plug-in source file.

  3. Restart Directory Server.
    $ dsadm restart instance-path

To Use the Password Check Plug-In

Before You Begin

Populate the suffix dc=example,dc=com with sample data. Also, register the plug-in with Directory Server.

  1. Enforce password quality checking so Directory Server calls your password check plug-in.
    $ dsconf set-server-prop -h localhost -p 1389 \
     pwd-check-enabled:on pwd-strong-check-enabled:off
  2. Enable logging of informational messages.
    $ dsconf set-log-prop -h localhost -p 1389 error level:err-plugins
  3. Prepare an entry that tests your password quality check.
    $ cat quentin.ldif
    dn: uid=qcubbins,ou=People,dc=example,dc=com
    objectclass: top
    objectclass: person
    objectclass: organizationalPerson
    objectclass: inetOrgPerson
    uid: qcubbins
    givenName: Quentin
    sn: Cubbins
    cn: Quentin Cubbins
    mail: quentin.cubbins@example.com
    userPassword: secret12
  4. Add the entry to the directory.
    $ ldapmodify -a -D uid=kvaughan,ou=people,dc=example,dc=com \
    -w bribery -h localhost -p 1389 -f quentin.ldif
    
    adding new entry uid=qcubbins,ou=People,dc=example,dc=com
    ldap_add_s: Constraint violation
  5. Check the errors log for further information.
    $ grep secret12 /local/ds/logs/errors
    [16/Feb/2006:18:13:06 +0100] - INFORMATION - 
    Sample password check plug-in - conn=0 op=1 msgId=2 -  
    Invalid password: secret12

    The example log message as shown has been wrapped for readability in the printed version of this document.