00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <sys/types.h>
00035 #include <regex.h>
00036
00037 #include "../../str.h"
00038 #include "../../mem/mem.h"
00039 #include "../../route_struct.h"
00040 #include "group_mod.h"
00041 #include "re_group.h"
00042 #include "group.h"
00043
00044
00045 struct re_grp {
00046 regex_t re;
00047 int_str gid;
00048 struct re_grp *next;
00049 };
00050
00051
00052 static struct re_grp *re_list = 0;
00053
00054
00055
00056
00057
00058
00059
00060
00061 static int add_re(const char *re, int gid)
00062 {
00063 struct re_grp *rg;
00064
00065 LM_DBG("adding <%s> with %d\n",re, gid);
00066
00067 rg = (struct re_grp*)pkg_malloc(sizeof(struct re_grp));
00068 if (rg==0) {
00069 LM_ERR("no more pkg mem\n");
00070 goto error;
00071 }
00072 memset( rg, 0, sizeof(struct re_grp));
00073
00074 if (regcomp(&rg->re, re, REG_EXTENDED|REG_ICASE|REG_NEWLINE) ) {
00075 LM_ERR("bad re %s\n", re);
00076 pkg_free(rg);
00077 goto error;
00078 }
00079
00080 rg->gid.n = gid;
00081
00082 rg->next = re_list;
00083 re_list = rg;
00084
00085 return 0;
00086 error:
00087 return -1;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 int load_re( str *table )
00097 {
00098 db_key_t cols[2];
00099 db_res_t* res = NULL;
00100 db_row_t* row;
00101 int n;
00102
00103 cols[0] = &re_exp_column;
00104 cols[1] = &re_gid_column;
00105
00106 if (group_dbf.use_table(group_dbh, table) < 0) {
00107 LM_ERR("failed to set table <%s>\n", table->s);
00108 goto error;
00109 }
00110
00111 if (group_dbf.query(group_dbh, 0, 0, 0, cols, 0, 2, 0, &res) < 0) {
00112 LM_ERR("failed to query database\n");
00113 goto error;
00114 }
00115
00116 for( n=0 ; n<RES_ROW_N(res) ; n++) {
00117 row = &res->rows[n];
00118
00119 if (row->values[0].nul || row->values[0].type!=DB_STRING) {
00120 LM_ERR("empty or non-string "
00121 "value for <%s>(re) column\n",re_exp_column.s);
00122 goto error1;
00123 }
00124 if (row->values[1].nul || row->values[1].type!=DB_INT) {
00125 LM_ERR("empty or non-integer "
00126 "value for <%s>(gid) column\n",re_gid_column.s);
00127 goto error1;
00128 }
00129
00130 if ( add_re( row->values[0].val.string_val,
00131 row->values[1].val.int_val)!=0 ) {
00132 LM_ERR("failed to add row\n");
00133 goto error1;
00134 }
00135 }
00136 LM_DBG("%d rules were loaded\n", n);
00137
00138 group_dbf.free_result(group_dbh, res);
00139 return 0;
00140 error1:
00141 group_dbf.free_result(group_dbh, res);
00142 error:
00143 return -1;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int get_user_group(struct sip_msg *req, char *user, char *avp)
00155 {
00156 static char uri_buf[MAX_URI_SIZE];
00157 str username;
00158 str domain;
00159 pv_spec_t *pvs;
00160 pv_value_t val;
00161 struct re_grp *rg;
00162 regmatch_t pmatch;
00163 char *c;
00164 int n;
00165
00166 if (get_username_domain( req, (group_check_p)user, &username, &domain)!=0){
00167 LM_ERR("failed to get username@domain\n");
00168 goto error;
00169 }
00170
00171 if (username.s==NULL || username.len==0 ) {
00172 LM_DBG("no username part\n");
00173 return -1;
00174 }
00175
00176 if ( 4 + username.len + 1 + domain.len + 1 > MAX_URI_SIZE ) {
00177 LM_ERR("URI to large!!\n");
00178 goto error;
00179 }
00180
00181 *(int*)uri_buf = htonl(('s'<<24) + ('i'<<16) + ('p'<<8) + ':');
00182 c = uri_buf + 4;
00183 memcpy( c, username.s, username.len);
00184 c += username.len;
00185 *(c++) = '@';
00186 memcpy( c, domain.s, domain.len);
00187 c += domain.len;
00188 *c = 0;
00189
00190 LM_DBG("getting groups for <%s>\n",uri_buf);
00191 pvs = (pv_spec_t*)avp;
00192 memset(&val, 0, sizeof(pv_value_t));
00193 val.flags = PV_VAL_INT|PV_TYPE_INT;
00194
00195
00196 for( rg=re_list,n=0 ; rg ; rg=rg->next ) {
00197 if (regexec( &rg->re, uri_buf, 1, &pmatch, 0)==0) {
00198 LM_DBG("user matched to group %d!\n", rg->gid.n);
00199
00200
00201 val.ri = rg->gid.n;
00202 if(pvs->setf(req, &pvs->pvp, (int)EQ_T, &val)<0)
00203 {
00204 LM_ERR("setting PV AVP failed\n");
00205 goto error;
00206 }
00207 n++;
00208
00209 if (multiple_gid==0)
00210 break;
00211 }
00212 }
00213
00214 return n?n:-1;
00215 error:
00216 return -1;
00217 }
00218
00219