group.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
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 
00037 #include <string.h>
00038 #include "../../dprint.h"               /* Logging */
00039 #include "../../lib/srdb1/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 
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                 default: {
00120                         LM_ERR("incorrect check id %d\n", gcp->id);
00121                         return -1;
00122                 }
00123         }
00124 
00125         if (gcp->id != 4) {
00126                 *username = turi->user;
00127                 *domain = turi->host;
00128         } else {
00129                 *username = c->digest.username.user;
00130                 *domain = *(GET_REALM(&c->digest));
00131         }
00132         return 0;
00133 }
00134 
00135 
00136 
00144 int is_user_in(struct sip_msg* _msg, char* _hf, char* _grp)
00145 {
00146         db_key_t keys[3];
00147         db_val_t vals[3];
00148         db_key_t col[1];
00149         db1_res_t* res = NULL;
00150 
00151         keys[0] = &user_column;
00152         keys[1] = &group_column;
00153         keys[2] = &domain_column;
00154         col[0]  = &group_column;
00155 
00156         if ( get_username_domain( _msg, (group_check_p)_hf, &(VAL_STR(vals)),
00157         &(VAL_STR(vals+2)))!=0) {
00158                 LM_ERR("failed to get username@domain\n");
00159                 return -1;
00160         }
00161 
00162         if (VAL_STR(vals).s==NULL || VAL_STR(vals).len==0 ) {
00163                 LM_DBG("no username part\n");
00164                 return -1;
00165         }
00166 
00167         VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB1_STR;
00168         VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0;
00169 
00170         VAL_STR(vals + 1) = *((str*)_grp);
00171 
00172         if (group_dbf.use_table(group_dbh, &table) < 0) {
00173                 LM_ERR("failed to use_table\n");
00174                 return -5;
00175         }
00176 
00177         if (group_dbf.query(group_dbh, keys, 0, vals, col, (use_domain) ? (3): (2),
00178                                 1, 0, &res) < 0) {
00179                 LM_ERR("failed to query database\n");
00180                 return -5;
00181         }
00182 
00183         if (RES_ROW_N(res) == 0) {
00184                 LM_DBG("user is not in group '%.*s'\n", 
00185                     ((str*)_grp)->len, ZSW(((str*)_grp)->s));
00186                 group_dbf.free_result(group_dbh, res);
00187                 return -6;
00188         } else {
00189                 LM_DBG("user is in group '%.*s'\n", 
00190                         ((str*)_grp)->len, ZSW(((str*)_grp)->s));
00191                 group_dbf.free_result(group_dbh, res);
00192                 return 1;
00193         }
00194 }
00195 
00196 
00202 int group_db_init(const str* db_url)
00203 {
00204         if (group_dbf.init==0){
00205                 LM_CRIT("null dbf \n");
00206                 goto error;
00207         }
00208         group_dbh=group_dbf.init(db_url);
00209         if (group_dbh==0){
00210                 LM_ERR("unable to connect to the database\n");
00211                 goto error;
00212         }
00213         return 0;
00214 error:
00215         return -1;
00216 }
00217 
00218 
00224 int group_db_bind(const str* db_url)
00225 {
00226         if (db_bind_mod(db_url, &group_dbf)<0){
00227                 LM_ERR("unable to bind to the database module\n");
00228                 return -1;
00229         }
00230 
00231         if (!DB_CAPABILITY(group_dbf, DB_CAP_QUERY)) {
00232                 LM_ERR("database module does not implement 'query' function\n");
00233                 return -1;
00234         }
00235 
00236         return 0;
00237 }
00238 
00239 
00243 void group_db_close(void)
00244 {
00245         if (group_dbh && group_dbf.close){
00246                 group_dbf.close(group_dbh);
00247                 group_dbh=0;
00248         }
00249 }