123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632 |
- <?xml version="1.0" encoding='ISO-8859-1'?>
- <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
- "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
- <!-- Include general documentation entities -->
- <!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
- %docentities;
- ]>
- <!-- LDAP_H350 Module Developer's Guide -->
- <chapter>
- <title>&develguide;</title>
- <section>
- <title>Overview</title>
- <para>
- The LDAP module API can be used by other &kamailio; modules to implement
- LDAP search functionality. This frees the module implementer from having
- to care about LDAP connection management and configuration.
- </para>
- <para>
- In order to use this API, a module has to load the API using the <varname>load_ldap_api</varname>
- function which returns a pointer to a <varname>ldap_api</varname> structure. This structure
- includes pointers to the API functions described below. The LDAP module source file
- <varname>api.h</varname> includes all declarations needed to load the API, it has to
- be included in the file that use the API. Loading the API is typically done inside a
- module's <varname>mod_init</varname> call as the following example shows:
- <example>
- <title>Example code fragment to load LDAP module API</title>
- <programlisting><![CDATA[
- #include "../../sr_module.h"
- #include "../ldap/api.h"
- /*
- * global pointer to ldap api
- */
- extern ldap_api_t ldap_api;
- ...
- static int mod_init(void)
- {
- /*
- * load the LDAP API
- */
- if (load_ldap_api(&ldap_api) != 0)
- {
- LM_ERR("Unable to load LDAP API - this module requires ldap module\n");
- return -1;
- }
- ...
- }
- ...
- ]]>
- </programlisting>
- </example>
- </para>
- <para>
- The API functions can then be used like in the following example:
- <example>
- <title>Example LDAP module API function call</title>
- <programlisting><![CDATA[
- ...
-
- rc = ldap_api.ldap_rfc4515_escape(str1, str2, 0);
-
- ...
- ]]>
- </programlisting>
- </example>
- </para>
-
- </section>
-
- <section>
- <title>API Functions</title>
-
- <section>
- <title>ldap_params_search</title>
- <para>
- Performs an LDAP search using the parameters given as function arguments.
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_params_search_t)(int* _ld_result_count,
- char* _lds_name,
- char* _dn,
- int _scope,
- char** _attrs,
- char* _filter,
- ...);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>int* _ld_result_count</term>
- <listitem>
- <para>
- The function stores the number of returned LDAP entries
- in <varname>_ld_result_count</varname>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>char* _lds_name</term>
- <listitem>
- <para>
- LDAP session name as configured in the LDAP
- module configuration file.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>char* _dn</term>
- <listitem>
- <para>
- LDAP search DN.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>int _scope</term>
- <listitem>
- <para>
- LDAP search scope, one of <varname>LDAP_SCOPE_ONELEVEL</varname>,
- <varname>LDAP_SCOPE_BASE</varname>, or <varname>LDAP_SCOPE_SUBTREE</varname>,
- as defined in OpenLDAP's <varname>ldap.h</varname>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>char** _attrs</term>
- <listitem>
- <para>
- A null-terminated array of attribute types to return from entries.
- If empty (<varname>NULL</varname>), all attribute types are returned.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>char* _filter</term>
- <listitem>
- <para>
- LDAP search filter string according to RFC 4515.
- <varname>printf</varname> patterns in this string do get replaced with
- the function arguments' values following the <varname>_filter</varname> argument.
- </para>
- </listitem>
- </varlistentry>
-
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- Internal error.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, <varname>_ld_result_count</varname> includes the number of LDAP entries found.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_url_search</title>
- <para>
- Performs an LDAP search using an LDAP URL.
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_url_search_t)(char* _ldap_url,
- int* _result_count);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>char* _ldap_url</term>
- <listitem>
- <para>
- LDAP URL as described in <xref linkend="ldap-urls" />.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>int* _result_count</term>
- <listitem>
- <para>
- The function stores the number of returned LDAP entries in <varname>_ld_result_count</varname>.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- Internal error.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, <varname>_ld_result_count</varname> includes the number of LDAP entries found.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_result_attr_vals</title>
- <para>
- Retrieve the value(s) of a returned LDAP attribute. The function accesses
- the LDAP result returned by the last call of <varname>ldap_params_search</varname>
- or <varname>ldap_url_search</varname>. The <varname>berval</varname> structure is
- defined in OpenLDAP's <varname>ldap.h</varname>, which has to be included.
- </para>
- <para>
- This function allocates memory to store the LDAP attribute value(s). This memory
- has to freed with the function <varname>ldap_value_free_len</varname> (see next section).
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_result_attr_vals_t)(str* _attr_name,
- struct berval ***_vals);
-
- typedef struct berval {
- ber_len_t bv_len;
- char *bv_val;
- } BerValue;
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>str* _attr_name</term>
- <listitem>
- <para>
- <varname>str</varname> structure holding the LDAP attribute name.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>struct berval ***_vals</term>
- <listitem>
- <para>
- A null-terminated array of the attribute's value(s).
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- Internal error.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, <varname>_vals</varname> includes the attribute's value(s).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>1</term>
- <listitem>
- <para>
- No attribute value found.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_value_free_len</title>
- <para>
- Function used to free memory allocated by <varname>ldap_result_attr_vals</varname>.
- The <varname>berval</varname> structure is defined in OpenLDAP's
- <varname>ldap.h</varname>, which has to be included.
- </para>
- <programlisting><![CDATA[
- typedef void (*ldap_value_free_len_t)(struct berval **_vals);
- typedef struct berval {
- ber_len_t bv_len;
- char *bv_val;
- } BerValue;
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>struct berval **_vals</term>
- <listitem>
- <para>
- <varname>berval</varname> array returned by <varname>ldap_result_attr_vals</varname>.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_result_next</title>
- <para>
- Increments the LDAP result pointer.
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_result_next_t)();
- ]]>
- </programlisting>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- No LDAP result found, probably because <varname>ldap_params_search</varname>
- or <varname>ldap_url_search</varname> was not called.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, LDAP result pointer points now to next result.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>1</term>
- <listitem>
- <para>
- No more results available.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_str2scope</title>
- <para>
- Converts LDAP search scope string into integer value e.g. for <varname>ldap_params_search</varname>.
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_str2scope_t)(char* scope_str);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>char* scope_str</term>
- <listitem>
- <para>
- LDAP search scope string. One of "one", "onelevel", "base", "sub", or "subtree".
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- <varname>scope_str</varname> not recognized.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>n >= 0</term>
- <listitem>
- <para>
- LDAP search scope integer.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>ldap_rfc4515_escape</title>
- <para>
- Applies escaping rules described in <xref linkend="ldap-filter-url-encode-fn" />.
- </para>
- <programlisting><![CDATA[
- typedef int (*ldap_rfc4515_escape_t)(str *sin, str *sout, int url_encode);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>str *sin</term>
- <listitem>
- <para>
- <varname>str</varname> structure holding the string to apply the escaping rules.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>str *sout</term>
- <listitem>
- <para>
- <varname>str</varname> structure holding the escaped string. The length of this string must be at least three times the length of <varname>sin</varname> plus one.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>int url_encode</term>
- <listitem>
- <para>
- Flag that specifies if a '?' character gets escaped with '%3F' or not. If <varname>url_encode</varname> equals <varname>0</varname>, '?' does not get escaped.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- Internal error.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, <varname>sout</varname> contains escaped string.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>get_ldap_handle</title>
- <para>
- Returns the OpenLDAP LDAP handle for a specific LDAP session. This allows a module
- implementor to use the OpenLDAP API functions directly, instead of using the API
- functions exported by the &kamailio; LDAP module. The <varname>LDAP</varname> structure
- is defined in OpenLDAP's <varname>ldap.h</varname>, which has to be included.
- </para>
- <programlisting><![CDATA[
- typedef int (*get_ldap_handle_t)(char* _lds_name, LDAP** _ldap_handle);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>char* _lds_name</term>
- <listitem>
- <para>
- LDAP session name as specified in the LDAP module configuration file.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>LDAP** _ldap_handle</term>
- <listitem>
- <para>
- OpenLDAP LDAP handle returned by this function.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <variablelist>
- <title>Return Values:</title>
- <varlistentry>
- <term>-1</term>
- <listitem>
- <para>
- Internal error.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>0</term>
- <listitem>
- <para>
- Success, <varname>_ldap_handle</varname> contains the OpenLDAP LDAP handle.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
-
- <section>
- <title>get_last_ldap_result</title>
- <para>
- Returns the OpenLDAP LDAP handle and OpenLDAP result handle of the last LDAP search
- operation. These handles can be used as input for OpenLDAP LDAP result API functions.
- <varname>LDAP</varname> and <varname>LDAPMessage</varname> structures are defined in
- OpenLDAP's <varname>ldap.h</varname>, which has to be included.
- </para>
- <programlisting><![CDATA[
- typedef void (*get_last_ldap_result_t)
- (LDAP** _last_ldap_handle, LDAPMessage** _last_ldap_result);
- ]]>
- </programlisting>
- <variablelist>
- <title>Function arguments:</title>
- <varlistentry>
- <term>LDAP** _last_ldap_handle</term>
- <listitem>
- <para>
- OpenLDAP LDAP handle returned by this function.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>LDAPMessage** _last_ldap_result</term>
- <listitem>
- <para>
- OpenLDAP result handle returned by this function.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- </section>
- <section>
- <title>Example Usage</title>
- <para>
- The following example shows how this API can be used to perform an LDAP search operation.
- It is assumed that the API is loaded and available through the <varname>ldap_api</varname> pointer.
- </para>
- <programlisting><![CDATA[
- ...
-
- int rc, ld_result_count, scope = 0;
- char* sip_username = "test";
- /*
- * get LDAP search scope integer
- */
- scope = ldap_api.ldap_str2scope("sub");
- if (scope == -1)
- {
- LM_ERR("ldap_str2scope failed\n");
- return -1;
- }
- /*
- * perform LDAP search
- */
- if (ldap_api.ldap_params_search(
- &ld_result_count,
- "campus",
- "dc=example,dc=com",
- scope,
- NULL,
- "(&(objectClass=SIPIdentity)(SIPIdentityUserName=%s))",
- sip_username)
- != 0)
- {
- LM_ERR("LDAP search failed\n");
- return -1;
- }
- /*
- * check result count
- */
- if (ld_result_count < 1)
- {
- LM_ERR("LDAP search returned no entry\n");
- return 1;
- }
- /*
- * get password attribute value
- */
-
- struct berval **attr_vals = NULL;
- str ldap_pwd_attr_name = str_init("SIPIdentityPassword");
- str res_password;
- rc = ldap_api.ldap_result_attr_vals(&ldap_pwd_attr_name, &attr_vals);
- if (rc < 0)
- {
- LM_ERR("ldap_result_attr_vals failed\n");
- ldap_api.ldap_value_free_len(attr_vals);
- return -1;
- }
- if (rc == 1)
- {
- LM_INFO("No password attribute value found for [%s]\n", sip_username);
- ldap_api.ldap_value_free_len(attr_vals);
- return 2;
- }
- res_password.s = attr_vals[0]->bv_val;
- res_password.len = attr_vals[0]->bv_len;
- ldap_api.ldap_value_free_len(attr_vals);
- LM_INFO("Password for user [%s]: [%s]\n", sip_username, res_password.s);
- ...
- return 0;
- ]]>
- </programlisting>
- </section>
- </chapter>
|