/* * Check if username in specified header field is in a table */ int is_user_in(struct sip_msg* _msg, char* _hf, char* _grp) { db_key_t keys[3]; db_val_t vals[3]; db_key_t col[1]; db_res_t* res; str uri; long hf_type; struct sip_uri puri; struct hdr_field* h; struct auth_body* c = 0; /* Makes gcc happy */ group_check_p gcp=NULL; xl_value_t value; keys[0] = user_column.s; keys[1] = group_column.s; keys[2] = domain_column.s; col[0] = group_column.s; gcp = (group_check_p)_hf; hf_type = (long)gcp->id; uri.s = 0; uri.len = 0; switch(hf_type) { case 1: /* Request-URI */ if (get_request_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while obtaining username from Request-URI\n"); return -1; } break; case 2: /* To */ if (get_to_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while extracting To username\n"); return -2; } break; case 3: /* From */ if (get_from_uri(_msg, &uri) < 0) { LOG(L_ERR, "is_user_in(): Error while extracting From username\n"); return -3; } break; case 4: /* Credentials */ get_authorized_cred(_msg->authorization, &h); if (!h) { get_authorized_cred(_msg->proxy_auth, &h); if (!h) { LOG(L_ERR, "is_user_in(): No authorized credentials found (error in scripts)\n"); return -1; } } c = (auth_body_t*)(h->parsed); break; case 5: /* AVP spec */ if(xl_get_spec_value(_msg, &gcp->sp, &value)!=0 || value.flags&XL_VAL_NULL || value.rs.len<=0) { LOG(L_ERR, "is_user_in(): no AVP found (error in scripts)\n"); return -1; } uri.s = value.rs.s; uri.len = value.rs.len; break; } if (hf_type != 4) { if (parse_uri(uri.s, uri.len, &puri) < 0) { LOG(L_ERR, "is_user_in(): Error while parsing URI\n"); return -5; } VAL_STR(vals) = puri.user; VAL_STR(vals + 2) = puri.host; } else { VAL_STR(vals) = c->digest.username.user; VAL_STR(vals + 2) = *(GET_REALM(&c->digest)); } VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB_STR; VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0; VAL_STR(vals + 1) = *((str*)_grp); if (group_dbf.use_table(db_handle, table.s) < 0) { LOG(L_ERR, "is_user_in(): Error in use_table\n"); return -5; } if (group_dbf.query(db_handle, keys, 0, vals, col, (use_domain) ? (3): (2), 1, 0, &res) < 0) { LOG(L_ERR, "is_user_in(): Error while querying database\n"); return -5; } if (RES_ROW_N(res) == 0) { DBG("is_user_in(): User is not in group '%.*s'\n", ((str*)_grp)->len, ZSW(((str*)_grp)->s)); group_dbf.free_result(db_handle, res); return -6; } else { DBG("is_user_in(): User is in group '%.*s'\n", ((str*)_grp)->len, ZSW(((str*)_grp)->s)); group_dbf.free_result(db_handle, res); return 1; } }
/* rpl.s will be alloc'ed with the proper size & rpl.len set * returns 0 on success, <0 on error*/ static int replace_build(const char* match, int nmatch, regmatch_t* pmatch, struct subst_expr* se, struct sip_msg* msg, str* rpl) { int r; str* uri; xl_value_t sv; char* p; char* dest; char* end; int size; #define REPLACE_BUFFER_SIZE 1024 static char rbuf[REPLACE_BUFFER_SIZE]; #if 0 /* use static bufer now since we cannot easily get the length */ rpl->len=replace_len(match, nmatch, pmatch, se, msg); if (rpl->len==0){ rpl->s=0; /* empty string */ return 0; } rpl->s=pkg_malloc(rpl->len); if (rpl->s==0){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } #endif p=se->replacement.s; end=p+se->replacement.len; dest=rbuf; for (r=0; r<se->n_escapes; r++){ /* copy the unescaped parts */ size=se->replacement.s+se->replace[r].offset-p; if(dest-rbuf+size>=REPLACE_BUFFER_SIZE-1){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } memcpy(dest, p, size); p+=size+se->replace[r].size; dest+=size; switch(se->replace[r].type){ case REPLACE_NMATCH: if ((se->replace[r].u.nmatch<nmatch)&&( pmatch[se->replace[r].u.nmatch].rm_so!=-1)){ /* do the replace */ size=pmatch[se->replace[r].u.nmatch].rm_eo- pmatch[se->replace[r].u.nmatch].rm_so; if(dest-rbuf+size>=REPLACE_BUFFER_SIZE-1){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } memcpy(dest, match+pmatch[se->replace[r].u.nmatch].rm_so, size); dest+=size; }; break; case REPLACE_CHAR: if(dest-rbuf+1>=REPLACE_BUFFER_SIZE-1){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } *dest=se->replace[r].u.c; dest++; break; case REPLACE_URI: if (msg->first_line.type!=SIP_REQUEST){ LOG(L_CRIT, "BUG: replace_build: uri substitution on" " a reply\n"); break; /* ignore, we can continue */ } uri= (msg->new_uri.s)?(&msg->new_uri): (&msg->first_line.u.request.uri); if(dest-rbuf+uri->len>=REPLACE_BUFFER_SIZE-1){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } memcpy(dest, uri->s, uri->len); dest+=uri->len; break; case REPLACE_SPEC: if(xl_get_spec_value(msg, &se->replace[r].u.spec, &sv)!=0) { LOG(L_CRIT, "BUG: replace_build: item substitution" " returned error\n"); break; /* ignore, we can continue */ } if(dest-rbuf+sv.rs.len>=REPLACE_BUFFER_SIZE-1){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } memcpy(dest, sv.rs.s, sv.rs.len); dest+=sv.rs.len; break; default: LOG(L_CRIT, "BUG: replace_build: unknown type %d\n", se->replace[r].type); /* ignore it */ } } memcpy(dest, p, end-p); rpl->len = (dest-rbuf)+(end-p); rpl->s=pkg_malloc(rpl->len); if (rpl->s==0){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } memcpy(rpl->s, rbuf, rpl->len); return 0; error: return -1; }