Esempio n. 1
0
int sd_lookup(struct sip_msg* _msg, char* _index, char* _str2)
{
    int i;
    str user_s, uid, did;
    db_res_t* res = NULL;
    db_rec_t* rec;

    /* init */
    i = (int)(long)_index;

    /* Retrieve the owner of the record */
    if (get_from_uid(&uid, _msg) < 0) {
        LOG(L_ERR, "sd_lookup: Unable to get user identity\n");
        return -1;
    }

    /* Retrieve the called domain id */
    if (get_to_did(&did, _msg) < 0) {
        LOG(L_ERR, "sd_lookup: Destination domain ID not known\n");
        return -1;
    }

    tables[i].lookup_num->match[0].v.lstr = uid;
    tables[i].lookup_num->match[1].v.lstr = did;

    /* Get the called username */
    if (parse_sip_msg_uri(_msg) < 0)
    {
        LOG(L_ERR, "sd_lookup: Error while parsing Request-URI\n");
        goto err_badreq;
    }

    tables[i].lookup_num->match[2].v.lstr = _msg->parsed_uri.user;

    DBG("speeddial: Looking up (uid:%.*s,username:%.*s,did:%.*s)\n",
        uid.len, uid.s,
        _msg->parsed_uri.user.len, _msg->parsed_uri.user.s,
        did.len, did.s);

    if (db_exec(&res, tables[i].lookup_num) < 0) {
        ERR("speeddial: Error while executing database command\n");
        goto err_server;
    }

    if (res == NULL) {
        DBG("speeddial: No SIP URI found for speeddial (num:%.*s, uid:%.*s,"
            " did:%.*s)\n",
            _msg->parsed_uri.user.len,
            _msg->parsed_uri.user.s,
            uid.len, uid.s,
            did.len, did.s);
        return -1;
    }

    user_s.s = useruri_buf + 4;
    rec = db_first(res);
    while(rec) {
        if (rec->fld[0].flags & DB_NULL) goto skip;
        strncpy(user_s.s,
                rec->fld[0].v.lstr.s,
                rec->fld[0].v.lstr.len);
        user_s.len = rec->fld[0].v.lstr.len;
        user_s.s[user_s.len] = '\0';
        goto out;

skip:
        rec = db_next(res);
    }

    if (rec == NULL) {
        DBG("speeddial: No usable SIP URI found for (num:%.*s, uid:%.*s,"
            " did:%.*s)\n",
            _msg->parsed_uri.user.len,
            _msg->parsed_uri.user.s,
            uid.len, uid.s,
            did.len, did.s);
        db_res_free(res);
        return -1;
    }

out:
    /* check 'sip:' */
    if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) {
        memcpy(useruri_buf, "sip:", 4);
        user_s.s -= 4;
        user_s.len += 4;
    }

    db_res_free(res);

    /* set the URI */
    DBG("sd_lookup: URI of sd from R-URI [%s]\n", user_s.s);
    if(rewrite_uri(_msg, &user_s)<0)
    {
        LOG(L_ERR, "sd_lookup: Cannot replace the R-URI\n");
        goto err_server;
    }

    return 1;

err_server:
    if (slb.zreply(_msg, 500, "Server Internal Error") == -1)
    {
        LOG(L_ERR, "sd_lookup: Error while sending reply\n");
    }
    return 0;
err_badreq:
    if (slb.zreply(_msg, 400, "Bad Request") == -1)
    {
        LOG(L_ERR, "sd_lookup: Error while sending reply\n");
    }
    return 0;
}
Esempio n. 2
0
/* create an array of str's for accounting using a formatting string;
 * this is the heart of the accounting module -- it prints whatever
 * requested in a way, that can be used for syslog, radius,
 * sql, whatsoever
 * tm sip_msg_clones does not clone (shmmem-zed) parsed fields, other then Via1,2. Such fields clone now or use from rq_rp
 */
static int fmt2strar(char *fmt,             /* what would you like to account ? */
		     struct sip_msg *rq,    /* accounted message */
		     str* ouri,             /* Outbound Request-URI */
		     struct hdr_field *to,
		     unsigned int code,
		     time_t req_time)       /* Timestamp of the request */
{
	int cnt;
	struct to_body* from, *pto;
	str *cr, *at;
	struct cseq_body *cseq;

	cnt = 0;

	     /* we don't care about parsing here; either the function
	      * was called from script, in which case the wrapping function
	      * is supposed to parse, or from reply processing in which case
	      * TM should have preparsed from REQUEST_IN callback; what's not
	      * here is replaced with NA
	      */
	while(*fmt) {
		if (cnt == ALL_LOG_FMT_LEN) {
			LOG(L_ERR, "ERROR:acc:fmt2strar: Formatting string is too long\n");
			return 0;
		}

		switch(*fmt) {
		case 'a': /* attr */
			at = print_attrs(avps, avps_n, 0);
			if (!at) {
				vals[cnt].nul = 1;
			} else {
				vals[cnt].val.str_val = *at;
			}
			break;

		case 'c': /* sip_callid */
			if (rq->callid && rq->callid->body.len) {
				vals[cnt].val.str_val = rq->callid->body;
			} else {
				vals[cnt].nul = 1;
			}
			break;

		case 'd': /* to_tag */
			if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) {
				vals[cnt].val.str_val = pto->tag_value;
			} else {
				vals[cnt].nul = 1;
			}
			break;

		case 'f': /* sip_from */
			if (rq->from && rq->from->body.len) {
				vals[cnt].val.str_val = rq->from->body;
			} else {
				vals[cnt].nul = 1;
			}
			break;

		case 'g': /* flags */
			vals[cnt].val.int_val = rq->flags;
			break;

		case 'i': /* inbound_ruri */
			vals[cnt].val.str_val = rq->first_line.u.request.uri;
			break;

		case 'm': /* sip_method */
			vals[cnt].val.str_val = rq->first_line.u.request.method;
			break;

		case 'n': /* sip_cseq */
			if (rq->cseq && (cseq = get_cseq(rq)) && cseq->number.len) {
				str2int(&cseq->number, (unsigned int*)&vals[cnt].val.int_val);
			} else {
				vals[cnt].nul = 1;
			}
			break;

		case 'o': /* outbound_ruri */
		        vals[cnt].val.str_val = *ouri;
			break;

		case 'p':
			vals[cnt].val.int_val = rq->rcv.src_ip.u.addr32[0];
			break;
			break;

		case 'r': /* from_tag */
			if (rq->from && (from = get_from(rq)) && from->tag_value.len) {
				vals[cnt].val.str_val = from->tag_value;
			} else {
				vals[cnt].nul = 1;
			}
			break;

		case 't': /* sip_to */
			if (to && to->body.len) vals[cnt].val.str_val = to->body;
			else vals[cnt].nul = 1;
			break;

		case 'u': /* digest_username */
			cr = cred_user(rq);
			if (cr) vals[cnt].val.str_val = *cr;
			else vals[cnt].nul = 1;
			break;

		case 'x': /* request_timestamp */
			vals[cnt].val.time_val = req_time;
			break;

		case 'D': /* to_did */
			vals[cnt].nul = 1;
			break;

		case 'F': /* from_uri */
			if (rq->from && (from = get_from(rq)) && from->uri.len) {
				vals[cnt].val.str_val = from->uri;
			} else vals[cnt].nul = 1;
			break;

		case 'I': /* from_uid */
			if (get_from_uid(&vals[cnt].val.str_val, rq) < 0) {
				vals[cnt].nul = 1;
			}
			break;

		case 'M': /* from_did */
			vals[cnt].nul = 1;
			break;

		case 'P': /* source_port */
			vals[cnt].val.int_val = rq->rcv.src_port;
			break;

		case 'R': /* digest_realm */
			cr = cred_realm(rq);
			if (cr) vals[cnt].val.str_val = *cr;
			else vals[cnt].nul = 1;
			break;

		case 'S': /* sip_status */
			if (code > 0) vals[cnt].val.int_val = code;
			else vals[cnt].nul = 1;
			break;

		case 'T': /* to_uri */
			if (rq->to && (pto = get_to(rq)) && pto->uri.len) vals[cnt].val.str_val = pto->uri;
			else vals[cnt].nul = 1;
			break;

		case 'U': /* to_uid */
			if (get_to_uid(&vals[cnt].val.str_val, rq) < 0) {
				vals[cnt].nul = 1;
			}
			break;

		case 'X': /* response_timestamp */
			vals[cnt].val.time_val = time(0);
			break;

		default:
			LOG(L_CRIT, "BUG:acc:fmt2strar: unknown char: %c\n", *fmt);
			return 0;
		} /* switch (*fmt) */

		fmt++;
		cnt++;
	} /* while (*fmt) */

	return cnt;
}
Esempio n. 3
0
int rls_create_subscription(struct sip_msg *m, 
		rl_subscription_t **dst, 
		flat_list_t *flat, 
		xcap_query_params_t *params)
{
	rl_subscription_t *s;
	str from_uid = STR_NULL;
	int res;

	if (!dst) return RES_INTERNAL_ERR;
	*dst = NULL;

	s = rls_alloc_subscription(rls_external_subscription);
	if (!s) {
		LOG(L_ERR, "rls_create_new(): can't allocate memory\n");
		return RES_MEMORY_ERR;
	}
	generate_db_id(&s->dbid, s);

	res = sm_init_subscription_nolock(rls_manager, &s->u.external, m);
	if (res != RES_OK) {
		rls_free(s);
		return res;
	}
	
	if (params) {
		if (dup_xcap_params(&s->xcap_params, params) < 0) {
			ERR("can't duplicate xcap_params\n");
			rls_free(s);
			return -1;
		}
	}		

	/* store pointer to this RL subscription as user data 
	 * of (low level) subscription */
	s->u.external.usr_data = s;
	if (get_from_uid(&from_uid, m) < 0) str_clear(&s->from_uid);
	else str_dup(&s->from_uid, &from_uid);
			
/*	res = set_rls_info(m, s, xcap_root);
	if (res != 0) {
		rls_free(s);
		return res;
	}*/
	
	res = add_virtual_subscriptions(s, flat, max_list_nesting_level);
	if (res != 0) {
		rls_free(s);
		return res;
	}

	if (use_db) {
		if (rls_db_add(s) != 0) {
			rls_free(s);
			return RES_INTERNAL_ERR; /* FIXME RES_DB_ERR */
		}
	}

	*dst = s;
	return RES_OK;
}
Esempio n. 4
0
/* create an array of str's for accounting using a formatting string;
 * this is the heart of the accounting module -- it prints whatever
 * requested in a way, that can be used for syslog, radius,
 * sql, whatsoever
 * tm sip_msg_clones does not clone (shmmem-zed) parsed fields, other then Via1,2. Such fields clone now or use from rq_rp
 */
static int fmt2rad(char *fmt,
		   struct sip_msg *rq,
		   str* ouri,
		   struct hdr_field *to,
		   unsigned int code,
		   VALUE_PAIR** send,
		   time_t req_time)       /* Timestamp of the request */
{
	static unsigned int cseq_num, src_port, src_ip;
	static time_t rq_time, rs_time;
	int cnt;
	struct to_body* from, *pto;
	str val, *cr, *at;
	struct cseq_body *cseq;
	struct attr* attr;
	int dir;

	cnt = 0;
	dir = -2;

	     /* we don't care about parsing here; either the function
	      * was called from script, in which case the wrapping function
	      * is supposed to parse, or from reply processing in which case
	      * TM should have preparsed from REQUEST_IN callback.
	      */
	while(*fmt) {
		if (cnt == ALL_LOG_FMT_LEN) {
			LOG(L_ERR, "ERROR:acc:fmt2rad: Formatting string is too long\n");
			return 0;
		}

		attr = 0;
		switch(*fmt) {
		case 'a': /* attr */
			at = print_attrs(avps, avps_n, 0);
			if (at) {
				attr = &attrs[A_SER_ATTR];
				val = *at;
			}
			break;

		case 'c': /* sip_callid */
			if (rq->callid && rq->callid->body.len) {
				attr = &attrs[A_ACCT_SESSION_ID];
				val = rq->callid->body;
			}
			break;

		case 'd': /* to_tag */
			if (swap_dir && dir == -2) dir = get_direction(rq);
			if (dir <= 0) {
				if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) {
					attr = &attrs[A_SIP_TO_TAG];
					val = pto->tag_value;
				}
			} else {
				if (rq->from && (from = get_from(rq)) && from->tag_value.len) {
					attr = &attrs[A_SIP_TO_TAG];
					val = from->tag_value;
				}
			}
			break;

		case 'f': /* sip_from */
			if (rq->from && rq->from->body.len) {
				attr = &attrs[A_SER_FROM];
				val = rq->from->body;
			}
			break;

		case 'g': /* flags */
			attr = &attrs[A_SER_FLAGS];
			val.s = (char*)&rq->flags;
			val.len = sizeof(unsigned int);
			break;

		case 'i': /* inbound_ruri */
			attr = &attrs[A_SER_ORIGINAL_REQUEST_ID];
			val = rq->first_line.u.request.uri;
			break;

		case 'm': /* sip_method */
			attr = &attrs[A_SIP_METHOD];
			val = rq->first_line.u.request.method;
			break;

		case 'n': /* sip_cseq */
			if (rq->cseq && (cseq = get_cseq(rq)) && cseq->number.len) {
				attr = &attrs[A_SIP_CSEQ];
				str2int(&cseq->number, &cseq_num);
				val.s = (char*)&cseq_num;
				val.len = sizeof(unsigned int);
			}
			break;

		case 'o': /* outbound_ruri */
			attr = &attrs[A_SIP_TRANSLATED_REQUEST_ID];
			val = *ouri;
			break;

		case 'p': /* Source IP address */
			attr = &attrs[A_SIP_SOURCE_IP_ADDRESS];
			src_ip = ntohl(rq->rcv.src_ip.u.addr32[0]);
			val.s = (char*)&src_ip;
			val.len = sizeof(src_ip);
			break;

		case 'r': /* from_tag */
			if (swap_dir && dir == -2) dir = get_direction(rq);
			if (dir <= 0) {
				if (rq->from && (from = get_from(rq)) && from->tag_value.len) {
					attr = &attrs[A_SIP_FROM_TAG];
					val = from->tag_value;
				}
			} else {
				if (to && (pto = (struct to_body*)(to->parsed)) && pto->tag_value.len) {
					attr = &attrs[A_SIP_FROM_TAG];
					val = pto->tag_value;
				}
			}
			break;

		case 's': /* server_id */
			attr = &attrs[A_SER_SERVER_ID];
			val.s = (char*)&server_id;
			val.len = sizeof(int);
			break;

		case 't': /* sip_to */
			if (to && to->body.len) {
				attr = &attrs[A_SER_TO];
				val = to->body;
			}
			break;

		case 'u': /* digest_username */
			cr = cred_user(rq);
			if (cr) {
				attr = &attrs[A_SER_DIGEST_USERNAME];
				val = *cr;
			}
			break;

		case 'x': /* request_timestamp */
			attr = &attrs[A_SER_REQUEST_TIMESTAMP];
			rq_time = req_time;
			val.s = (char*)&rq_time;
			val.len = sizeof(time_t);
			break;

		case 'D': /* to_did */
			break;

		case 'F': /* from_uri */
			if (swap_dir && dir == -2) dir = get_direction(rq);
			if (dir <= 0) {
				if (rq->from && (from = get_from(rq)) && from->uri.len) {
					attr = &attrs[A_CALLING_STATION_ID];
					val = from->uri;
				}
			} else {
				if (rq->to && (pto = get_to(rq)) && pto->uri.len) {
					attr = &attrs[A_CALLING_STATION_ID];
					val = pto->uri;
				}
			}
			break;

		case 'I': /* from_uid */
			if (get_from_uid(&val, rq) < 0) {
				attr = &attrs[A_SER_FROM_UID];
			}
			break;

		case 'M': /* from_did */
			break;

		case 'P': /* Source port */
			attr = &attrs[A_SIP_SOURCE_PORT];
			src_port = rq->rcv.src_port;
			val.s = (char*)&src_port;
			val.len = sizeof(unsigned int);
			break;

		case 'R': /* digest_realm */
			cr = cred_realm(rq);
			if (cr) {
				attr = &attrs[A_SER_DIGEST_REALM];
				val = *cr;
			}
			break;

		case 'S': /* sip_status */
			attr = &attrs[A_SIP_RESPONSE_CODE];
			val.s = (char*)&code;
			val.len = sizeof(unsigned int);
			break;

		case 'T': /* to_uri */
			if (swap_dir && dir == -2) dir = get_direction(rq);
			if (dir <= 0) {
				if (rq->to && (pto = get_to(rq)) && pto->uri.len) {
					attr = &attrs[A_CALLED_STATION_ID];
					val = pto->uri;
				}
			} else {
				if (rq->from && (from = get_from(rq)) && from->uri.len) {
					attr = &attrs[A_CALLED_STATION_ID];
					val = from->uri;
				}
			}
			break;

		case 'U': /* to_uid */
			if (get_from_uid(&val, rq) < 0) {
				attr = &attrs[A_SER_TO_UID];
			}
			break;

		case 'X': /* response_timestamp */
			attr = &attrs[A_SER_RESPONSE_TIMESTAMP];
			rs_time = time(0);
			val.s = (char*)&rs_time;
			val.len = sizeof(time_t);
			break;

		default:
			LOG(L_CRIT, "BUG:acc:fmt2rad: unknown char: %c\n", *fmt);
			return -1;
		} /* switch (*fmt) */

		if (attr) {
			if (!rc_avpair_add(rh, send, ATTRID(attr->v), val.s, val.len, VENDOR(attr->v))) {
				LOG(L_ERR, "ERROR:acc:fmt2rad: Failed to add attribute %s\n",
				    attr->n);
				return -1;
			}
		}

		fmt++;
		cnt++;
	} /* while (*fmt) */

	return 0;
}