Beispiel #1
0
static inline int insert_siptrace_avp(struct usr_avp *avp,
		int_str *first_val,db_key_t *keys,db_val_t *vals)
{
	int_str        avp_value;

	if (avp == 0)
		return 0;

	if (!is_avp_str_val(avp)) {
		avp_value.s.s=int2str(first_val->n,&avp_value.s.len);
		LM_DBG("int val [%.*s]\n",avp_value.s.len,avp_value.s.s);
	} else {
		avp_value = *first_val;
		LM_DBG("str val [%.*s]\n",avp_value.s.len,avp_value.s.s);
	}
	db_vals[13].val.str_val.s = avp_value.s.s;
	db_vals[13].val.str_val.len = avp_value.s.len;

	LM_DBG("storing info 14...\n");
	CON_PS_REFERENCE(db_con) = &siptrace_ps;
	if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 )
		CON_RESET_INSLIST(db_con);
	if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0) {
		LM_ERR("error storing trace\n");
		return -1;
	}

	avp = search_next_avp( avp, &avp_value);
	while(avp!=NULL)
	{
		if (!is_avp_str_val(avp))
			avp_value.s.s=int2str(avp_value.n,&avp_value.s.len);
		db_vals[13].val.str_val.s = avp_value.s.s;
		db_vals[13].val.str_val.len = avp_value.s.len;

		LM_DBG("### - storing info 14 \n");
		CON_PS_REFERENCE(db_con) = &siptrace_ps;
		if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 )
			CON_RESET_INSLIST(db_con);
		if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0)
		{
			LM_ERR("error storing trace\n");
			return -1;
		}
		avp = search_next_avp( avp, &avp_value);
	}

	return 0;
}
/* this is only called from destroy_dlg, where the cell's entry 
 * lock is acquired
 */
int remove_dialog_from_db(struct dlg_cell * cell)
{
	static db_ps_t my_ps = NULL;
	db_val_t values[2];
	db_key_t match_keys[2] = { &h_entry_column, &h_id_column};

	/*if the dialog hasn 't been yet inserted in the database*/
	LM_DBG("trying to remove a dialog, update_flag is %i\n", cell->flags);
	if (cell->flags & DLG_FLAG_NEW) 
		return 0;

	if (use_dialog_table()!=0)
		return -1;

	VAL_TYPE(values) = VAL_TYPE(values+1) = DB_INT;
	VAL_NULL(values) = VAL_NULL(values+1) = 0;

	VAL_INT(values) 	= cell->h_entry;
	VAL_INT(values+1) 	= cell->h_id;

	CON_PS_REFERENCE(dialog_db_handle) = &my_ps;

	if(dialog_dbf.delete(dialog_db_handle, match_keys, 0, values, 2) < 0) {
		LM_ERR("failed to delete database information\n");
		return -1;
	}

	LM_DBG("callid was %.*s\n", cell->callid.len, cell->callid.s );

	/* dialog saved */
	run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

	return 0;
}
Beispiel #3
0
int acc_db_request( struct sip_msg *rq, struct sip_msg *rpl,
		query_list_t **ins_list)
{
	static db_ps_t my_ps_ins = NULL;
	static db_ps_t my_ps = NULL;
	int m;
	int n;
	int i;

	/* formated database columns */
	m = core2strar( rq, val_arr );

	for(i = 0; i < m; i++)
		VAL_STR(db_vals+i) = val_arr[i];
	/* time value */
	VAL_TIME(db_vals+(m++)) = acc_env.ts;

	/* extra columns */
	m += extra2strar( db_extra, rq, rpl, val_arr+m, 0);

	for( i++; i < m; i++)
		VAL_STR(db_vals+i) = val_arr[i];

	acc_dbf.use_table(db_handle, &acc_env.text/*table*/);
	CON_PS_REFERENCE(db_handle) = ins_list? &my_ps_ins : &my_ps;

	/* multi-leg columns */
	if ( !leg_info ) {
		if (con_set_inslist(&acc_dbf,db_handle,ins_list,db_keys,m) < 0 )
			CON_RESET_INSLIST(db_handle);
		if (acc_dbf.insert(db_handle, db_keys, db_vals, m) < 0) {
			LM_ERR("failed to insert into database\n");
			return -1;
		}
	} else {
		n = legs2strar(leg_info,rq,val_arr+m,1);
		do {
			for ( i = m; i < m + n; i++)
				VAL_STR(db_vals+i)=val_arr[i];
			if (con_set_inslist(&acc_dbf,db_handle,ins_list,db_keys,m+n) < 0 )
				CON_RESET_INSLIST(db_handle);
			if (acc_dbf.insert(db_handle, db_keys, db_vals, m+n) < 0) {
				LM_ERR("failed to insert into database\n");
				return -1;
			}
		}while ( (n = legs2strar(leg_info,rq,val_arr+m,0))!=0 );
	}

	return 1;
}
Beispiel #4
0
void flush_query_list(void)
{
	query_list_t *it;
	static db_ps_t my_ps = NULL;
	int i;

	/* no locks, only attendent is left at this point */
	for (it=*query_list;it;it=it->next)
	{
		if (it->no_rows > 0)
		{
			memset(&it->dbf,0,sizeof(db_func_t));
			if (db_bind_mod(&it->url,&it->dbf) < 0)
			{
				LM_ERR("failed to bind to db at shutdown\n");
				lock_release(it->lock);
				continue;
			}

			it->conn[process_no] = it->dbf.init(&it->url);
			if (it->conn[process_no] == 0)
			{
				LM_ERR("unable to connect to DB at shutdown\n");
				lock_release(it->lock);
				continue;
			}

			it->dbf.use_table(it->conn[process_no],&it->table);

			//Reset prepared statement between query lists/connections
			my_ps = NULL;

			CON_PS_REFERENCE(it->conn[process_no]) = &my_ps;

			/* and let's insert the rows */
			for (i=0;i<it->no_rows;i++)
			{
				if (it->dbf.insert(it->conn[process_no],it->cols,it->rows[i],
							it->col_no) < 0)
					LM_ERR("failed to insert into DB\n");

				shm_free(it->rows[i]);
			}

			/* no longer need this connection */
			if (it->conn[process_no] && it->dbf.close)
				it->dbf.close(it->conn[process_no]);
		}
	}
}
Beispiel #5
0
/*
 * Check if uri belongs to a local user
 */
int does_uri_exist(struct sip_msg* _msg, char* _s1, char* _s2)
{
	static db_ps_t my_ps = NULL;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t cols[1];
	db_res_t* res = NULL;

	if (parse_sip_msg_uri(_msg) < 0) {
		LM_ERR("Error while parsing URI\n");
		return ERR_INTERNAL;
	}

	if (use_uri_table != 0) {
		uridb_dbf.use_table(db_handle, &db_table);
		keys[0] = &uridb_uriuser_col;
		keys[1] = &uridb_domain_col;
		cols[0] = &uridb_uriuser_col;
	} else {
		uridb_dbf.use_table(db_handle, &db_table);
		keys[0] = &uridb_user_col;
		keys[1] = &uridb_domain_col;
		cols[0] = &uridb_user_col;
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = 0;
	VAL_STR(vals) = _msg->parsed_uri.user;
	VAL_STR(vals + 1) = _msg->parsed_uri.host;

	CON_PS_REFERENCE(db_handle) = &my_ps;

	if (uridb_dbf.query(db_handle, keys, 0, vals, cols, (use_domain ? 2 : 1),
				1, 0, &res) < 0) {
		LM_ERR("Error while querying database\n");
		return ERR_USERNOTFOUND;
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("User in request uri does not exist\n");
		uridb_dbf.free_result(db_handle, res);
		return ERR_DBEMTPYRES;
	} else {
		LM_DBG("User in request uri does exist\n");
		uridb_dbf.free_result(db_handle, res);
		return OK;
	}
}
Beispiel #6
0
static inline int insert_siptrace_flag(struct sip_msg *msg,
		db_key_t *keys,db_val_t *vals)
{
	db_vals[13].val.str_val.s   = "";
	db_vals[13].val.str_val.len = 0;

	LM_DBG("storing info 1...\n");
	if (con_set_inslist(&db_funcs,db_con,&ins_list,keys,NR_KEYS) < 0 )
		CON_RESET_INSLIST(db_con);
	CON_PS_REFERENCE(db_con) = &siptrace_ps;
	if(db_funcs.insert(db_con, keys, vals, NR_KEYS) < 0)
	{
			LM_ERR("error storing trace\n");
		return -1;
	}

	return 0;
}
Beispiel #7
0
int acc_db_cdrs(struct dlg_cell *dlg, struct sip_msg *msg)
{
	int total, nr_vals, i, j, ret, res = -1;
	time_t created, start_time;
	str core_s, leg_s, extra_s, table;
	short nr_legs;
	static db_ps_t my_ps = NULL;
	static query_list_t *ins_list = NULL;

	core_s.s = extra_s.s = leg_s.s = 0;

	ret = prebuild_core_arr(dlg, &core_s, &start_time);
	if (ret < 0) {
		LM_ERR("cannot copy core arguments\n");
		goto end;
	}

	ret = prebuild_extra_arr(dlg, msg, &extra_s,
			&db_extra_str, db_extra_bye, ret);
	if (ret < 0) {
		LM_ERR("cannot copy extra arguments\n");
		goto end;
	}

	/* here starts the extra leg */
	nr_vals = prebuild_leg_arr(dlg, &leg_s, &nr_legs);
	if (nr_vals < 0) {
		LM_ERR("cannot compute leg values\n");
		goto end;
	}

	if (!(created = acc_get_created(dlg))) {
		LM_ERR("cannot get created\n");
		goto end;
	}

	if (dlg_api.fetch_dlg_value(dlg, &table_str, &table, 0) < 0) {
		LM_ERR("error getting table name\n");
		return -1;
	}

	for (i=0;i<ACC_CORE_LEN;i++)
		VAL_STR(db_vals+i) = val_arr[i];
	for (i=ACC_CORE_LEN; i<ret; i++)
		VAL_STR(db_vals+i+1) = val_arr[i];

	VAL_TIME(db_vals+ACC_CORE_LEN) = start_time;
	VAL_INT(db_vals+ret+nr_vals+1) = time(NULL) - start_time;
	VAL_INT(db_vals+ret+nr_vals+2) = start_time - created;
	VAL_TIME(db_vals+ret+nr_vals+3) = created;

	total = ret + 4;
	acc_dbf.use_table(db_handle, &table);
	CON_PS_REFERENCE(db_handle) = &my_ps;

	if (!leg_info) {
		if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 )
			CON_RESET_INSLIST(db_handle);
		if (acc_dbf.insert(db_handle, db_keys, db_vals, total) < 0) {
			LM_ERR("failed to insert into database\n");
			goto end;
		}
	} else {
		total += nr_vals;
		leg_s.len = 4;
		for (i=0;i<nr_legs;i++) {
			complete_dlg_values(&leg_s,val_arr+ret,nr_vals);
			for (j = 0; j<nr_vals; j++)
				VAL_STR(db_vals+ret+j+1) = val_arr[ret+j];
			if (con_set_inslist(&acc_dbf,db_handle,&ins_list,db_keys,total) < 0 )
				CON_RESET_INSLIST(db_handle);
			if (acc_dbf.insert(db_handle,db_keys,db_vals,total) < 0) {
				LM_ERR("failed inserting into database\n");
				goto end;
			}
		}
	}

	res = 1;
end:
	if (core_s.s)
		pkg_free(core_s.s);
	if (extra_s.s)
		pkg_free(extra_s.s);
	if (leg_s.s)
		pkg_free(leg_s.s);
	return res;
}
Beispiel #8
0
static int alias_db_query(struct sip_msg* _msg, char* _table,
								struct sip_uri *puri, unsigned long flags,
								set_alias_f set_alias, void *param)
{
	static db_ps_t my_ps[4] = {NULL,NULL,NULL,NULL};
	str user_s, table_s;
	db_key_t db_keys[2];
	db_val_t db_vals[2];
	db_key_t db_cols[2];
	db_res_t* db_res = NULL;
	int i;
	int ps_idx=0;

	if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) {
		LM_ERR("invalid table parameter\n");
		return -1;
	}

	if (flags&ALIAS_REVERT_FLAG) {
		/* revert lookup: user->alias */
		db_keys[0] = &user_column;
		db_keys[1] = &domain_column;
		db_cols[0] = &alias_user_column;
		db_cols[1] = &alias_domain_column;
		ps_idx += 2;
	} else {
		/* rnormal lookup: alias->user */
		db_keys[0] = &alias_user_column;
		db_keys[1] = &alias_domain_column;
		db_cols[0] = &user_column;
		db_cols[1] = &domain_column;
	}

	db_vals[0].type = DB_STR;
	db_vals[0].nul = 0;
	db_vals[0].val.str_val.s = puri->user.s;
	db_vals[0].val.str_val.len = puri->user.len;

	if ( (flags&ALIAS_NO_DOMAIN_FLAG)==0 ) {
		db_vals[1].type = DB_STR;
		db_vals[1].nul = 0;
		db_vals[1].val.str_val.s = puri->host.s;
		db_vals[1].val.str_val.len = puri->host.len;

		if (domain_prefix.s && domain_prefix.len>0
			&& domain_prefix.len<puri->host.len
			&& strncasecmp(puri->host.s,domain_prefix.s,
				domain_prefix.len)==0)
		{
			db_vals[1].val.str_val.s   += domain_prefix.len;
			db_vals[1].val.str_val.len -= domain_prefix.len;
		}
		ps_idx ++;
	}

	adbf.use_table(db_handle, &table_s);
	if (!ald_append_branches)
		CON_PS_REFERENCE(db_handle) = my_ps[ps_idx];

	if(adbf.query( db_handle, db_keys, NULL, db_vals, db_cols,
		(flags&ALIAS_NO_DOMAIN_FLAG)?1:2 /*no keys*/, 2 /*no cols*/,
		NULL, &db_res)!=0)
	{
		LM_ERR("failed to query database\n");
		goto err_server;
	}

	if (RES_ROW_N(db_res)<=0 || RES_ROWS(db_res)[0].values[0].nul != 0) {
		LM_DBG("no alias found for R-URI\n");
		if (db_res!=NULL && adbf.free_result(db_handle, db_res) < 0)
			LM_DBG("failed to freeing result of query\n");
		return -1;
	}

	memcpy(useruri_buf, "sip:", 4);
	for(i=0; i<RES_ROW_N(db_res); i++)
	{
		user_s.len = 4;
		user_s.s = useruri_buf+4;
		switch(RES_ROWS(db_res)[i].values[0].type)
		{
			case DB_STRING:
				strcpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[0].val.string_val);
				user_s.len += strlen(user_s.s);
			break;
			case DB_STR:
				strncpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[0].val.str_val.s,
					RES_ROWS(db_res)[i].values[0].val.str_val.len);
				user_s.len += RES_ROWS(db_res)[i].values[0].val.str_val.len;
			break;
			case DB_BLOB:
				strncpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[0].val.blob_val.s,
					RES_ROWS(db_res)[i].values[0].val.blob_val.len);
				user_s.len += RES_ROWS(db_res)[i].values[0].val.blob_val.len;
			break;
			default:
				LM_ERR("unknown type of DB user column\n");
				if (db_res != NULL && adbf.free_result(db_handle, db_res)<0){
					LM_DBG("failed to freeing result of query\n");
				}
				goto err_server;
		}

		/* add the @*/
		useruri_buf[user_s.len] = '@';
		user_s.len++;

		/* add the domain */
		user_s.s = useruri_buf+user_s.len;
		switch(RES_ROWS(db_res)[i].values[1].type)
		{
			case DB_STRING:
				strcpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[1].val.string_val);
				user_s.len += strlen(user_s.s);
			break;
			case DB_STR:
				strncpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[1].val.str_val.s,
					RES_ROWS(db_res)[i].values[1].val.str_val.len);
				user_s.len += RES_ROWS(db_res)[i].values[1].val.str_val.len;
				useruri_buf[user_s.len] = '\0';
			break;
			case DB_BLOB:
				strncpy(user_s.s,
					(char*)RES_ROWS(db_res)[i].values[1].val.blob_val.s,
					RES_ROWS(db_res)[i].values[1].val.blob_val.len);
				user_s.len += RES_ROWS(db_res)[i].values[1].val.blob_val.len;
				useruri_buf[user_s.len] = '\0';
			break;
			default:
				LM_ERR("unknown type of DB user column\n");
				if (db_res != NULL && adbf.free_result(db_handle, db_res) < 0)
				{
					LM_DBG("failed to freeing result of query\n");
				}
				goto err_server;
		}
		user_s.s = useruri_buf;
		/* set the URI */
		LM_DBG("new URI [%d] is [%.*s]\n", i, user_s.len ,user_s.s );
		if (set_alias(_msg, &user_s, i, param)!=0) {
			LM_ERR("error while setting alias\n");
			goto err_server;
		}
	}

	/**
	 * Free the DB result
	 */
	if (db_res!=NULL && adbf.free_result(db_handle, db_res) < 0)
		LM_DBG("failed to freeing result of query\n");

	return 1;

err_server:
	if (db_res!=NULL && adbf.free_result(db_handle, db_res) < 0)
		LM_DBG("failed to freeing result of query\n");
	return -1;
}
Beispiel #9
0
/*
 * Check if username in specified header field is in a table
 */
int db_is_user_in(struct sip_msg* _msg, char* _hf, char* _grp)
{
	static db_ps_t my_ps = NULL;
	db_key_t keys[3];
	db_val_t vals[3];
	db_key_t col[1];
	db_res_t* res = NULL;

	keys[0] = &user_column;
	keys[1] = &group_column;
	keys[2] = &domain_column;
	col[0]  = &group_column;

	str hf_s = { NULL, 0 };
	str grp_s = { NULL, 0 };

	if(_hf ==  NULL || fixup_get_svalue(_msg, (gparam_p)_hf, &hf_s) != 0) {
		LM_ERR("Invalid parameter URI\n");
		return -1;
	}

	if(_grp == NULL || fixup_get_svalue(_msg, (gparam_p)_grp, &grp_s) != 0) {
		LM_ERR("Invalid parameter grp\n");
		return -1;
	}

	if ( get_username_domain( _msg, &hf_s, &(VAL_STR(vals)),
	&(VAL_STR(vals+2)))!=0) {
		LM_ERR("failed to get username@domain\n");
		return -1;
	}

	if (VAL_STR(vals).s==NULL || VAL_STR(vals).len==0 ) {
		LM_DBG("no username part\n");
		return -1;
	}

	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) = *(&grp_s);

	group_dbf.use_table(group_dbh, &table);
	CON_PS_REFERENCE(group_dbh) = &my_ps;

	if (group_dbf.query(group_dbh, keys, 0, vals, col, (use_domain) ? (3): (2),
				1, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		return -5;
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("user is not in group '%.*s'\n",
		    (grp_s.len), ZSW((grp_s.s)));
		group_dbf.free_result(group_dbh, res);
		return -6;
	} else {
		LM_DBG("user is in group '%.*s'\n",
			(grp_s.len), ZSW((grp_s.s)));
		group_dbf.free_result(group_dbh, res);
		return 1;
	}
}
Beispiel #10
0
/* store data in the table emergency_report
*/
int report(struct emergency_report *report, str db_url, str table_report) {

    static query_list_t *ins_list = NULL;
    static db_ps_t emergency_ps = NULL;

    LM_DBG("Report emergency call in db\n");

    db_funcs.use_table(db_con, &table_report);

    db_key_t db_keys[NR_KEYS];


    db_val_t db_vals[NR_KEYS];

    if (report == NULL) {
        LM_DBG("invalid parameter\n");
        return -1;
    }

    db_keys[0] = &id_rep_col;
    db_vals[0].type = DB_BIGINT;
    db_vals[0].val.bigint_val = 0;


    db_keys[1] = &callid_rep_col;
    db_vals[1].type = DB_STR;
    db_vals[1].val.str_val = report->callid;

    LM_DBG("CALLID_REPORT %.*s \n", report->callid.len, report->callid.s);
    LM_DBG("CALLID_REPORT_LEN %d \n", report->callid.len);

    db_keys[2] = &srid_rep_col;
    db_vals[2].type = DB_STR;
    db_vals[2].val.str_val = report->ert_srid;

    LM_DBG("SRID_REPORT %.*s \n", report->ert_srid.len, report->ert_srid.s);
    LM_DBG("SRID_REPORT_LEN %d \n", report->ert_srid.len);

    db_keys[3] = &resn_rep_col;
    db_vals[3].type = DB_BIGINT;
    db_vals[3].val.bigint_val = report->ert_resn;

    LM_DBG("RESN_REPORT %d \n", report->ert_resn);

    db_keys[4] = &npa_rep_col;
    db_vals[4].type = DB_BIGINT;
    db_vals[4].val.bigint_val = report->ert_npa;

    LM_DBG("NPA_REPORT %d \n", report->ert_npa);

    db_keys[5] = &esgwri_rep_col;
    db_vals[5].type = DB_STR;
    db_vals[5].val.str_val = report->esgwri;

    LM_DBG("ESGWRI_REPORT %.*s \n", report->esgwri.len, report->esgwri.s);
    LM_DBG("ESGWRI_REPORT_LEN %d \n", report->esgwri.len);

    db_keys[6] = &lro_rep_col;
    db_vals[6].type = DB_STR;
    db_vals[6].val.str_val = report->lro;

    LM_DBG("LRO_REPORT %.*s \n", report->lro.len, report->lro.s);
    LM_DBG("LRO_REPORT_LEN %d \n", report->lro.len);

    db_keys[7] = &vpc_name_rep_col;
    db_vals[7].type = DB_STR;
    db_vals[7].val.str_val = report->vpc_name;

    LM_DBG("VPC_NAME_REPORT %.*s \n", report->vpc_name.len, report->vpc_name.s);
    LM_DBG("VPC_NAME_REPORT_LEN %d \n", report->vpc_name.len);

    db_keys[8] = &vpc_host_rep_col;
    db_vals[8].type = DB_STR;
    db_vals[8].val.str_val = report->vpc_host;

    LM_DBG("VPC_HOST_REPORT %.*s \n", report->vpc_host.len, report->vpc_host.s);
    LM_DBG("VPC_HOST_REPORT_LEN %d \n", report->vpc_host.len);

    db_keys[9] = &timestamp_rep_col;
    db_vals[9].type = DB_STR;
    db_vals[9].val.str_val = report->timestamp;

    LM_DBG("VPC_TIMESTAMP_REPORT %.*s \n", report->timestamp.len, report->timestamp.s);
    LM_DBG("VPC_TIMESTAMP_REPORT_LEN %d \n", report->timestamp.len);

    db_keys[10] = &result_rep_col;
    db_vals[10].type = DB_STR;
    db_vals[10].val.str_val = report->result;

    LM_DBG("RESULT_REPORT %.*s \n", report->result.len, report->result.s);
    LM_DBG("RESULT_REPORT_LEN %d \n", report->result.len);

    db_keys[11] = &disposition_rep_col;
    db_vals[11].type = DB_STR;
    db_vals[11].val.str_val = report->disposition;

    LM_DBG("DISPOSITION_REPORT %.*s \n", report->disposition.len, report->disposition.s);
    LM_DBG("DISPOSITION_REPORT_LEN %d \n", report->disposition.len);


    // no field can be null 
    int i = 0;

    for (i = 0; i < NR_KEYS; i++)
        db_vals[i].nul = 0;

    LM_DBG("storing info...\n");

    if (con_set_inslist(&db_funcs, db_con, &ins_list, db_keys, NR_KEYS) < 0)
        CON_RESET_INSLIST(db_con);
    CON_PS_REFERENCE(db_con) = &emergency_ps;

    if (db_funcs.insert(db_con, db_keys, db_vals, NR_KEYS) < 0) {
        LM_ERR("failed to insert into database\n");
        return -1;;
    }
    
    return 1;
}
int update_dialog_dbinfo(struct dlg_cell * cell)
{
	static db_ps_t my_ps_insert = NULL;
	static db_ps_t my_ps_update = NULL;
	static db_ps_t my_ps_update_vp = NULL;
	struct dlg_entry entry;
	db_val_t values[DIALOG_TABLE_TOTAL_COL_NO];
	int callee_leg;

	db_key_t insert_keys[DIALOG_TABLE_TOTAL_COL_NO] = { &h_entry_column,
			&h_id_column,        &call_id_column,     &from_uri_column,
			&from_tag_column,    &to_uri_column,      &to_tag_column,
			&from_sock_column,   &to_sock_column,
			&start_time_column,  &mangled_fu_column,  &mangled_tu_column,
			
			&state_column,       &timeout_column,
			&from_cseq_column,   &to_cseq_column,     &from_ping_cseq_column,
			&to_ping_cseq_column,&flags_column,
			&vars_column,        &profiles_column,    &sflags_column,
			&from_route_column,
			&to_route_column,    &from_contact_column,&to_contact_column};

	if(use_dialog_table()!=0)
		return -1;

	callee_leg= callee_idx(cell);

	if((cell->flags & DLG_FLAG_NEW) != 0){
		/* save all the current dialogs information*/
		VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
		VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+16) =
		VAL_TYPE(values+17) = VAL_TYPE(values+18) = 
		VAL_TYPE(values+21) = DB_INT;

		VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
		VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
		VAL_TYPE(values+8) = VAL_TYPE(values+10) = VAL_TYPE(values+11) =
		VAL_TYPE(values+14) = VAL_TYPE(values+15) = 
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = VAL_TYPE(values+22) =
		VAL_TYPE(values+23) = VAL_TYPE(values+24) =
		VAL_TYPE(values+25) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);
		SET_STR_VALUE(values+2, cell->callid);

		SET_STR_VALUE(values+3, cell->from_uri);
		SET_STR_VALUE(values+4, cell->legs[DLG_CALLER_LEG].tag);
		SET_STR_VALUE(values+5, cell->to_uri);
		SET_STR_VALUE(values+6, cell->legs[callee_leg].tag);

		SET_STR_VALUE(values+7, cell->legs[DLG_CALLER_LEG].bind_addr->sock_str);
		if (cell->legs[callee_leg].bind_addr) {
			SET_STR_VALUE(values+8, 
				cell->legs[callee_leg].bind_addr->sock_str);
		} else {
			VAL_NULL(values+8) = 1;
		}

		SET_INT_VALUE(values+9, cell->start_ts);

		SET_STR_VALUE(values+10,cell->legs[callee_leg].from_uri);
		SET_STR_VALUE(values+11,cell->legs[callee_leg].to_uri);

		SET_INT_VALUE(values+12, cell->state);
		SET_INT_VALUE(values+13, (unsigned int)( (unsigned int)time(0) +
			 cell->tl.timeout - get_ticks()) );

		SET_STR_VALUE(values+14, cell->legs[DLG_CALLER_LEG].r_cseq);
		SET_STR_VALUE(values+15, cell->legs[callee_leg].r_cseq);
		SET_INT_VALUE(values+16,cell->legs[DLG_CALLER_LEG].last_gen_cseq);
		SET_INT_VALUE(values+17,cell->legs[callee_leg].last_gen_cseq);
		SET_INT_VALUE(values+18, cell->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED));
		set_final_update_cols(values+19, cell, 0);
		SET_STR_VALUE(values+22, cell->legs[DLG_CALLER_LEG].route_set);
		SET_STR_VALUE(values+23, cell->legs[callee_leg].route_set);
		SET_STR_VALUE(values+24, cell->legs[DLG_CALLER_LEG].contact);
		SET_STR_VALUE(values+25, cell->legs[callee_leg].contact);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_insert;

		if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, 
								DIALOG_TABLE_TOTAL_COL_NO)) !=0){
			LM_ERR("could not add another dialog to db\n");
			goto error;
		}

		/* dialog saved */
		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);

	} else if((cell->flags & DLG_FLAG_CHANGED) != 0) {
		/* save only dialog's state and timeout */
		VAL_TYPE(values) = VAL_TYPE(values+1) = 
		VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+16) =
		VAL_TYPE(values+17) = VAL_TYPE(values+18) =
		VAL_TYPE(values+21) =DB_INT;

		VAL_TYPE(values+14) = VAL_TYPE(values+15) =
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);
		SET_INT_VALUE(values+12, cell->state);
		SET_INT_VALUE(values+13, (unsigned int)( (unsigned int)time(0) +
				 cell->tl.timeout - get_ticks()) );

		SET_STR_VALUE(values+14, cell->legs[DLG_CALLER_LEG].r_cseq);
		SET_STR_VALUE(values+15, cell->legs[callee_leg].r_cseq);
		SET_INT_VALUE(values+16,cell->legs[DLG_CALLER_LEG].last_gen_cseq);
		SET_INT_VALUE(values+17,cell->legs[callee_leg].last_gen_cseq);
		SET_INT_VALUE(values+18, cell->flags);
		set_final_update_cols(values+19, cell, 1);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update;

		if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
						(values), (insert_keys+12), (values+12), 2, 10)) !=0){
			LM_ERR("could not update database info\n");
			goto error;
		}

		/* dialog saved */
		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~(DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);
	} else if (cell->flags & DLG_FLAG_VP_CHANGED) {
		cell->flags |= DLG_FLAG_VP_CHANGED;
		VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+21) = DB_INT;
		VAL_TYPE(values+19) = VAL_TYPE(values+20) = DB_STR;

		/* lock the entry */
		entry = (d_table->entries)[cell->h_entry];
		dlg_lock( d_table, &entry);

		SET_INT_VALUE(values, cell->h_entry);
		SET_INT_VALUE(values+1, cell->h_id);

		set_final_update_cols(values+19, cell, 0);

		CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update_vp;

		if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
						(values), (insert_keys+19), (values+19), 2, 3)) !=0){
			LM_ERR("could not update database info\n");
			goto error;
		}

		run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

		cell->flags &= ~DLG_FLAG_VP_CHANGED;
	} else {
		return 0;
	}

	dlg_unlock( d_table, &entry);
	return 0;

error:
	dlg_unlock( d_table, &entry);
	return -1;
}
void dialog_update_db(unsigned int ticks, void * param)
{
	static db_ps_t my_ps_update = NULL;
	static db_ps_t my_ps_insert = NULL;
	static db_ps_t my_ps_update_vp = NULL;
	int index;
	db_val_t values[DIALOG_TABLE_TOTAL_COL_NO];
	struct dlg_entry entry;
	struct dlg_cell  * cell; 
	unsigned char on_shutdown;
	int callee_leg,ins_done=0;
	static query_list_t *ins_list = NULL;

	db_key_t insert_keys[DIALOG_TABLE_TOTAL_COL_NO] = {	&h_entry_column,
			&h_id_column,		&call_id_column,		&from_uri_column,
			&from_tag_column,	&to_uri_column,			&to_tag_column,
			&from_sock_column,	&to_sock_column,		&start_time_column,
			&from_route_column,	&to_route_column, 	&from_contact_column,
			&to_contact_column, &mangled_fu_column, &mangled_tu_column,
			/*update chunk */
			&state_column,		&timeout_column,		&from_cseq_column,
			&to_cseq_column,	&from_ping_cseq_column, &to_ping_cseq_column,
			&vars_column,		&profiles_column,		&sflags_column, &flags_column};

	if (dialog_db_handle==0 || use_dialog_table()!=0)
		return;

	on_shutdown = (ticks==0);

	/*save the current dialogs information*/
	VAL_TYPE(values) = VAL_TYPE(values+1) = VAL_TYPE(values+9) = 
	VAL_TYPE(values+16) = VAL_TYPE(values+17) = VAL_TYPE(values+20) =
	VAL_TYPE(values+21) = VAL_TYPE(values+24) = VAL_TYPE(values+25)= DB_INT;

	VAL_TYPE(values+2) = VAL_TYPE(values+3) = VAL_TYPE(values+4) = 
	VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
	VAL_TYPE(values+8) = VAL_TYPE(values+10) = VAL_TYPE(values+11) = 
	VAL_TYPE(values+12) = VAL_TYPE(values+13) = VAL_TYPE(values+14) =
	VAL_TYPE(values+15) = VAL_TYPE(values+18) = VAL_TYPE(values+19) = 
	VAL_TYPE(values+22) = VAL_TYPE(values+23) = DB_STR;

	for(index = 0; index< d_table->size; index++){

		/* lock the whole entry */
		entry = (d_table->entries)[index];
		dlg_lock( d_table, &entry);

		for(cell = entry.first; cell != NULL; cell = cell->next){

			callee_leg = callee_idx(cell);

			if( (cell->flags & DLG_FLAG_NEW) != 0 ) {

				if ( cell->state == DLG_STATE_DELETED ) {
					/* don't need to insert dialogs already terminated */
					continue;
				}
				LM_DBG("inserting new dialog %p\n",cell);

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);
				SET_STR_VALUE(values+2, cell->callid);
				SET_STR_VALUE(values+3, cell->from_uri);

				SET_STR_VALUE(values+4, cell->legs[DLG_CALLER_LEG].tag);
				SET_STR_VALUE(values+5, cell->to_uri);
				SET_STR_VALUE(values+6, cell->legs[callee_leg].tag);

				SET_STR_VALUE(values+7,
					cell->legs[DLG_CALLER_LEG].bind_addr->sock_str);
				if (cell->legs[callee_leg].bind_addr) {
					SET_STR_VALUE(values+8, 
						cell->legs[callee_leg].bind_addr->sock_str);
				} else {
					VAL_NULL(values+8) = 1;
				}

				SET_INT_VALUE(values+9,  cell->start_ts);

				SET_STR_VALUE(values+10, cell->legs[DLG_CALLER_LEG].route_set);
				SET_STR_VALUE(values+11,
					cell->legs[callee_leg].route_set);
				SET_STR_VALUE(values+12, cell->legs[DLG_CALLER_LEG].contact);
				SET_STR_VALUE(values+13,
					cell->legs[callee_leg].contact);


				SET_STR_VALUE(values+14,cell->legs[callee_leg].from_uri);
				SET_STR_VALUE(values+15,cell->legs[callee_leg].to_uri);

				SET_INT_VALUE(values+16, cell->state);
				SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0)
					+ cell->tl.timeout - get_ticks()) );

				SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq);
				SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq);

				SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq);
				SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq);

				set_final_update_cols(values+22, cell, on_shutdown);
				SET_INT_VALUE(values+25, cell->flags & ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED));

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_insert;
				if (con_set_inslist(&dialog_dbf,dialog_db_handle,
				&ins_list,insert_keys,DIALOG_TABLE_TOTAL_COL_NO) < 0 )
					CON_RESET_INSLIST(dialog_db_handle);

				if((dialog_dbf.insert(dialog_db_handle, insert_keys, 
				values, DIALOG_TABLE_TOTAL_COL_NO)) !=0){
					LM_ERR("could not add another dialog to db\n");
					goto error;
				}

				if (ins_done==0)
					ins_done=1;

				/* dialog saved */
				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~(DLG_FLAG_NEW |DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);

			} else if ( (cell->flags & DLG_FLAG_CHANGED)!=0 || on_shutdown ){
				LM_DBG("updating existing dialog %p\n",cell);

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);

				SET_INT_VALUE(values+16, cell->state);
				SET_INT_VALUE(values+17, (unsigned int)((unsigned int)time(0)
					 + cell->tl.timeout - get_ticks()) );
				SET_STR_VALUE(values+18, cell->legs[DLG_CALLER_LEG].r_cseq);
				SET_STR_VALUE(values+19, cell->legs[callee_leg].r_cseq);
				SET_INT_VALUE(values+20, cell->legs[DLG_CALLER_LEG].last_gen_cseq);
				SET_INT_VALUE(values+21, cell->legs[callee_leg].last_gen_cseq);

				set_final_update_cols(values+22, cell, 1);
				SET_INT_VALUE(values+25, cell->flags);

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update;

				if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
				(values), (insert_keys+16), (values+16), 2, 10)) !=0) {
					LM_ERR("could not update database info\n");
					goto error;
				}

				/* dialog saved */
				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~(DLG_FLAG_CHANGED|DLG_FLAG_VP_CHANGED);
			} else if (cell->flags & DLG_FLAG_VP_CHANGED) {

				SET_INT_VALUE(values, cell->h_entry);
				SET_INT_VALUE(values+1, cell->h_id);

				set_final_update_cols(values+22, cell, 0);

				CON_PS_REFERENCE(dialog_db_handle) = &my_ps_update_vp;

				if((dialog_dbf.update(dialog_db_handle, (insert_keys), 0, 
				(values), (insert_keys+22), (values+22), 2, 3)) !=0) {
					LM_ERR("could not update database info\n");
					goto error;
				}

				run_dlg_callbacks( DLGCB_SAVED, cell, 0, DLG_DIR_NONE, 0);

				cell->flags &= ~DLG_FLAG_VP_CHANGED;
			}
		}
		dlg_unlock( d_table, &entry);

	}

	if (ins_done) {
		LM_DBG("dlg timer attempting to flush rows to DB\n");
		/* flush everything to DB
		 * so that next-time timer fires
		 * we are sure that DB updates will be succesful */
		if (ql_flush_rows(&dialog_dbf,dialog_db_handle,ins_list) < 0)
			LM_ERR("failed to flush rows to DB\n");
	}

	return;

error:
	dlg_unlock( d_table, &entry);
}
Beispiel #13
0
int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner)
{
	static db_ps_t my_ps = NULL;
	str user_s, table_s, uri_s;
	int nr_keys;
	struct sip_uri *puri;
	struct sip_uri turi;
	db_key_t db_keys[4];
	db_val_t db_vals[4];
	db_key_t db_cols[1];
	db_res_t* db_res = NULL;

	if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0)
	{
		LM_ERR("invalid table parameter");
		return -1;
	}

	/* init */
	nr_keys = 0;
	db_cols[0]=&new_uri_column;

	if(_owner)
	{
		memset(&turi, 0, sizeof(struct sip_uri));
		if(fixup_get_svalue(_msg, (gparam_p)_owner, &uri_s)!=0)
		{
			LM_ERR("invalid owner uri parameter");
			return -1;
		}
		if(parse_uri(uri_s.s, uri_s.len, &turi)!=0)
		{
			LM_ERR("bad owner SIP address!\n");
			goto err_server;
		}
		LM_DBG("using user id [%.*s]\n", uri_s.len, uri_s.s);
		puri = &turi;
	} else {
		/* take username@domain from From header */
		if ( (puri = parse_from_uri(_msg ))==NULL )
		{
			LM_ERR("failed to parse FROM header\n");
			goto err_server;
		}
	}

	db_keys[nr_keys]=&user_column;
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = puri->user.s;
	db_vals[nr_keys].val.str_val.len = puri->user.len;
	nr_keys++;

	if(use_domain>=1)
	{
		db_keys[nr_keys]=&domain_column;
		db_vals[nr_keys].type = DB_STR;
		db_vals[nr_keys].nul = 0;
		db_vals[nr_keys].val.str_val.s = puri->host.s;
		db_vals[nr_keys].val.str_val.len = puri->host.len;
		nr_keys++;

		if (dstrip_s.s!=NULL && dstrip_s.len>0
			&& dstrip_s.len<puri->host.len
			&& strncasecmp(puri->host.s,dstrip_s.s,dstrip_s.len)==0)
		{
			db_vals[nr_keys].val.str_val.s   += dstrip_s.len;
			db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
		}
	}
	/* take sd from r-uri */
	if (parse_sip_msg_uri(_msg) < 0)
	{
		LM_ERR("failed to parsing Request-URI\n");
		goto err_server;
	}

	db_keys[nr_keys]=&sd_user_column;
	db_vals[nr_keys].type = DB_STR;
	db_vals[nr_keys].nul = 0;
	db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.user.s;
	db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.user.len;
	nr_keys++;

	if(use_domain>=2)
	{
		db_keys[nr_keys]=&sd_domain_column;
		db_vals[nr_keys].type = DB_STR;
		db_vals[nr_keys].nul = 0;
		db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.host.s;
		db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.host.len;
		nr_keys++;

		if (dstrip_s.s!=NULL && dstrip_s.len>0
			&& dstrip_s.len<_msg->parsed_uri.host.len
			&& strncasecmp(_msg->parsed_uri.host.s,dstrip_s.s,dstrip_s.len)==0)
		{
			db_vals[nr_keys].val.str_val.s   += dstrip_s.len;
			db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
		}
	}

	db_funcs.use_table(db_handle, &table_s);
	CON_PS_REFERENCE(db_handle) = &my_ps;

	if(db_funcs.query(db_handle, db_keys, NULL, db_vals, db_cols,
		nr_keys /*no keys*/, 1 /*no cols*/, NULL, &db_res)!=0)
	{
		LM_ERR("failed to query database\n");
		goto err_server;
	}

	if (RES_ROW_N(db_res)<=0 || RES_ROWS(db_res)[0].values[0].nul != 0)
	{
		LM_DBG("no sip addres found for R-URI\n");
		if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0)
			LM_DBG("failed to free result of query\n");
		return -1;
	}

	user_s.s = useruri_buf+4;
	switch(RES_ROWS(db_res)[0].values[0].type)
	{
		case DB_STRING:
			strcpy(user_s.s,
				(char*)RES_ROWS(db_res)[0].values[0].val.string_val);
			user_s.len = strlen(user_s.s);
		break;
		case DB_STR:
			strncpy(user_s.s,
				(char*)RES_ROWS(db_res)[0].values[0].val.str_val.s,
				RES_ROWS(db_res)[0].values[0].val.str_val.len);
			user_s.len = RES_ROWS(db_res)[0].values[0].val.str_val.len;
			user_s.s[user_s.len] = '\0';
		break;
		case DB_BLOB:
			strncpy(user_s.s,
				(char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s,
				RES_ROWS(db_res)[0].values[0].val.blob_val.len);
			user_s.len = RES_ROWS(db_res)[0].values[0].val.blob_val.len;
			user_s.s[user_s.len] = '\0';
		default:
			LM_ERR("unknown type of DB new_uri column\n");
			if (db_res != NULL && db_funcs.free_result(db_handle, db_res) < 0)
			{
				LM_DBG("failed to free result of query\n");
			}
			goto err_server;
	}

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

	/**
	 * Free the result because we don't need it anymore
	 */
	if (db_res!=NULL && db_funcs.free_result(db_handle, db_res) < 0)
		LM_DBG("failed to free result of query\n");

	/* set the URI */
	LM_DBG("URI of sd from R-URI [%.*s]\n", user_s.len,user_s.s);
	if(set_ruri(_msg, &user_s)<0)
	{
		LM_ERR("failed to replace the R-URI\n");
		goto err_server;
	}

	return 1;

err_server:
	return -1;
}
Beispiel #14
0
/*
 * Check if a header field contains the same username
 * as digest credentials
 */
static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
{
	static db_ps_t my_ps = NULL;
	struct hdr_field* h;
	auth_body_t* c;
	db_key_t keys[3];
	db_val_t vals[3];
	db_key_t cols[1];
	db_res_t* res = NULL;

	if (_uri == NULL) {
		LM_ERR("Bad parameter\n");
		return ERR_INTERNAL;
	}

	/* Get authorized digest credentials */
	get_authorized_cred(_m->authorization, &h);
	if (h == NULL) {
		get_authorized_cred(_m->proxy_auth, &h);
		if (h == NULL) {
			LM_ERR("No authorized credentials found (error in scripts)\n");
			LM_ERR("Call {www,proxy}_authorize before calling check_* functions!\n");
			update_stat(negative_checks, 1);
			return ERR_CREDENTIALS;
		}
	}

	c = (auth_body_t*)(h->parsed);

	/* Parse To/From URI */
	/* Make sure that the URI contains username */
	if (_uri->user.len == 0) {
		LM_ERR("Username not found in URI\n");
		return ERR_USERNOTFOUND;
	}

	/* If use_uri_table is set, use URI table to determine if Digest username
	 * and To/From username match. URI table is a table enumerating all allowed
	 * usernames for a single, thus a user can have several different usernames
	 * (which are different from digest username and it will still match)
	 */
	if (use_uri_table != 0) {
		keys[0] = &uridb_user_col;
		keys[1] = &uridb_domain_col;
		keys[2] = &uridb_uriuser_col;
		cols[0] = &uridb_user_col;

		/* The whole fields are type DB_STR, and not null */
		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) = c->digest.username.user;
		VAL_STR(vals + 1) = *GET_REALM(&c->digest);
		VAL_STR(vals + 2) = _uri->user;

		uridb_dbf.use_table(db_handle, &db_table);
		CON_PS_REFERENCE(db_handle) = &my_ps;

		if (uridb_dbf.query(db_handle, keys, 0, vals, cols, 3, 1, 0, &res) < 0)
		{
			LM_ERR("Error while querying database\n");
			return ERR_DBQUERY;
		}

		/* If the previous function returns at least one row, it means
		 * there is an entry for given digest username and URI username
		 * and thus this combination is allowed and the function will match
		 */
		if (RES_ROW_N(res) == 0) {
			LM_DBG("From/To user '%.*s' is spoofed\n",
				   _uri->user.len, ZSW(_uri->user.s));
			uridb_dbf.free_result(db_handle, res);
			update_stat(negative_checks, 1);
			return ERR_SPOOFEDUSER;
		} else {
			LM_DBG("From/To user '%.*s' and auth user match\n",
				   _uri->user.len, ZSW(_uri->user.s));
			uridb_dbf.free_result(db_handle, res);
			update_stat(positive_checks, 1);
			return OK;
		}
	} else {
		/* URI table not used, simply compare digest username and From/To
		 * username, the comparison is case insensitive
		 */
		if (_uri->user.len == c->digest.username.user.len) {
			if (!strncasecmp(_uri->user.s, c->digest.username.user.s,
			_uri->user.len)) {
				LM_DBG("Digest username and URI username match\n");
				update_stat(positive_checks, 1);
				return OK;
			}
		}

		LM_DBG("Digest username and URI username do NOT match\n");
		update_stat(negative_checks, 1);
		return ERR_NOMATCH;
	}
}
Beispiel #15
0
/**
 * Retrieves authentication id and realm from uri_table for a given sip uri
 */
int get_auth_id(struct sip_msg* _msg, char* _uri, char* _auth_user, char* _auth_realm)
{
	str uri, sip_user, sip_domain;
	struct sip_uri sip_uri;
	int_str ret_authuser, ret_authrealm;
	static db_ps_t my_ps = NULL;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t cols[2];
	db_res_t* dbres = NULL;
	db_row_t* dbres_row;


	// retrieve the string value of the given uri (pseudo variables will also be
	// already substituted with their proper values)
	if (_uri == NULL || pv_printf_s(_msg, (pv_elem_t *) _uri, &uri) != 0 ||
	uri.len == 0 || uri.s == NULL) {
		LM_WARN("cannot get string for value\n");
		return -1;
	}

	// check if we really have a valid uri as parameter
	// TODO: check Bug ID 2685700
	if (parse_uri(uri.s, strlen(uri.s), &sip_uri) < 0
			&& (sip_uri.user.s == NULL || sip_uri.user.len <= 0)) {
		LM_ERR("First parameter must be a URI (val = '%s').", uri.s);
		return -1;
	}

	// split uri into user and realm part
	sip_user.s = strtok(sip_uri.user.s, "@");
	sip_domain.s = strtok(NULL, "@");
	sip_user.len = strlen(sip_user.s);
	sip_domain.len = strlen(sip_domain.s);

	if (use_uri_table != 0) {
		uridb_dbf.use_table(db_handle, &db_table);
		keys[0] = &uridb_uriuser_col;
		keys[1] = &uridb_domain_col;
		cols[0] = &uridb_user_col;
		cols[1] = &uridb_domain_col;
	} else {
		uridb_dbf.use_table(db_handle, &db_table);
		keys[0] = &uridb_user_col;
		keys[1] = &uridb_domain_col;
		cols[0] = &uridb_user_col;
		cols[1] = &uridb_domain_col;
	}

	VAL_TYPE(vals) = DB_STR;
	VAL_NULL(vals) = 0;
	VAL_STR(vals) = sip_user;

	VAL_TYPE(vals + 1) = DB_STR;
	VAL_NULL(vals + 1) = 0;
	VAL_STR(vals + 1) = sip_domain;

	CON_PS_REFERENCE(db_handle) = &my_ps;

	// if use_domain is set also the domain column of the database table will
	// be honoured in the following query (see sixth parameter)
	if (uridb_dbf.query(db_handle, keys, 0, vals, cols, (use_domain ? 2 : 1), 2, 0, &dbres) < 0) {
		LM_ERR("Error while querying database");
		return ERR_DBQUERY;
	}

	if (RES_ROW_N(dbres) == 0) {
		LM_DBG("User in given uri is not local.");
		uridb_dbf.free_result(db_handle, dbres);
		return ERR_USERNOTFOUND;
	}

	// if more than one matching db entry is found, there is either a duplicate or a
	// wrong tuple in the database. or maybe just the 'use_domain' paramter should be set.
	if (RES_ROW_N(dbres) > 1) {
		LM_WARN("Multiple entries are matching the given uri. Consider setting the 'use_domain' param.");
	}

	LM_DBG("User in request uri does exist");

	// in the case there is more than a single match, the above warning is presented
	// to the user. anyway we continue by just using the first result row only.
	dbres_row = RES_ROWS(dbres);

	// check the datatypes of the results of the database query
	if (ROW_VALUES(dbres_row)->type != DB_STRING) {
		LM_ERR("Database '%s' column is not of type string.", ((str*) cols[0])->s);
		return ERR_DBUSE;
	}
	if ((ROW_VALUES(dbres_row)+1)->type != DB_STRING) {
		LM_ERR("Database '%s' column is not of type string.", ((str*) cols[1])->s);
		return ERR_DBUSE;
	}

	// set result parameters
	ret_authuser.s.s = (char*) VAL_STRING(ROW_VALUES(dbres_row));
	ret_authuser.s.len = strlen(ret_authuser.s.s);
	ret_authrealm.s.s = (char*) VAL_STRING(ROW_VALUES(dbres_row)+1);
	ret_authrealm.s.len = strlen(ret_authrealm.s.s);
	set_result_pv(_msg, AVP_VAL_STR, ret_authuser, _auth_user);
	set_result_pv(_msg, AVP_VAL_STR, ret_authrealm, _auth_realm);

	uridb_dbf.free_result(db_handle, dbres);

	return OK;
}
Beispiel #16
0
static inline int get_ha1(struct username* _username, str* _domain,
			  const str* _table, char* _ha1, db_res_t** res)
{
	struct aaa_avp *cred;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t *col;
	str result;
	static db_ps_t auth_ps = NULL;

	int n, nc;

	col = pkg_malloc(sizeof(*col) * (credentials_n + 1));
	if (col == NULL) {
		LM_ERR("no more pkg memory\n");
		return -1;
	}

	keys[0] = &user_column;
	keys[1] = &domain_column;

	/* should we calculate the HA1, and is it calculated with domain? */
	col[0] = (_username->domain.len && !calc_ha1) ?
		(&pass_column_2) : (&pass_column);

	for (n = 0, cred=credentials; cred ; n++, cred=cred->next) {
		col[1 + n] = &cred->attr_name;
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB_STR;
	VAL_NULL(vals) = VAL_NULL(vals + 1) = 0;

	VAL_STR(vals).s = _username->user.s;
	VAL_STR(vals).len = _username->user.len;

	if (_username->domain.len) {
		VAL_STR(vals + 1) = _username->domain;
	} else {
		VAL_STR(vals + 1) = *_domain;
	}

	if (auth_dbf.use_table(auth_db_handle, _table) < 0) {
		LM_ERR("failed to use_table\n");
		pkg_free(col);
		return -1;
	}

	CON_PS_REFERENCE(auth_db_handle) = &auth_ps;

	n = (use_domain ? 2 : 1);
	nc = 1 + credentials_n;
	if (auth_dbf.query(auth_db_handle, keys, 0, vals, col, n, nc, 0, res) < 0) {
		LM_ERR("failed to query database\n");
		pkg_free(col);
		return -1;
	}
	pkg_free(col);

	if (RES_ROW_N(*res) == 0) {
		LM_DBG("no result for user \'%.*s@%.*s\'\n",
				_username->user.len, ZSW(_username->user.s),
			(use_domain ? (_domain->len) : 0), ZSW(_domain->s));
		return 1;
	}

	result.s = (char*)ROW_VALUES(RES_ROWS(*res))[0].val.string_val;
	result.len = strlen(result.s);

	if (calc_ha1) {
		/* Only plaintext passwords are stored in database,
		 * we have to calculate HA1 */
		auth_api.calc_HA1(HA_MD5, &_username->whole, _domain, &result,
				0, 0, _ha1);
		LM_DBG("HA1 string calculated: %s\n", _ha1);
	} else {
		memcpy(_ha1, result.s, result.len);
		_ha1[result.len] = '\0';
	}

	return 0;
}