The following example shows a code excerpt from the source file install-path/examples/testbind.c.
#include "slapi-plugin.h" int test_bind(Slapi_PBlock * pb) { char * dn; /* Target DN */ int method; /* Authentication method */ struct berval * credentials; /* Client SASL credentials */ Slapi_DN * sdn = NULL; /* DN used in internal srch */ char * attrs[2] = { /* Look at userPassword only */ SLAPI_USERPWD_ATTR, NULL }; Slapi_Entry * entry = NULL; /* Entry returned by srch */ Slapi_Attr * attr = NULL; /* Pwd attr in entry found */ int is_repl; /* Is this replication? */ int is_intl; /* Is this an internal op? */ int connId, opId, rc = 0; long msgId; /* Obtain the bind information from the parameter block. */ rc |= slapi_pblock_get(pb, SLAPI_BIND_TARGET, &dn); rc |= slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method); rc |= slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &credentials); rc |= slapi_pblock_get(pb, SLAPI_OPERATION_MSGID, &msgId); rc |= slapi_pblock_get(pb, SLAPI_CONN_ID, &connId); rc |= slapi_pblock_get(pb, SLAPI_OPERATION_ID, &opId); rc |= slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_repl); rc |= slapi_pblock_get(pb, SLAPI_IS_INTERNAL_OPERATION, &is_intl); if (rc != 0) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, SLAPI_LOG_NO_MSGID, SLAPI_LOG_NO_CONNID, SLAPI_LOG_NO_OPID, "test_bind in test-bind plug-in", "Could not get parameters for bind operation (error %d).\n", rc ); slapi_send_ldap_result( pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); return (LDAP_OPERATIONS_ERROR);/* Server aborts bind here. */ } /* The following code handles simple authentication, where a * user offers a bind DN and a password for authentication. * * Handling simple authentication is a matter of finding the * entry corresponding to the bind DN sent in the request, * then if the entry is found, checking whether the password * sent in the request matches a value found on the * userPassword attribute of the entry. */ /* Avoid interfering with replication or internal operations. */ if (!is_repl && !is_intl) switch (method) { case LDAP_AUTH_SIMPLE: /* Find the entry specified by the bind DN... */ sdn = slapi_sdn_new_dn_byref(dn); rc |= slapi_search_internal_get_entry( sdn, attrs, &entry, plugin_id ); slapi_sdn_free(&sdn); if (rc != 0 || entry == NULL) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Could not find entry: %s\n", dn ); rc = LDAP_NO_SUCH_OBJECT; slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); return (rc); } else { /* ...check credentials against the userpassword... */ Slapi_Value * credval; /* Value of credentials */ Slapi_ValueSet * pwvalues; /* Password attribute values */ rc |= slapi_entry_attr_find( entry, SLAPI_USERPWD_ATTR, &attr ); if (attr == NULL) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Entry %s has no userpassword.\n", dn ); rc = LDAP_INAPPROPRIATE_AUTH; slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); return (rc); } rc |= slapi_attr_get_valueset( attr, &pwvalues ); if (rc != 0 || slapi_valueset_count(pwvalues) == 0) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Entry %s has no %s attribute values.\n", dn, SLAPI_USERPWD_ATTR ); rc = LDAP_INAPPROPRIATE_AUTH; slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); slapi_valueset_free(pwvalues); return (rc); } credval = slapi_value_new_berval(credentials); rc = slapi_pw_find_valueset(pwvalues, credval); slapi_value_free(&credval); slapi_valueset_free(pwvalues); if (rc != 0) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Credentials are not correct.\n" ); rc = LDAP_INVALID_CREDENTIALS; slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); return (rc); } } /* ...if successful, set authentication for the connection. */ if (rc != 0) return (rc); rc |=slapi_pblock_set(pb, SLAPI_CONN_DN, slapi_ch_strdup(dn)); rc |=slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, SLAPD_AUTH_SIMPLE); if (rc != 0) { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Failed to set connection info.\n" ); rc = LDAP_OPERATIONS_ERROR; slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); return (rc); } else { slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Authenticated: %s\n", dn ); /* Now that authentication succeeded, the plug-in * returns a value greater than 0, even though the * authentication has been successful. A return * code > 0 tells the server not to continue * processing the bind. A return code of 0, such * as LDAP_SUCCESS tells the server to continue * processing the operation. */ slapi_send_ldap_result( pb, LDAP_SUCCESS, NULL, NULL, 0, NULL); rc = 1; } break; /* This plug-in supports only simple authentication. */ case LDAP_AUTH_NONE: /* Anonymous binds are handled by the front-end before * pre-bind plug-in functions are called, so this * part of the code should never be reached. */ case LDAP_AUTH_SASL: default: slapi_log_info_ex( SLAPI_LOG_INFO_AREA_PLUGIN, SLAPI_LOG_INFO_LEVEL_DEFAULT, msgId, connId, opId, "test_bind in test-bind plug-in", "Plug-in does not handle auth. method: %d\n", method ); rc = 0; /* Let server handle bind. */ break; } return (rc); /* Server stops processing * the bind if rc > 0. */ }
The bulk of the code processes the LDAP_AUTH_SIMPLE case. In the simple authentication case, the plug-in uses the DN and the password to authenticate the user binding through plug-in API calls.