mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
633 lines
16 KiB
633 lines
16 KiB
<?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>
|
|
|