ldap_exp_fn.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ldap_exp_fn.c 4585 2008-08-06 08:20:30Z klaus_darilion $
00003  *
00004  * Kamailio LDAP Module
00005  *
00006  * Copyright (C) 2007 University of North Carolina
00007  *
00008  * Original author: Christian Schlatter, cs@unc.edu
00009  *
00010  *
00011  * This file is part of Kamailio, a free SIP server.
00012  *
00013  * Kamailio is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version
00017  *
00018  * Kamailio is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  * History:
00028  * --------
00029  * 2007-02-18: Initial version
00030  */
00031 
00032 
00033 #include <string.h>
00034 #include <stdio.h>
00035 
00036 #include <ldap.h>
00037 
00038 #include "../../ut.h"
00039 #include "../../str.h"
00040 #include "../../pvar.h"
00041 #include "../../usr_avp.h"
00042 #include "../../mem/mem.h"
00043 #include "ldap_exp_fn.h"
00044 #include "ldap_connect.h"
00045 #include "ldap_api_fn.h"
00046 #include "ldap_escape.h"
00047 
00048 
00049 #define STR_BUF_SIZE 1024
00050 #define ESC_BUF_SIZE 65536
00051 
00052 static char str_buf[STR_BUF_SIZE];
00053 static char esc_buf[ESC_BUF_SIZE];
00054 
00055 
00056 /*
00057 * exported functions
00058 */ 
00059 
00060 int ldap_search_impl(
00061    struct sip_msg* _msg,
00062    pv_elem_t* _ldap_url)
00063 {
00064    str ldap_url;
00065    int ld_result_count = 0;
00066    
00067    /*
00068    * do variable substitution for _ldap_url (pv_printf_s)
00069    */
00070    if (_ldap_url==NULL) {
00071       LM_ERR("empty ldap_url\n");
00072       return -2;
00073    }
00074    if ( _ldap_url->spec.getf!=NULL) {
00075       if (pv_printf_s( _msg, _ldap_url, &ldap_url)!=0 || ldap_url.len<=0) {
00076          LM_ERR("pv_printf_s failed\n");
00077          return -2;
00078       }
00079    } else {
00080       ldap_url = _ldap_url->text;
00081    }
00082 
00083    /*
00084    * perform LDAP search
00085    */
00086    if (ldap_url_search(ldap_url.s, &ld_result_count) != 0)
00087    {
00088       /* LDAP search error */
00089       return -2;
00090    }
00091    if (ld_result_count < 1)
00092    {
00093       /* no LDAP entry found */
00094       LM_INFO("no LDAP entry found\n");
00095       return -1;
00096    }
00097    return ld_result_count;
00098 }
00099 
00100 int ldap_write_result(
00101    struct sip_msg* _msg,
00102    struct ldap_result_params* _lrp,
00103    struct subst_expr* _se)
00104 {
00105    int_str                    dst_avp_name, dst_avp_val;
00106    unsigned short             dst_avp_type;
00107    int                        nmatches, rc, i, added_avp_count = 0;
00108    struct berval              **attr_vals;
00109    str                        avp_val_str, *subst_result = NULL;
00110    int                        avp_val_int;
00111    
00112    /*
00113    * get dst AVP name (dst_avp_name)
00114    */
00115    
00116    if (pv_get_avp_name( _msg,
00117             &(_lrp->dst_avp_spec.pvp), 
00118             &dst_avp_name, 
00119             &dst_avp_type)
00120          != 0) 
00121    {
00122       LM_ERR("error getting dst AVP name\n");
00123       return -2;
00124    }
00125    if (dst_avp_type & AVP_NAME_STR)
00126    {
00127       if (dst_avp_name.s.len >= STR_BUF_SIZE)
00128       {
00129          LM_ERR("dst AVP name too long\n");
00130          return -2;
00131       }
00132       strncpy(str_buf, dst_avp_name.s.s, dst_avp_name.s.len);
00133       str_buf[dst_avp_name.s.len] = '\0';
00134       dst_avp_name.s.s = str_buf;
00135    }
00136 
00137    /*
00138    * get LDAP attr values
00139    */
00140    if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0)
00141    {
00142       if (rc > 0) {
00143          return -1;
00144       } else {
00145          return -2;
00146       }
00147    }
00148 
00149    /*
00150    * add AVPs
00151    */
00152    for (i = 0; attr_vals[i] != NULL; i++)
00153    {
00154       if (_se == NULL)
00155       {
00156          avp_val_str.s = attr_vals[i]->bv_val;
00157          avp_val_str.len = attr_vals[i]->bv_len;
00158       }
00159       else
00160       {
00161          subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se,
00162                &nmatches);
00163          if ((subst_result == NULL) || (nmatches < 1))
00164          {
00165             continue;
00166          }
00167          avp_val_str = *subst_result;
00168       }
00169 
00170       if (_lrp->dst_avp_val_type == 1)
00171       {
00172          /* try to convert ldap value to integer */
00173          if (!str2sint(&avp_val_str, &avp_val_int)) 
00174          {
00175             dst_avp_val.n = avp_val_int;
00176             rc = add_avp(dst_avp_type, dst_avp_name, dst_avp_val);
00177          } else
00178          {
00179             continue;
00180          }
00181       } else
00182       {
00183          /* save ldap value as string */
00184          dst_avp_val.s = avp_val_str;
00185          rc = add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, dst_avp_val);
00186       }
00187       
00188       if (subst_result != NULL) {
00189          if (subst_result->s != 0) {
00190             pkg_free(subst_result->s);
00191          }
00192          pkg_free(subst_result);
00193          subst_result = NULL;
00194       }
00195       
00196       if (rc < 0) 
00197       {
00198          LM_ERR("failed to create new AVP\n");
00199          ldap_value_free_len(attr_vals);
00200          return -2;
00201       }
00202       added_avp_count++;
00203    }
00204    ldap_value_free_len(attr_vals);
00205    
00206    if (added_avp_count > 0)
00207    {
00208       return added_avp_count;
00209    } else
00210    {
00211       return -1;
00212    }
00213 }
00214 
00215 int ldap_result_next(void)
00216 {
00217    int rc;
00218 
00219    rc = ldap_inc_result_pointer();
00220    switch (rc)
00221    {
00222    case 1:
00223       return -1;
00224    case 0:
00225       return 1;
00226    case -1:
00227    default:
00228       return -2;
00229    }
00230 }
00231 
00232 int ldap_result_check(
00233    struct sip_msg* _msg,
00234    struct ldap_result_check_params* _lrp,
00235    struct subst_expr* _se)
00236 {
00237    str check_str, *subst_result = NULL;
00238    int rc, i, nmatches;
00239    char *attr_val;
00240    struct berval **attr_vals;
00241 
00242    /*
00243    * do variable substitution for check_str 
00244    */
00245    
00246    if (_lrp->check_str_elem_p)
00247    {
00248       if (pv_printf_s(_msg, _lrp->check_str_elem_p, &check_str) != 0)
00249       {
00250          LM_ERR("pv_printf_s failed\n");
00251          return -2;
00252       }
00253    } else 
00254    {
00255       LM_ERR("empty check string\n");
00256       return -2;
00257    }
00258 
00259    LM_DBG("check_str [%s]\n", check_str.s);
00260    
00261    /*
00262    * get LDAP attr values
00263    */
00264    
00265    if ((rc = ldap_get_attr_vals(&_lrp->ldap_attr_name, &attr_vals)) != 0)
00266    {
00267       if (rc > 0) {
00268          return -1;
00269       } else {
00270          return -2;
00271       }
00272    }
00273 
00274    /*
00275    * loop through attribute values
00276    */
00277    
00278    for (i = 0; attr_vals[i] != NULL; i++)
00279    {
00280       if (_se == NULL)
00281       {
00282          attr_val = attr_vals[i]->bv_val;
00283       } else
00284       {  
00285          subst_result = subst_str(attr_vals[i]->bv_val, _msg, _se,
00286                &nmatches);
00287          if ((subst_result == NULL) || (nmatches < 1))
00288          {
00289             continue;
00290          }
00291          attr_val = subst_result->s;
00292       }
00293       
00294       LM_DBG("attr_val [%s]\n", attr_val);
00295       rc = strncmp(check_str.s, attr_val, check_str.len);
00296       if (_se != NULL) 
00297       {
00298          pkg_free(subst_result->s);
00299       }
00300       if (rc == 0)
00301       {
00302          ldap_value_free_len(attr_vals);
00303          return 1;
00304       }
00305    }
00306 
00307    ldap_value_free_len(attr_vals);
00308    return -1;
00309 }
00310 
00311 int ldap_filter_url_encode(
00312    struct sip_msg* _msg,
00313    pv_elem_t* _filter_component,
00314    pv_spec_t* _dst_avp_spec)
00315 {
00316    str             filter_component_str, esc_str;  
00317    int_str         dst_avp_name;
00318    unsigned short  dst_avp_type;
00319 
00320    /*
00321    * variable substitution for _filter_component
00322    */
00323    if (_filter_component) {
00324       if (pv_printf_s(_msg, _filter_component, &filter_component_str) != 0) {
00325          LM_ERR("pv_printf_s failed\n");
00326          return -1;
00327       }
00328    } else {
00329       LM_ERR("empty first argument\n");
00330       return -1;
00331    }
00332 
00333    /*
00334    * get dst AVP name (dst_avp_name)
00335    */
00336    if (pv_get_avp_name(_msg, &(_dst_avp_spec->pvp), &dst_avp_name,
00337             &dst_avp_type) != 0)
00338    {
00339       LM_ERR("error getting dst AVP name\n");
00340       return -1;
00341    }
00342    if (dst_avp_type & AVP_NAME_STR)
00343    {
00344       if (dst_avp_name.s.len >= STR_BUF_SIZE)
00345       {
00346          LM_ERR("dst AVP name too long\n");
00347          return -1;
00348       }
00349       strncpy(str_buf, dst_avp_name.s.s, dst_avp_name.s.len);
00350       str_buf[dst_avp_name.s.len] = '\0';
00351       dst_avp_name.s.s = str_buf;
00352    }
00353 
00354    /*
00355    * apply LDAP filter escaping rules
00356    */
00357    esc_str.s = esc_buf;
00358    esc_str.len = ESC_BUF_SIZE;
00359    if (ldap_rfc4515_escape(&filter_component_str, &esc_str, 1) != 0)
00360    {
00361       LM_ERR("ldap_rfc4515_escape() failed\n");
00362       return -1;
00363    }
00364 
00365    /*
00366    * add dst AVP
00367    */
00368    if (add_avp(dst_avp_type|AVP_VAL_STR, dst_avp_name, (int_str)esc_str) != 0)
00369    {
00370       LM_ERR("failed to add new AVP\n");
00371       return -1;
00372    }
00373 
00374    return 1;
00375 }

Generated on Wed May 23 18:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6