group.c

Go to the documentation of this file.
00001 /*
00002  * $Id: group.c 5241 2008-11-21 12:52:25Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  * 2003-02-25 - created by janakj
00025  * 2004-06-07   updated to the new DB api, added group_db_{bind,init,close,ver}
00026  *               (andrei)
00027  */
00028 
00029 /**
00030  * \file
00031  * \brief Group membership module
00032  * \ingroup group
00033  * - Module: \ref group
00034  */
00035 
00036 
00037 #include <string.h>
00038 #include "../../dprint.h"               /* Logging */
00039 #include "../../db/db.h"                /* Generic database API */
00040 #include "../../ut.h"
00041 #include "../../parser/digest/digest.h" /* get_authorized_cred */
00042 #include "../../parser/hf.h"            /* Header Field types */
00043 #include "../../parser/parse_from.h"    /* From parser */
00044 #include "../../parser/parse_uri.h"
00045 #include "group.h"
00046 #include "group_mod.h"                   /* Module parameters */
00047 
00048 /*!
00049  * \brief Extract the username and domain from the SIP message
00050  *
00051  * Set the username and domain depending on the value of the SIP
00052  * message and the group check structure.
00053  * \param msg SIP message
00054  * \param gcp group check structure
00055  * \param username stored username
00056  * \param domain stored domain
00057  * \return 0 on success, -1 on failure
00058  */
00059 int get_username_domain(struct sip_msg *msg, group_check_p gcp,
00060                                  str *username, str *domain)
00061 {
00062    struct sip_uri puri;
00063    struct sip_uri *turi;
00064    struct hdr_field* h;
00065    struct auth_body* c = 0;
00066    pv_value_t value;
00067 
00068    turi = NULL;
00069 
00070    switch(gcp->id) {
00071       case 1: /* Request-URI */
00072          if(parse_sip_msg_uri(msg)<0) {
00073             LM_ERR("failed to get Request-URI\n");
00074             return -1;
00075          }
00076          turi = &msg->parsed_uri;
00077          break;
00078 
00079       case 2: /* To */
00080          if((turi=parse_to_uri(msg))==NULL) {
00081             LM_ERR("failed to get To URI\n");
00082             return -1;
00083          }
00084          break;
00085 
00086       case 3: /* From */
00087          if((turi=parse_from_uri(msg))==NULL) {
00088             LM_ERR("failed to get From URI\n");
00089             return -1;
00090          }
00091          break;
00092 
00093       case 4: /* Credentials */
00094          get_authorized_cred( msg->authorization, &h);
00095          if (!h) {
00096             get_authorized_cred( msg->proxy_auth, &h);
00097             if (!h) {
00098                LM_ERR("no authorized credentials found "
00099                      "(error in scripts)\n");
00100                return -1;
00101             }
00102          }
00103          c = (auth_body_t*)(h->parsed);
00104          break;
00105 
00106       case 5: /* AVP spec */
00107          if(pv_get_spec_value( msg, &gcp->sp, &value)!=0 
00108             || value.flags&PV_VAL_NULL || value.rs.len<=0)
00109          {
00110             LM_ERR("no AVP found (error in scripts)\n");
00111             return -1;
00112          }
00113          if (parse_uri(value.rs.s, value.rs.len, &puri) < 0) {
00114             LM_ERR("failed to parse URI <%.*s>\n",value.rs.len, value.rs.s);
00115             return -1;
00116          }
00117          turi = &puri;
00118          break;
00119    }
00120 
00121    if (gcp->id != 4) {
00122       *username = turi->user;
00123       *domain = turi->host;
00124    } else {
00125       *username = c->digest.username.user;
00126       *domain = *(GET_REALM(&c->digest));
00127    }
00128    return 0;
00129 }
00130 
00131 
00132 
00133 /*!
00134  * \brief Check if username in specified header field is in a table
00135  * \param _msg SIP message
00136  * \param _hf Header field
00137  * \param _grp checked table
00138  * \return 1 on success, negative on failure 
00139  */
00140 int is_user_in(struct sip_msg* _msg, char* _hf, char* _grp)
00141 {
00142    db_key_t keys[3];
00143    db_val_t vals[3];
00144    db_key_t col[1];
00145    db_res_t* res = NULL;
00146 
00147    keys[0] = &user_column;
00148    keys[1] = &group_column;
00149    keys[2] = &domain_column;
00150    col[0]  = &group_column;
00151 
00152    if ( get_username_domain( _msg, (group_check_p)_hf, &(VAL_STR(vals)),
00153    &(VAL_STR(vals+2)))!=0) {
00154       LM_ERR("failed to get username@domain\n");
00155       return -1;
00156    }
00157 
00158    if (VAL_STR(vals).s==NULL || VAL_STR(vals).len==0 ) {
00159       LM_DBG("no username part\n");
00160       return -1;
00161    }
00162 
00163    VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR;
00164    VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0;
00165 
00166    VAL_STR(vals + 1) = *((str*)_grp);
00167 
00168    if (group_dbf.use_table(group_dbh, &table) < 0) {
00169       LM_ERR("failed to use_table\n");
00170       return -5;
00171    }
00172 
00173    if (group_dbf.query(group_dbh, keys, 0, vals, col, (use_domain) ? (3): (2),
00174             1, 0, &res) < 0) {
00175       LM_ERR("failed to query database\n");
00176       return -5;
00177    }
00178 
00179    if (RES_ROW_N(res) == 0) {
00180       LM_DBG("user is not in group '%.*s'\n", 
00181           ((str*)_grp)->len, ZSW(((str*)_grp)->s));
00182       group_dbf.free_result(group_dbh, res);
00183       return -6;
00184    } else {
00185       LM_DBG("user is in group '%.*s'\n", 
00186          ((str*)_grp)->len, ZSW(((str*)_grp)->s));
00187       group_dbf.free_result(group_dbh, res);
00188       return 1;
00189    }
00190 }
00191 
00192 
00193 /*!
00194  * \brief Initialize the DB connection
00195  * \param db_url database URL
00196  * \return 0 on success, -1 on failure
00197  */
00198 int group_db_init(const str* db_url)
00199 {
00200    if (group_dbf.init==0){
00201       LM_CRIT("null dbf \n");
00202       goto error;
00203    }
00204    group_dbh=group_dbf.init(db_url);
00205    if (group_dbh==0){
00206       LM_ERR("unable to connect to the database\n");
00207       goto error;
00208    }
00209    return 0;
00210 error:
00211    return -1;
00212 }
00213 
00214 
00215 /*!
00216  * \brief Bind the DB connection
00217  * \param db_url database URL
00218  * \return 0 on success, -1 on failure
00219  */
00220 int group_db_bind(const str* db_url)
00221 {
00222    if (db_bind_mod(db_url, &group_dbf)<0){
00223       LM_ERR("unable to bind to the database module\n");
00224       return -1;
00225    }
00226 
00227    if (!DB_CAPABILITY(group_dbf, DB_CAP_QUERY)) {
00228       LM_ERR("database module does not implement 'query' function\n");
00229       return -1;
00230    }
00231 
00232    return 0;
00233 }
00234 
00235 
00236 /*!
00237  * \brief Close the DB connection
00238  */
00239 void group_db_close(void)
00240 {
00241    if (group_dbh && group_dbf.close){
00242       group_dbf.close(group_dbh);
00243       group_dbh=0;
00244    }
00245 }

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