コード例 #1
0
ファイル: dbcassa_base.cpp プロジェクト: adubovikov/kamailio
/*
 * Query table for specified rows
 * _h: structure representing database connection
 * _k: key names
 * _op: operators
 * _v: values of the keys that must match
 * _c: column names to return
 * _n: number of key=values pairs to compare
 * _nc: number of columns to return
 * _o: order by the specified column
 */
int db_cassa_query(const db1_con_t* _h, const db_key_t* _k, const db_op_t* _op,
		const db_val_t* _v, const db_key_t* _c, int _n, int _nc,
		const db_key_t _o, db1_res_t** _r)
{
	db1_res_t* db_res = 0;
	int rows_no;
	ColumnVecPtr cassa_result;
	dbcassa_table_p tbc;
	int seckey_len;

	if (!_h || !CON_TABLE(_h) || !_r) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}
	LM_DBG("query table=%s\n", _h->table->s);

	/** Construct and send the query to Cassandra Cluster **/

	cassa_result = cassa_translate_query(_h, _k, _v, _c, _n, _nc, &rows_no);

	if(cassa_result.get() == NULL) {
		LM_ERR("Failed to query Cassandra cluster\n");
		return -1;
	}

	/* compare the number of queried cols with the key cols*/
//	if(no_kc + no_sec_kc < _n) { /* TODO */
		/* filter manually for the rest of the values */
//	}

	db_res = db_new_result();
	if (!db_res) {
		LM_ERR("no memory left\n");
		goto error;
	}
	RES_COL_N(db_res)= _nc;
	if(!db_allocate_columns(db_res, _nc) < 0) {
		LM_ERR("no more memory\n");
		goto error;
	}

	tbc = dbcassa_db_get_table(&CON_CASSA(_h)->db_name, CON_TABLE(_h));
	if(!tbc) {
		LM_ERR("table %.*s does not exist!\n", CON_TABLE(_h)->len, CON_TABLE(_h)->s);
		return -1;
	}

	/** Convert the result from Cassandra **/
	/* fill in the columns name and type */
	for(int col = 0; col < _nc; col++) {
		RES_NAMES(db_res)[col] = (str*)pkg_malloc(sizeof(str));
		if (! RES_NAMES(db_res)[col]) {
			LM_ERR("no private memory left\n");
			dbcassa_lock_release(tbc);
			RES_COL_N(db_res) = col;
			db_free_columns(db_res);
			goto error;
		}

		*RES_NAMES(db_res)[col]   = *_c[col];

		/* search the column in table schema to get the type */
		dbcassa_column_p colp = cassa_search_col(tbc, _c[col]);
		if(!colp) {
			LM_ERR("No column with name [%.*s] found\n", _c[col]->len, _c[col]->s);
			dbcassa_lock_release(tbc);
			RES_COL_N(db_res) = col;
			db_free_columns(db_res);
			goto error;
		}
		RES_TYPES(db_res)[col] = colp->type;

		LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(db_res)[col], col,
				RES_NAMES(db_res)[col]->len, RES_NAMES(db_res)[col]->s);
	}
	/* TODO  if all columns asked - take from table schema */
	seckey_len = tbc->seckey_len;
	dbcassa_lock_release(tbc);

	if(!cassa_result->size()) {
		LM_DBG("The query returned no result\n");
		RES_ROW_N(db_res) = 0;
		goto done;
	}

	/* Initialize the row_slices vector for the case with one column and no secondary key */
	if(rows_no == 1) {
		row_slices[0][0]= cassa_result->size();
		row_slices[0][1]= 0;

		if(seckey_len) { /* if the table has a secondary key defined */
			/* pass through the result once to see how many rows there are */
			rows_no = cassa_result_separate_rows(*cassa_result);
			if(rows_no < 0) {
				LM_ERR("Wrong formated column names\n");
				goto error;
			}
		}
	}

	RES_ROW_N(db_res) = rows_no;

	if (db_allocate_rows(db_res) < 0) {
		LM_ERR("could not allocate rows");
		goto error;
	}

	for(int ri=0; ri < rows_no; ri++) {
		if (db_allocate_row(db_res, &(RES_ROWS(db_res)[ri])) != 0) {
			LM_ERR("could not allocate row");
			goto error;
		}

		/* complete the row with the columns */
		for(int col = 0; col< _nc; col++) {
			RES_ROWS(db_res)[ri].values[col].type = RES_TYPES(db_res)[col];
			cassa_convert_result(_c[col], *cassa_result, (ri>0?row_slices[ri-1][0]:0),  row_slices[ri][0],
					row_slices[ri][1], &RES_ROWS(db_res)[ri].values[col]);
		}
	}

done:
	*_r = db_res;
	LM_DBG("Exited with success\n");
	return 0;

error:
	if(db_res)
		db_free_result(db_res);
	return -1;
}
コード例 #2
0
ファイル: pua.c プロジェクト: TheGrandWazoo/kamailio
static int db_restore(void)
{
	ua_pres_t* p= NULL;
	db_key_t result_cols[19];
	db1_res_t *res= NULL;
	db_row_t *row = NULL;
	db_val_t *row_vals= NULL;
	str pres_uri, pres_id;
	str etag, tuple_id;
	str watcher_uri, call_id;
	str to_tag, from_tag, remote_contact;
	str record_route, contact, extra_headers;
	int size= 0, i;
	int n_result_cols= 0;
	int puri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col;
	int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col;
	int event_col,contact_col,tuple_col,record_route_col, extra_headers_col;
	int version_col;
	unsigned int hash_code;

	if (dbmode==PUA_DB_ONLY)
	{
		LM_ERR( "db_restore shouldn't be called in PUA_DB_ONLY mode\n" );
		return(-1);
	}

	result_cols[puri_col=n_result_cols++]	= &str_pres_uri_col;
	result_cols[pid_col=n_result_cols++]	= &str_pres_id_col;
	result_cols[expires_col=n_result_cols++]= &str_expires_col;
	result_cols[flag_col=n_result_cols++]	= &str_flag_col;
	result_cols[etag_col=n_result_cols++]	= &str_etag_col;
	result_cols[tuple_col=n_result_cols++]	= &str_tuple_id_col;
	result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col;
	result_cols[callid_col=n_result_cols++] = &str_call_id_col;
	result_cols[totag_col=n_result_cols++]	= &str_to_tag_col;
	result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col;
	result_cols[cseq_col= n_result_cols++]	= &str_cseq_col;
	result_cols[event_col= n_result_cols++]	= &str_event_col;
	result_cols[record_route_col= n_result_cols++]	= &str_record_route_col;
	result_cols[contact_col= n_result_cols++]	= &str_contact_col;
	result_cols[remote_contact_col= n_result_cols++]	= &str_remote_contact_col;
	result_cols[extra_headers_col= n_result_cols++]	= &str_extra_headers_col;
	result_cols[desired_expires_col= n_result_cols++]	= &str_desired_expires_col;
	result_cols[version_col= n_result_cols++]	= &str_version_col;

	if(!pua_db)
	{
		LM_ERR("null database connection\n");
		return -1;
	}

	if(pua_dbf.use_table(pua_db, &db_table)< 0)
	{
		LM_ERR("in use table\n");
		return -1;
	}

	if(db_fetch_query(&pua_dbf, pua_fetch_rows, pua_db, 0, 0, 0, result_cols,
				0, n_result_cols, 0, &res)< 0)
	{
		LM_ERR("while querrying table\n");
		if(res)
		{
			pua_dbf.free_result(pua_db, res);
			res = NULL;
		}
		return -1;
	}
	if(res==NULL)
		return -1;

	if(res->n<=0)
	{
		LM_INFO("the query returned no result\n");
		pua_dbf.free_result(pua_db, res);
		res = NULL;
		return 0;
	}

	do {
		LM_DBG("found %d db entries\n", res->n);

		for(i =0 ; i< res->n ; i++)
		{
			row = &res->rows[i];
			row_vals = ROW_VALUES(row);

			pres_uri.s= (char*)row_vals[puri_col].val.string_val;
			pres_uri.len = strlen(pres_uri.s);

			LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s);

			memset(&etag,			 0, sizeof(str));
			memset(&tuple_id,		 0, sizeof(str));
			memset(&watcher_uri,	 0, sizeof(str));
			memset(&call_id,		 0, sizeof(str));
			memset(&to_tag,			 0, sizeof(str));
			memset(&from_tag,		 0, sizeof(str));
			memset(&record_route,	 0, sizeof(str));
			memset(&pres_id,         0, sizeof(str));
			memset(&contact,         0, sizeof(str));
			memset(&remote_contact,         0, sizeof(str));
			memset(&extra_headers,   0, sizeof(str));

			pres_id.s= (char*)row_vals[pid_col].val.string_val;
			if(pres_id.s)
				pres_id.len = strlen(pres_id.s);

			if(row_vals[etag_col].val.string_val)
			{
				etag.s= (char*)row_vals[etag_col].val.string_val;
				etag.len = strlen(etag.s);

				tuple_id.s= (char*)row_vals[tuple_col].val.string_val;
				tuple_id.len = strlen(tuple_id.s);
			}

			if(row_vals[watcher_col].val.string_val)
			{
				watcher_uri.s= (char*)row_vals[watcher_col].val.string_val;
				watcher_uri.len = strlen(watcher_uri.s);

				call_id.s= (char*)row_vals[callid_col].val.string_val;
				call_id.len = strlen(call_id.s);

				to_tag.s= (char*)row_vals[totag_col].val.string_val;
				to_tag.len = strlen(to_tag.s);

				from_tag.s= (char*)row_vals[fromtag_col].val.string_val;
				from_tag.len = strlen(from_tag.s);

				if(row_vals[record_route_col].val.string_val)
				{
					record_route.s= (char*)row_vals[record_route_col].val.string_val;
					record_route.len= strlen(record_route.s);
				}

				contact.s= (char*)row_vals[contact_col].val.string_val;
				contact.len = strlen(contact.s);

				remote_contact.s= (char*)row_vals[remote_contact_col].val.string_val;
				remote_contact.len = strlen(remote_contact.s);
			}
			extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val;
			if(extra_headers.s)
				extra_headers.len= strlen(extra_headers.s);
			else
				extra_headers.len= 0;

			size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+
					tuple_id.len)* sizeof(char);
			if(extra_headers.s)
				size+= sizeof(str)+ extra_headers.len* sizeof(char);

			if(watcher_uri.s)
				size+= sizeof(str)+ (watcher_uri.len+ call_id.len+ to_tag.len+
						from_tag.len+ record_route.len+ contact.len)* sizeof(char);

			p= (ua_pres_t*)shm_malloc(size);
			if(p== NULL)
			{
				LM_ERR("no more share memmory");
				goto error;
			}
			memset(p, 0, size);
			size= sizeof(ua_pres_t);

			p->pres_uri= (str*)((char*)p+ size);
			size+= sizeof(str);
			p->pres_uri->s= (char*)p + size;
			memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len);
			p->pres_uri->len= pres_uri.len;
			size+= pres_uri.len;

			if(pres_id.s)
			{
				p->id.s= (char*)p + size;
				memcpy(p->id.s, pres_id.s, pres_id.len);
				p->id.len= pres_id.len;
				size+= pres_id.len;
			}
			if(tuple_id.s && tuple_id.len)
			{
				p->tuple_id.s= (char*)p + size;
				memcpy(p->tuple_id.s, tuple_id.s, tuple_id.len);
				p->tuple_id.len= tuple_id.len;
				size+= tuple_id.len;
			}

			if(watcher_uri.s && watcher_uri.len)
			{
				p->watcher_uri= (str*)((char*)p+ size);
				size+= sizeof(str);

				p->watcher_uri->s= (char*)p+ size;
				memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len);
				p->watcher_uri->len= watcher_uri.len;
				size+= watcher_uri.len;

				p->to_tag.s= (char*)p+ size;
				memcpy(p->to_tag.s, to_tag.s, to_tag.len);
				p->to_tag.len= to_tag.len;
				size+= to_tag.len;

				p->from_tag.s= (char*)p+ size;
				memcpy(p->from_tag.s, from_tag.s, from_tag.len);
				p->from_tag.len= from_tag.len;
				size+= from_tag.len;

				p->call_id.s= (char*)p + size;
				memcpy(p->call_id.s, call_id.s, call_id.len);
				p->call_id.len= call_id.len;
				size+= call_id.len;

				if(record_route.s && record_route.len)
				{
					p->record_route.s= (char*)p + size;
					memcpy(p->record_route.s, record_route.s, record_route.len);
					p->record_route.len= record_route.len;
					size+= record_route.len;
				}
				p->contact.s= (char*)p + size;
				memcpy(p->contact.s, contact.s, contact.len);
				p->contact.len= contact.len;
				size+= contact.len;

				p->cseq= row_vals[cseq_col].val.int_val;

				p->remote_contact.s= (char*)shm_malloc(remote_contact.len* sizeof(char));
				if(p->remote_contact.s== NULL)
				{
					LM_ERR("No more shared memory\n");
					goto error;
				}
				memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len);
				p->remote_contact.len= remote_contact.len;

				p->version= row_vals[version_col].val.int_val;
			}

			if(extra_headers.s)
			{
				p->extra_headers= (str*)((char*)p+ size);
				size+= sizeof(str);
				p->extra_headers->s= (char*)p+ size;
				memcpy(p->extra_headers->s, extra_headers.s, extra_headers.len);
				p->extra_headers->len= extra_headers.len;
				size+= extra_headers.len;
			}

			LM_DBG("size= %d\n", size);
			p->event= row_vals[event_col].val.int_val;
			p->expires= row_vals[expires_col].val.int_val;
			p->desired_expires= row_vals[desired_expires_col].val.int_val;
			p->flag|=	row_vals[flag_col].val.int_val;

			memset(&p->etag, 0, sizeof(str));
			if(etag.s && etag.len)
			{
				/* alloc separately */
				p->etag.s= (char*)shm_malloc(etag.len* sizeof(char));
				if(p->etag.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}
				memcpy(p->etag.s, etag.s, etag.len);
				p->etag.len= etag.len;
			}

			print_ua_pres(p);

			hash_code= core_hash(p->pres_uri, p->watcher_uri, HASH_SIZE);
			lock_get(&HashT->p_records[hash_code].lock);
			insert_htable(p, hash_code);
			lock_release(&HashT->p_records[hash_code].lock);
		}

	} while((db_fetch_next(&pua_dbf, pua_fetch_rows, pua_db, &res)==1)
			&& (RES_ROW_N(res)>0));

	pua_dbf.free_result(pua_db, res);
	res = NULL;

	if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("while deleting information from db\n");
		goto error;
	}

	return 0;

error:
	if(res)
		pua_dbf.free_result(pua_db, res);

	if(p)
		shm_free(p);
	return -1;
}
コード例 #3
0
ファイル: db_checks.c プロジェクト: KISSMonX/opensips
/**
 * 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;
}
コード例 #4
0
ファイル: ul_db_handle.c プロジェクト: TheGrandWazoo/kamailio
int load_data(db_func_t * dbf, db1_con_t * dbh, ul_db_handle_t * handle, int id){
	db1_res_t *res;
	db_row_t *row;
	db_key_t cols[7];
	db_key_t keys[2];
	db_val_t key_vals[2];
	db_op_t op[2];
	db_key_t order;
	int i, ret = 0;

	if(!dbf || !dbh || !handle){
		LM_ERR("NULL-Pointer in Parameter\n");
		return -1;
	}

	memset(handle, 0, sizeof(ul_db_handle_t));
	
	cols[0] = &num_col;
	cols[1] = &url_col;
	cols[2] = &status_col;
	cols[3] = &failover_time_col;
	cols[4] = &spare_col;
	cols[5] = &error_col;
	cols[6] = &risk_group_col;
	
	order = &num_col;

	keys[0] = &id_col;
	op[0] = OP_EQ;
	key_vals[0].type = DB1_INT;
	key_vals[0].nul = 0;
	key_vals[0].val.int_val = id;
	
	if(dbf->use_table(dbh, &reg_table) < 0){
		LM_ERR("could't use table.\n");
		return -1;
	}
	if(dbf->query(dbh, keys, op, key_vals, cols, 1, 7, order, &res) < 0){
		LM_ERR("error while doing db query.\n");
		return -1;
	}
	if(RES_ROW_N(res) < DB_NUM) {
		LM_ERR("keys have too few location databases\n");
		ret = -1;
		goto ret;
	}

	handle->id = id;
	
	for(i=0; i<DB_NUM; i++) {
		row = RES_ROWS(res) + i;
		handle->db[i].no = (int)VAL_INT(ROW_VALUES(row));
		if(VAL_NULL(ROW_VALUES(row) + 1)){
			LM_ERR("Weird: Empty database URL\n");
			ret = -1;
			goto ret;
		}
		if(strlen((char *)VAL_STRING(ROW_VALUES(row) + 1)) >= (UL_DB_URL_LEN - 1)){
			LM_ERR("weird: very large URL (%d Bytes)\n",
					(int)(strlen((char *)VAL_STRING(ROW_VALUES(row) + 1)) + 1));
			ret = -1;
			goto ret;
		}
		strcpy(handle->db[i].url.s, (char *)VAL_STRING(ROW_VALUES(row) + 1));
		handle->db[i].url.len = strlen(handle->db[i].url.s);
		handle->db[i].status = (int)VAL_INT(ROW_VALUES(row) + 2);
		handle->db[i].failover_time = VAL_TIME (ROW_VALUES(row) + 3);
		handle->db[i].spare = VAL_INT (ROW_VALUES(row) + 4);
		handle->db[i].errors = VAL_INT (ROW_VALUES(row) + 5);
		handle->db[i].rg = VAL_INT (ROW_VALUES(row) + 6);
	}
ret:
	dbf->free_result(dbh, res);
	return ret;
}
コード例 #5
0
ファイル: udomain.c プロジェクト: 4N7HR4X/kamailio
/*!
 * \brief Loads from DB all contacts for an AOR
 * \param _c database connection
 * \param _d domain
 * \param _aor address of record
 * \return pointer to the record on success, 0 on errors or if nothing is found
 */
urecord_t* db_load_urecord(udomain_t* _d, str *_aor)
{
	ucontact_info_t *ci;
	db_key_t columns[16];
	db_key_t keys[2];
	db_key_t order;
	db_val_t vals[2];
	db1_res_t* res = NULL;
	str contact;
	char *domain;
	int i;

	urecord_t* r;
	ucontact_t* c;

	keys[0] = &user_col;
	vals[0].type = DB1_STR;
	vals[0].nul = 0;
	if (use_domain) {
		keys[1] = &domain_col;
		vals[1].type = DB1_STR;
		vals[1].nul = 0;
		domain = memchr(_aor->s, '@', _aor->len);
		vals[0].val.str_val.s   = _aor->s;
		if (domain==0) {
			vals[0].val.str_val.len = 0;
			vals[1].val.str_val = *_aor;
		} else {
			vals[0].val.str_val.len = domain - _aor->s;
			vals[1].val.str_val.s   = domain+1;
			vals[1].val.str_val.len = _aor->s + _aor->len - domain - 1;
		}
	} else {
		vals[0].val.str_val = *_aor;
	}

	columns[0] = &contact_col;
	columns[1] = &expires_col;
	columns[2] = &q_col;
	columns[3] = &callid_col;
	columns[4] = &cseq_col;
	columns[5] = &flags_col;
	columns[6] = &cflags_col;
	columns[7] = &user_agent_col;
	columns[8] = &received_col;
	columns[9] = &path_col;
	columns[10] = &sock_col;
	columns[11] = &methods_col;
	columns[12] = &last_mod_col;
	columns[13] = &ruid_col;
	columns[14] = &instance_col;
	columns[15] = &reg_id_col;

	if (desc_time_order)
		order = &last_mod_col;
	else
		order = &q_col;

	if (ul_db_layer_query(_d,  &vals[0].val.str_val,  &vals[1].val.str_val, keys, 0, vals, columns, (use_domain)?2:1, 16, order,
				&res) < 0) {
		LM_ERR("db_query failed\n");
		return 0;
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("aor %.*s not found in table %.*s\n",_aor->len, _aor->s, _d->name->len, _d->name->s);

		ul_db_layer_free_result(_d, res);
		return 0;
	}

	r = 0;

	for(i = 0; i < RES_ROW_N(res); i++) {
		ci = dbrow2info(  ROW_VALUES(RES_ROWS(res) + i), &contact);
		if (ci==0) {
			LM_ERR("skipping record for %.*s in table %s\n",
					_aor->len, _aor->s, _d->name->s);
			continue;
		}
		
		if ( r==0 )
			get_static_urecord( _d, _aor, &r);

		if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
			LM_ERR("mem_insert failed\n");
			free_urecord(r);
			ul_db_layer_free_result(_d, res);
			return 0;
		}

		/* We have to do this, because insert_ucontact sets state to CS_NEW
		 * and we have the contact in the database already */
		c->state = CS_SYNC;
	}

	ul_db_layer_free_result(_d, res);
	return r;
}
コード例 #6
0
ファイル: authorize.c プロジェクト: Jared-Prime/kamailio
int fetch_credentials(sip_msg_t *msg, str *user, str* domain, str *table)
{
	pv_elem_t *cred;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t *col;
	db1_res_t *res = 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;

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

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

	n = 1;
	VAL_STR(vals) = *user;

	if (domain && domain->len) {
		VAL_STR(vals + 1) = *domain;
		n = 2;
	}

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

	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);
		if(res)
			auth_dbf.free_result(auth_db_handle, res);
		return -1;
	}
	pkg_free(col);
	if (RES_ROW_N(res) == 0) {
		if(res)
			auth_dbf.free_result(auth_db_handle, res);
		LM_DBG("no result for user \'%.*s%s%.*s\' in [%.*s]\n",
				user->len, user->s, (n==2)?"@":"",
				(n==2)?domain->len:0, (n==2)?domain->s:"",
				table->len, table->s);
		return -2;
	}
	for (cred=credentials, n=0; cred; cred=cred->next, n++) {
		if (db_val2pv_spec(msg, &RES_ROWS(res)[0].values[n], cred->spec) != 0) {
			if(res)
				auth_dbf.free_result(auth_db_handle, res);
			LM_ERR("Failed to convert value for column %.*s\n",
					RES_NAMES(res)[n]->len, RES_NAMES(res)[n]->s);
			return -3;
		}
	}
	if(res)
		auth_dbf.free_result(auth_db_handle, res);
	return 0;
}
コード例 #7
0
ファイル: dlist.c プロジェクト: iamroger/voip
static inline int get_all_db_ucontacts(void *buf, int len, unsigned int flags,
								unsigned int part_idx, unsigned int part_max)
{
	static char query_buf[512];
	static str query_str;

	struct socket_info *sock;
	unsigned int dbflags;
	db_res_t* res = NULL;
	db_row_t *row;
	dlist_t *dom;
	char *p, *p1;
	char now_s[25];
	int now_len;
	int port, proto, p_len, p1_len;
	str host;
	int i;
	void *cp;
	int shortage, needed;

	cp = buf;
	shortage = 0;
	/* Reserve space for terminating 0000 */
	len -= sizeof(p_len);

	/* get the current time in DB format */
	now_len = 25;
	if (db_time2str( time(0), now_s, &now_len)!=0) {
		LM_ERR("failed to print now time\n");
		return -1;
	}

	for (dom = root; dom!=NULL ; dom=dom->next) {
		/* build query */
		i = snprintf( query_buf, sizeof(query_buf), "select %.*s, %.*s, %.*s,"
#ifdef ORACLE_USRLOC
			" %.*s, %.*s from %s where %.*s > %.*s and "
			"bitand(%.*s, %d) = %d and mod(id, %u) = %u",
#else
			" %.*s, %.*s from %s where %.*s > %.*s and %.*s & %d = %d and "
			"id %% %u = %u",
#endif
			received_col.len, received_col.s,
			contact_col.len, contact_col.s,
			sock_col.len, sock_col.s,
			cflags_col.len, cflags_col.s,
			path_col.len, path_col.s,
			dom->d->name->s,
			expires_col.len, expires_col.s,
			now_len, now_s,
			cflags_col.len, cflags_col.s,
			flags, flags, part_max, part_idx);
		if ( i>=sizeof(query_buf) ) {
			LM_ERR("DB query too long\n");
			return -1;
		}
		query_str.s = query_buf;
		query_str.len = i;
		if ( ul_dbf.raw_query( ul_dbh, &query_str, &res)<0 ) {
			LM_ERR("raw_query failed\n");
			return -1;
		}
		if( RES_ROW_N(res)==0 ) {
			ul_dbf.free_result(ul_dbh, res);
			continue;
		}

		for(i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;

			/* received */
			p = (char*)VAL_STRING(ROW_VALUES(row));
			if ( VAL_NULL(ROW_VALUES(row)) || p==0 || p[0]==0 ) {
				/* contact */
				p = (char*)VAL_STRING(ROW_VALUES(row)+1);
				if (VAL_NULL(ROW_VALUES(row)+1) || p==0 || p[0]==0) {
					LM_ERR("empty contact -> skipping\n");
					continue;
				}
			}
			p_len = strlen(p);

			/* path */
			p1 = (char*)VAL_STRING(ROW_VALUES(row)+4);
			if (VAL_NULL(ROW_VALUES(row)+4) || p1==0 || p1[0]==0){
				p1 = NULL;
				p1_len = 0;
			} else {
				p1_len = strlen(p1);
			}

			needed = (int)(sizeof(p_len)+p_len+sizeof(sock)+sizeof(dbflags)+
				sizeof(p1_len)+p1_len);
			if (len < needed) {
				shortage += needed ;
				continue;
			}

			/* write received/contact */
			memcpy(cp, &p_len, sizeof(p_len));
			cp = (char*)cp + sizeof(p_len);
			memcpy(cp, p, p_len);
			cp = (char*)cp + p_len;

			/* sock */
			p  = (char*)VAL_STRING(ROW_VALUES(row) + 2);
			if (VAL_NULL(ROW_VALUES(row)+2) || p==0 || p[0]==0){
				sock = 0;
			} else {
				if (parse_phostport( p, strlen(p), &host.s, &host.len,
				&port, &proto)!=0) {
					LM_ERR("bad socket <%s>...ignoring\n", p);
					sock = 0;
				} else {
					sock = grep_sock_info( &host, (unsigned short)port, proto);
					if (sock==0) {
						LM_DBG("non-local socket <%s>...ignoring\n", p);
					}
				}
			}

			/* flags */
			dbflags = VAL_BITMAP(ROW_VALUES(row) + 3);

			/* write sock and flags */
			memcpy(cp, &sock, sizeof(sock));
			cp = (char*)cp + sizeof(sock);
			memcpy(cp, &dbflags, sizeof(dbflags));
			cp = (char*)cp + sizeof(dbflags);

			/* write path */
			memcpy(cp, &p1_len, sizeof(p1_len));
			cp = (char*)cp + sizeof(p1_len);
			memcpy(cp, p1, p1_len);
			cp = (char*)cp + p1_len;

			len -= needed;
		} /* row cycle */

		ul_dbf.free_result(ul_dbh, res);
	} /* domain cycle */

	/* len < 0 is possible, if size of the buffer < sizeof(c->c.len) */
	if (len >= 0)
		memset(cp, 0, sizeof(p_len));

	/* Shouldn't happen */
	if (shortage > 0 && len > shortage) {
		abort();
	}

	shortage -= len;

	return shortage > 0 ? shortage : 0;
}
コード例 #8
0
ファイル: xcap_server.c プロジェクト: adubovikov/kamailio
static int xcaps_put_db(str* user, str *domain, xcap_uri_t *xuri, str *etag,
		str* doc)
{
	db_key_t qcols[9], rcols[2], ucols[5];
	db_val_t qvals[9], uvals[5];
	db1_res_t *res = NULL;
	int ncols = 0, num_ucols = 0, nrows = 0;

	if(xcaps_check_doc_validity(doc)<0)
	{
		LM_ERR("invalid xml doc to insert in database\n");
		goto error;
	}

	qcols[ncols] = &str_username_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *user;
	ncols++;
	
	qcols[ncols] = &str_domain_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *domain;
	ncols++;
	
	qcols[ncols] = &str_doc_type_col;
	qvals[ncols].type = DB1_INT;
	qvals[ncols].nul = 0;
	qvals[ncols].val.int_val= xuri->type;
	ncols++;

	qcols[ncols] = &str_doc_uri_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val= xuri->adoc;
	ncols++;

	rcols[0] = &str_id_col;

	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) 
	{
		LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len,
				xcaps_db_table.s);
		goto error;
	}

	if (xcaps_dbf.query(xcaps_db, qcols, 0, qvals, rcols, ncols, 1, 0, &res) < 0)
	{
		LM_ERR("in sql query\n");
		goto error;
	}

	nrows = RES_ROW_N(res);
	xcaps_dbf.free_result(xcaps_db, res);

	if (nrows == 0)
	{
		qcols[ncols] = &str_doc_col;
		qvals[ncols].type = DB1_BLOB;
		qvals[ncols].nul = 0;
		qvals[ncols].val.str_val= *doc;
		ncols++;

		qcols[ncols] = &str_etag_col;
		qvals[ncols].type = DB1_STR;
		qvals[ncols].nul = 0;
		qvals[ncols].val.str_val= *etag;
		ncols++;

		qcols[ncols] = &str_source_col;
		qvals[ncols].type = DB1_INT;
		qvals[ncols].nul = 0;
		qvals[ncols].val.int_val = 0;
		ncols++;

		qcols[ncols] = &str_port_col;
		qvals[ncols].type = DB1_INT;
		qvals[ncols].nul = 0;
		qvals[ncols].val.int_val = 0;
		ncols++;

		if(xcaps_dbf.insert(xcaps_db, qcols, qvals, ncols)< 0)
		{
			LM_ERR("in sql insert\n");
			goto error;
		}
	}
	else if (nrows == 1)
	{
		ucols[num_ucols] = &str_doc_col;
		uvals[num_ucols].type = DB1_BLOB;
		uvals[num_ucols].nul = 0;
		uvals[num_ucols].val.str_val= *doc;
		num_ucols++;

		ucols[num_ucols] = &str_etag_col;
		uvals[num_ucols].type = DB1_STR;
		uvals[num_ucols].nul = 0;
		uvals[num_ucols].val.str_val= *etag;
		num_ucols++;

		ucols[num_ucols] = &str_source_col;
		uvals[num_ucols].type = DB1_INT;
		uvals[num_ucols].nul = 0;
		uvals[num_ucols].val.int_val = 0;
		num_ucols++;

		ucols[num_ucols] = &str_port_col;
		uvals[num_ucols].type = DB1_INT;
		uvals[num_ucols].nul = 0;
		uvals[num_ucols].val.int_val = 0;
		num_ucols++;

		if (xcaps_dbf.update(xcaps_db, qcols, 0, qvals, ucols, uvals, ncols, num_ucols) < 0)
		{
			LM_ERR("in sql update\n");
			goto error;
		}
	}
	else
	{
		LM_ERR("found %d copies of the same document in XCAP Server\n", nrows);
		goto error;
	}

	return 0;
error:
	return -1;
}
コード例 #9
0
ファイル: xcap_server.c プロジェクト: adubovikov/kamailio
static int xcaps_get_db_doc(str* user, str *domain, xcap_uri_t *xuri, str *doc)
{
	db_key_t qcols[3];
	db_val_t qvals[3];
	int ncols = 0;
	db_key_t rcols[3];
	int nrcols = 0;
	db1_res_t* db_res = NULL;
	str s;

	/* returned cols from table xcap*/
	rcols[nrcols] = &str_doc_col;
	nrcols++;

	/* query cols in xcap table*/
	qcols[ncols] = &str_username_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *user;
	ncols++;

	qcols[ncols] = &str_domain_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *domain;
	ncols++;

	qcols[ncols] = &str_doc_uri_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val= xuri->adoc;
	ncols++;

	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) 
	{
		LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len,
				xcaps_db_table.s);
		goto error;
	}

	if(xcaps_dbf.query(xcaps_db, qcols, NULL, qvals, rcols,
				ncols, nrcols, NULL, &db_res)< 0)
	{
		LM_ERR("in sql query\n");
		goto error;
	}
	if (RES_ROW_N(db_res) <= 0)
	{
		LM_DBG("no document\n");
		goto notfound;
	}

	/* doc */
	switch(RES_ROWS(db_res)[0].values[0].type)
	{
		case DB1_STRING:
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.string_val;
			s.len=strlen(s.s);
		break;
		case DB1_STR:
			s.len=RES_ROWS(db_res)[0].values[0].val.str_val.len;
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.str_val.s;
		break;
		case DB1_BLOB:
			s.len=RES_ROWS(db_res)[0].values[0].val.blob_val.len;
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s;
		break;
		default:
			s.len=0;
			s.s=NULL;
	}
	if(s.len==0)
	{
		LM_ERR("no xcap doc in db record\n");
		goto error;
	}
	if(s.len>xcaps_buf.len-1)
	{
		LM_ERR("xcap doc buffer overflow\n");
		goto error;
	}
	doc->len = s.len;
	doc->s = xcaps_buf.s;
	memcpy(doc->s, s.s, s.len);
	doc->s[doc->len] = '\0';

	if(xcaps_check_doc_validity(doc)<0)
	{
		LM_ERR("invalid xml doc retrieved from database\n");
		goto error;
	}

	xcaps_dbf.free_result(xcaps_db, db_res);
	return 0;

notfound:
	xcaps_dbf.free_result(xcaps_db, db_res);
	return 1;

error:
	if(db_res!=NULL)
		xcaps_dbf.free_result(xcaps_db, db_res);
	return -1;
}
コード例 #10
0
ファイル: udomain.c プロジェクト: AlessioCasco/kamailio
/*!
 * \brief Load all records from a udomain
 *
 * Load all records from a udomain, useful to populate the
 * memory cache on startup.
 * \param _c database connection
 * \param _d loaded domain
 * \return 0 on success, -1 on failure
 */
int preload_udomain(db1_con_t* _c, udomain_t* _d)
{
	pcontact_info_t *ci;
	db_row_t *row;
	db_key_t columns[18];
	db1_res_t* res = NULL;
	str aor, contact;
	int i, n;

	pcontact_t* c;

	LM_DBG("pre-loading domain from DB\n");

	columns[0] = &domain_col;
	columns[1] = &aor_col;
	columns[2] = &contact_col;
	columns[3] = &received_col;
	columns[4] = &received_port_col;
	columns[5] = &received_proto_col;
	columns[6] = &rx_session_id_col;
	columns[7] = &reg_state_col;
	columns[8] = &expires_col;
	columns[9] = &socket_col;
	columns[10] = &service_routes_col;
	columns[11] = &public_ids_col;
	columns[12] = &path_col;

	if (ul_dbf.use_table(_c, _d->name) < 0) {
		LM_ERR("sql use_table failed\n");
		return -1;
	}

#ifdef EXTRA_DEBUG
	LM_NOTICE("load start time [%d]\n", (int)time(NULL));
#endif

	if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
		if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 13, 0, 0) < 0) {
			LM_ERR("db_query (1) failed\n");
			return -1;
		}
		if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if (ul_dbf.query(_c, 0, 0, 0, columns, 0, 13, 0, &res) < 0) {
			LM_ERR("db_query failed\n");
			return -1;
		}
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("table is empty\n");
		ul_dbf.free_result(_c, res);
		return 0;
	}

	LM_DBG("%d rows returned in preload\n", RES_ROW_N(res));

	n = 0;
	do {
		LM_DBG("loading records - cycle [%d]\n", ++n);
		for(i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;

			aor.s = (char*) VAL_STRING(ROW_VALUES(row) + 1);
			if (VAL_NULL(ROW_VALUES(row) + 1) || aor.s == 0 || aor.s[0] == 0) {
				LM_CRIT("empty aor record in table %s...skipping\n", _d->name->s);
				continue;
			}
			aor.len = strlen(aor.s);

			ci = dbrow2info( ROW_VALUES(row)+1, &contact);
			if (ci==0) {
				LM_ERR("usrloc record for %.*s in table %s\n",
						aor.len, aor.s, _d->name->s);
				continue;
			}
			lock_udomain(_d, &aor, &ci->received_host, ci->received_port);

			if ( (mem_insert_pcontact(_d, &aor, ci, &c)) != 0) {
				LM_ERR("inserting contact failed\n");
				unlock_udomain(_d, &aor, &ci->received_host, ci->received_port);
				goto error1;
			}
			unlock_udomain(_d, &aor, &ci->received_host, ci->received_port);
		}

		if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
			if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
				LM_ERR("fetching rows (1) failed\n");
				ul_dbf.free_result(_c, res);
				return -1;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	ul_dbf.free_result(_c, res);

#ifdef EXTRA_DEBUG
	LM_NOTICE("load end time [%d]\n", (int)time(NULL));
#endif

	return 0;
error1:
	free_pcontact(c);

	ul_dbf.free_result(_c, res);
	return -1;
}
コード例 #11
0
ファイル: dp_db.c プロジェクト: 4N7HR4X/kamailio
/*load rules from DB*/
int dp_load_db(void)
{
	int i, nr_rows;
	db1_res_t * res = 0;
	db_val_t * values;
	db_row_t * rows;
	db_key_t query_cols[DP_TABLE_COL_NO] = {
		&dpid_column,	&pr_column,
		&match_op_column,	&match_exp_column,	&match_len_column,
		&subst_exp_column,	&repl_exp_column,	&attrs_column };

	db_key_t order = &pr_column;

	dpl_node_t *rule;

	LM_DBG("init\n");
	if( (*crt_idx) != (*next_idx)){
		LM_WARN("a load command already generated, aborting reload...\n");
		return 0;
	}

	if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){
		LM_ERR("error in use_table %.*s\n", dp_table_name.len, dp_table_name.s);
		return -1;
	}

	if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, 0) < 0){
			LM_ERR("failed to query database!\n");
			return -1;
		}
		if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
			LM_ERR("failed to fetch\n");
			if (res)
				dp_dbf.free_result(dp_db_handle, res);
			return -1;
		}
	} else {
		/*select the whole table and all the columns*/
		if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, 
					DP_TABLE_COL_NO, order, &res) < 0){
			LM_ERR("failed to query database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	*next_idx = ((*crt_idx) == 0)? 1:0;
	destroy_hash(*next_idx);

	if(nr_rows == 0){
		LM_WARN("no data in the db\n");
		goto end;
	}

	do {
		for(i=0; i<RES_ROW_N(res); i++){
			rows 	= RES_ROWS(res);

			values = ROW_VALUES(rows+i);

			if((rule = build_rule(values)) ==0 )
				goto err2;

			if(add_rule2hash(rule , *next_idx) != 0)
				goto err2;

		}
		if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) {
			if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) {
				LM_ERR("failure while fetching!\n");
				if (res)
					dp_dbf.free_result(dp_db_handle, res);
				return -1;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(res)>0);


end:
	/*update data*/
	*crt_idx = *next_idx;
	list_hash(*crt_idx);
	dp_dbf.free_result(dp_db_handle, res);
	return 0;

err2:
	if(rule)	destroy_rule(rule);
	destroy_hash(*next_idx);
	dp_dbf.free_result(dp_db_handle, res);
	*next_idx = *crt_idx; 
	return -1;
}
コード例 #12
0
ファイル: km_dbase.c プロジェクト: mehulsbhatt/sip-router
/*!
 * \brief Gets a partial result set, fetch rows from a result
 *
 * Gets a partial result set, fetch a number of rows from a database result.
 * This function initialize the given result structure on the first run, and
 * fetches the nrows number of rows. On subsequenting runs, it uses the
 * existing result and fetches more rows, until it reaches the end of the
 * result set. Because of this the result needs to be null in the first
 * invocation of the function. If the number of wanted rows is zero, the
 * function returns anything with a result of zero.
 * \param _con database connection
 * \param _res result set
 * \param nrows number of fetches rows
 * \return 0 on success, negative on failure
 */
int db_postgres_fetch_result(const db1_con_t* _con, db1_res_t** _res, const int nrows)
{
	int rows;
	PGresult *res = NULL;
	ExecStatusType pqresult;

	if (!_con || !_res || nrows < 0) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	/* exit if the fetch count is zero */
	if (nrows == 0) {
		if (*_res)
			db_free_result(*_res);

		*_res = 0;
		return 0;
	}

	if (*_res == NULL) {
		/* Allocate a new result structure */
		*_res = db_new_result();

		/* Get the result of the previous query */
		while (1) {
			if ((res = PQgetResult(CON_CONNECTION(_con)))) {
				CON_RESULT(_con) = res;
			} else {
				break;
			}
		}
		pqresult = PQresultStatus(CON_RESULT(_con));
		LM_DBG("%p PQresultStatus(%s) PQgetResult(%p)\n", _con,
			PQresStatus(pqresult), CON_RESULT(_con));

		switch(pqresult) {
			case PGRES_COMMAND_OK:
				/* Successful completion of a command returning no data
				 * (such as INSERT or UPDATE). */
				return 0;

			case PGRES_TUPLES_OK:
				/* Successful completion of a command returning data
				 * (such as a SELECT or SHOW). */
				if (db_postgres_get_columns(_con, *_res) < 0) {
					LM_ERR("failed to get column names\n");
					return -2;
				}
				break;

			case PGRES_FATAL_ERROR:
				LM_ERR("%p - invalid query, execution aborted\n", _con);
				LM_ERR("%p - PQresultStatus(%s)\n", _con,
						PQresStatus(pqresult));
				LM_ERR("%p: %s\n", _con,
						PQresultErrorMessage(CON_RESULT(_con)));
				if (*_res)
					db_free_result(*_res);
				*_res = 0;
				return -3;

			case PGRES_EMPTY_QUERY:
			/* notice or warning */
			case PGRES_NONFATAL_ERROR:
			/* status for COPY command, not used */
			case PGRES_COPY_OUT:
			case PGRES_COPY_IN:
			/* unexpected response */
			case PGRES_BAD_RESPONSE:
			default:
				LM_ERR("%p - probable invalid query\n", _con);
				LM_ERR("%p - PQresultStatus(%s)\n", _con, PQresStatus(pqresult));
				LM_ERR("%p: %s\n", _con, PQresultErrorMessage(CON_RESULT(_con)));
				if (*_res)
					db_free_result(*_res);
				*_res = 0;
				return -4;
		}

	} else {
		if(RES_ROWS(*_res) != NULL) {
			db_free_rows(*_res);
		}
		RES_ROWS(*_res) = 0;
		RES_ROW_N(*_res) = 0;
	}

	/* Get the number of rows (tuples) in the query result. */
	RES_NUM_ROWS(*_res) = PQntuples(CON_RESULT(_con));

	/* determine the number of rows remaining to be processed */
	rows = RES_NUM_ROWS(*_res) - RES_LAST_ROW(*_res);

	/* If there aren't any more rows left to process, exit */
	if (rows <= 0)
		return 0;

	/* if the fetch count is less than the remaining rows to process                 */
	/* set the number of rows to process (during this call) equal to the fetch count */
	if (nrows < rows)
		rows = nrows;

	RES_ROW_N(*_res) = rows;

	LM_DBG("converting row %d of %d count %d\n", RES_LAST_ROW(*_res),
			RES_NUM_ROWS(*_res), RES_ROW_N(*_res));

	if (db_postgres_convert_rows(_con, *_res) < 0) {
		LM_ERR("failed to convert rows\n");
		if (*_res)
			db_free_result(*_res);

		*_res = 0;
		return -3;
	}

	/* update the total number of rows processed */
	RES_LAST_ROW(*_res) += rows;
	return 0;
}
コード例 #13
0
ファイル: sca_db_handler.c プロジェクト: GeorgeShaw/opensips
static int load_sca_info_from_db(void)
{
	db_res_t * res = NULL;
	db_val_t * values;
	db_row_t * rows;
	int i, j, nr_rows;
	unsigned int valid_record;
	unsigned int n_result_cols = 0;
	unsigned int shared_line_col, watchers_col;
	unsigned int app_shared_entity_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_state_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_call_info_appearance_uri_col[MAX_APPEARANCE_INDEX];
	unsigned int app_b2bl_key_col[MAX_APPEARANCE_INDEX];
	db_key_t q_cols[SCA_TABLE_TOTAL_COL_NO];

	str shared_line, watchers_csv;
	//str_lst_t *watchers;
	//unsigned int size, watcher_size, watchers_no;
	//unsigned int size;
	unsigned int hash_index;
	//char *p;
	b2b_sca_record_t *record;
	b2b_sca_call_t *call;
	unsigned int shared_entity, appearance_index, call_state;
	str call_info_uri, call_info_apperance_uri, b2bl_key;
	b2bl_cb_ctx_t *cb_params;

	if(use_sca_table()) return -1;

	q_cols[shared_line_col = n_result_cols++] = &shared_line_column;
	q_cols[watchers_col = n_result_cols++] = &watchers_column;

	for (i=0; i<MAX_APPEARANCE_INDEX; i++) {
		q_cols[app_shared_entity_col[i]	= n_result_cols++] = &app_shared_entity_column[i];
		q_cols[app_call_state_col[i] = n_result_cols++] = &app_call_state_column[i];
		q_cols[app_call_info_uri_col[i] = n_result_cols++] = &app_call_info_uri_column[i];
		q_cols[app_call_info_appearance_uri_col[i] = n_result_cols++] =
						&app_call_info_appearance_uri_column[i];
		q_cols[app_b2bl_key_col[i] = n_result_cols++] = &app_b2bl_key_column[i];
	}

	/* select the whole tabel and all the columns */
	if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, 0) < 0) {
			LM_ERR("Error while querying (fetch) database\n");
			return -1;
		}
		if(sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0){
			LM_ERR("fetching rows failed\n");
			return -1;
		}
	} else {
		if(sca_dbf.query(sca_db_handle, 0, 0, 0, q_cols, 0,
				SCA_TABLE_TOTAL_COL_NO, 0, &res) < 0) {
			LM_ERR("Error while querying database\n");
			return -1;
		}
	}

	nr_rows = RES_ROW_N(res);

	do {
		LM_DBG("loading [%i] records from db\n", nr_rows);
		rows = RES_ROWS(res);
		/* for every row/record */
		for(i=0; i<nr_rows; i++){
			values = ROW_VALUES(rows + i);
			if (VAL_NULL(values+shared_line_col) || VAL_NULL(values+watchers_col)) {
				LM_ERR("columns [%.*s] or/and [%.*s] cannot be null -> skipping\n",
					shared_line_column.len, shared_line_column.s,
					watchers_column.len, watchers_column.s);
				continue;
			}
			shared_line.s = (char*)values[shared_line_col].val.string_val;
			shared_line.len = strlen(shared_line.s);

			watchers_csv.s = (char*)values[watchers_col].val.string_val;
			watchers_csv.len = strlen(watchers_csv.s);

			record = restore_record(&shared_line, &watchers_csv);
			if (record == NULL)
				goto error;
			hash_index = core_hash(&shared_line, NULL, b2b_sca_hsize);

			j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if(	VAL_NULL(values + app_shared_entity_col[j]) ||
					VAL_NULL(values + app_call_state_col[j]) ||
					VAL_NULL(values + app_call_info_uri_col[j]) ||
					VAL_NULL(values + app_call_info_appearance_uri_col[j]) ||
					VAL_NULL(values + app_b2bl_key_col[j]) ) {
					goto cont;
				}
				appearance_index = j + 1;
				/* 1 - get shared_entity */
				shared_entity = values[app_shared_entity_col[j]].val.int_val;
				if (shared_entity!=0 && shared_entity!=1) {
					LM_ERR("Unexpected shared_entity [%d] "
						"for shared_line [%.*s]\n",
						shared_entity, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 2 - get call_state */
				call_state = values[app_call_state_col[j]].val.int_val;
				if (call_state == IDLE_STATE) {
					LM_DBG("empty call[%d]\n", appearance_index);
					goto cont;
				}
				if (call_state > MAX_INDEX_STATE) {
					LM_ERR("Unexpected call_state [%d] for shared_line [%.*s]\n",
						call_state, shared_line.len, shared_line.s);
					goto cont;
				}
				/* 3 - get call_info_uri */
				call_info_uri.s =
					(char*)values[app_call_info_uri_col[j]].val.string_val;
				if (call_info_uri.s)
					call_info_uri.len = strlen(call_info_uri.s);
				else {
					LM_ERR("Missing call_info_uri for shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_uri=[%.*s]\n",
					call_info_uri.len, call_info_uri.s);
				/* 4 - get call_info_apperance_uri */
				call_info_apperance_uri.s =
					(char*)
					values[app_call_info_appearance_uri_col[j]].val.string_val;
				if (call_info_apperance_uri.s)
					call_info_apperance_uri.len =
						strlen(call_info_apperance_uri.s);
				else {
					LM_ERR("Missing call_info_apperance_uri for "
						"shared_line [%.*s][%d]\n",
						shared_line.len, shared_line.s, appearance_index);
					goto cont;
				}
				LM_DBG("call_info_apperance_uri=[%.*s]\n",
					call_info_apperance_uri.len, call_info_apperance_uri.s);
				/* 5 - get b2bl_key */
				b2bl_key.s = (char*)values[app_b2bl_key_col[j]].val.string_val;
				if (b2bl_key.s) {
					b2bl_key.len = strlen(b2bl_key.s);
					if (b2bl_key.len > B2BL_MAX_KEY_LEN) {
						LM_ERR("buffer overflow on b2bl_key [%.*s]"
							" for shared_line [%.*s][%d]\n",
							b2bl_key.len, b2bl_key.s,
							shared_line.len, shared_line.s,
							appearance_index);
						goto cont;
					}
					LM_DBG("b2bl_key=[%.*s]\n", b2bl_key.len, b2bl_key.s);
				} else {
					LM_ERR("Missing b2bl_key for shared_line [%.*s][1]\n",
						shared_line.len, shared_line.s);
					goto cont;
				}
				/* restore the call */
				call = restore_call(record, appearance_index,
					shared_entity, call_state,
					&call_info_uri, &call_info_apperance_uri);
				if (call == NULL) {
					goto error;
				}
				/* update record */
				if (0!=b2b_sca_update_call_record_key(call, &b2bl_key)) {
					LM_ERR("Unable to update b2bl_key [%.*s]\n",
						b2bl_key.len, b2bl_key.s);
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
				/* Prepare b2b_logic callback params. */
				cb_params = build_cb_params(hash_index,
							&shared_line, appearance_index);
				if (cb_params == NULL) {
					LM_ERR("Unable to build cb_params\n");
					goto error;
				}
				/* re-register callbacks */
				if(b2bl_api.register_cb(&b2bl_key, &sca_logic_notify, cb_params,
					B2B_RE_INVITE_CB|B2B_CONFIRMED_CB|B2B_DESTROY_CB) != 0){
					LM_ERR("Unable register b2b cb\n");
					shm_free(call);
					call = NULL;
					record->call[appearance_index-1] = NULL;
					goto cont;
				}
cont:
				j++;
			}

			valid_record = j = 0;
			while (j < MAX_APPEARANCE_INDEX) {
				if (record->call[j]) {
					valid_record = 1;
					goto check_valid_record;
				}
				j++;
			}
check_valid_record:
			if (valid_record) {
				b2b_sca_print_record(record);
				insert_record(hash_index, record);
			} else {
				LM_DBG("removing the record from db!\n");
				delete_sca_info_from_db(record);
			}
			LM_DBG("Done\n");
		}

		/* any more data to be fetched ?*/
		if (DB_CAPABILITY(sca_dbf, DB_CAP_FETCH)) {
			if (sca_dbf.fetch_result(sca_db_handle, &res, SCA_FETCH_SIZE)<0) {
				LM_ERR("fetching more rows failed\n");
				goto error;
			}
			nr_rows = RES_ROW_N(res);
		} else {
			nr_rows = 0;
		}
	}while (nr_rows>0);

	sca_dbf.free_result(sca_db_handle, res);
	return 0;
error:
	sca_dbf.free_result(sca_db_handle, res);
	return -1;
}
コード例 #14
0
ファイル: tls_mgm.c プロジェクト: Parantido/opensips
/* loads data from the db */
int load_info(db_func_t *dr_dbf, db_con_t* db_hdl, str *db_table,
	struct tls_domain **serv_dom, struct tls_domain **cli_dom)
{
	int int_vals[4];
	char *str_vals[11];
	int i, n;
	int no_rows = 5;
	int db_cols = 15;

	/* the columns from the db table */
	db_key_t columns[15];
	/* result from a db query */
	db_res_t* res;
	/* a row from the db table */
	db_row_t* row;

	res = 0;

	columns[0] = &id_col;
	columns[1] = &address_col;
	columns[2] = &type_col;
	columns[3] = &method_col;
	columns[4] = &verify_cert_col;
	columns[5] = &require_cert_col;
	columns[6] = &certificate_col;
	columns[7] = &pk_col;
	columns[8] = &crl_check_col;
	columns[9] = &crl_dir_col;
	columns[10] = &calist_col;
	columns[11] = &cadir_col;
	columns[12] = &cplist_col;
	columns[13] = &dhparams_col;
	columns[14] = &eccurve_col;

	/* checking if the table version is up to date*/
	if (db_check_table_version(dr_dbf, db_hdl, db_table, 1/*version*/) != 0)
		goto error;

	/* table to use*/
	if (dr_dbf->use_table(db_hdl, db_table) < 0) {
		LM_ERR("cannot select table \"%.*s\"\n", db_table->len, db_table->s);
		goto error;
	}

	if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {

		if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, 0) < 0) {
			LM_ERR("DB query failed - retrieve valid connections \n");
			goto error;
		}
		no_rows = estimate_available_rows(10 + 45 + 4 + 45 + 4 + 4 + 45 +
			45 + 4 + 45 + 45 + 45 + 45 + 45 + 45, db_cols);
		if (no_rows == 0) no_rows = 5;
		if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
			LM_ERR("Error fetching rows\n");
			goto error;
		}
	} else {
		if (dr_dbf->query(db_hdl, 0, 0, 0, columns, 0, db_cols, 0, &res) < 0) {
			LM_ERR("DB query failed - retrieve valid connections\n");
			goto error;
		}
	}

	LM_DBG("%d rows found in %.*s\n",
		RES_ROW_N(res), db_table->len, db_table->s);

	n = 0;
	do {
		for (i = 0; i < RES_ROW_N(res); i++) {
			row = RES_ROWS(res) + i;

			check_val(id_col, ROW_VALUES(row), DB_STRING, 1, 1);
			str_vals[STR_VALS_ID_COL] = (char *) VAL_STRING(ROW_VALUES(row));

			check_val(address_col, ROW_VALUES(row) + 1, DB_STRING, 1, 1);
			str_vals[STR_VALS_ADDRESS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 1);

			check_val(type_col, ROW_VALUES(row) + 2, DB_INT, 1, 0);
			int_vals[INT_VALS_TYPE_COL] = VAL_INT(ROW_VALUES(row) + 2);

			check_val(method_col, ROW_VALUES(row) + 3, DB_STRING, 0, 0);
			str_vals[STR_VALS_METHOD_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 3);

			check_val(verify_cert_col, ROW_VALUES(row) + 4, DB_INT, 0, 0);
			int_vals[INT_VALS_VERIFY_CERT_COL] = VAL_INT(ROW_VALUES(row) + 4);

			check_val(require_cert_col, ROW_VALUES(row) + 5, DB_INT, 0, 0);
			int_vals[INT_VALS_REQUIRE_CERT_COL] = VAL_INT(ROW_VALUES(row) + 5);

			check_val(certificate_col, ROW_VALUES(row) + 6, DB_STRING, 0, 0);
			str_vals[STR_VALS_CERTIFICATE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 6);

			check_val(pk_col, ROW_VALUES(row) + 7, DB_STRING, 0, 0);
			str_vals[STR_VALS_PK_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 7);

			check_val(crl_check_col, ROW_VALUES(row) + 8, DB_INT, 0, 0);
			int_vals[INT_VALS_CRL_CHECK_COL] = VAL_INT(ROW_VALUES(row) + 8);

			check_val(crl_dir_col, ROW_VALUES(row) + 9, DB_STRING, 0, 0);
			str_vals[STR_VALS_CRL_DIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 9);

			check_val(calist_col, ROW_VALUES(row) + 10, DB_STRING, 0, 0);
			str_vals[STR_VALS_CALIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 10);

			check_val(cadir_col, ROW_VALUES(row) + 11, DB_STRING, 0, 0);
			str_vals[STR_VALS_CADIR_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 11);

			check_val(cplist_col, ROW_VALUES(row) + 12, DB_STRING, 0, 0);
			str_vals[STR_VALS_CPLIST_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 12);

			check_val(dhparams_col, ROW_VALUES(row) + 13, DB_STRING, 0, 0);
			str_vals[STR_VALS_DHPARAMS_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 13);

			check_val(eccurve_col, ROW_VALUES(row) + 14, DB_STRING, 0, 0);
			str_vals[STR_VALS_ECCURVE_COL] = (char *) VAL_STRING(ROW_VALUES(row) + 14);

			tlsp_db_add_domain(str_vals, int_vals, serv_dom, cli_dom);
			
			n++;
		}

		if (DB_CAPABILITY(*dr_dbf, DB_CAP_FETCH)) {
			if (dr_dbf->fetch_result(db_hdl, &res, no_rows) < 0) {
				LM_ERR("fetching rows\n");
				goto error;
			}
		} else {
			break;
		}

	} while (RES_ROW_N(res) > 0);

	LM_DBG("%d records found in %.*s\n",
		n, db_table->len, db_table->s);

	dr_dbf->free_result(db_hdl, res);
	res = 0;

	return 0;
error:
	LM_ERR("database");
	return -1;
}
コード例 #15
0
ファイル: pua.c プロジェクト: abh-gitcs1989/opensips
static int db_restore(void)
{
	ua_pres_t* p= NULL;
	db_key_t result_cols[20];
	db_res_t *res= NULL;
	db_row_t *row = NULL;
	db_val_t *row_vals= NULL;
	str pres_uri, pres_id, to_uri;
	str etag, tuple_id;
	str watcher_uri, call_id;
	str to_tag, from_tag, remote_contact;
	str record_route, contact, extra_headers;
	int size= 0, i;
	int n_result_cols= 0;
	int puri_col,touri_col,pid_col,expires_col,flag_col,etag_col, desired_expires_col;
	int watcher_col,callid_col,totag_col,fromtag_col,cseq_col,remote_contact_col;
	int event_col,contact_col,tuple_col,record_route_col, extra_headers_col;
	int version_col;
	int no_rows = 10;

	result_cols[puri_col=n_result_cols++]	= &str_pres_uri_col;
	result_cols[touri_col=n_result_cols++]	= &str_to_uri_col;
	result_cols[pid_col=n_result_cols++]	= &str_pres_id_col;
	result_cols[expires_col=n_result_cols++]= &str_expires_col;
	result_cols[flag_col=n_result_cols++]	= &str_flag_col;
	result_cols[etag_col=n_result_cols++]	= &str_etag_col;
	result_cols[tuple_col=n_result_cols++]	= &str_tuple_id_col;
	result_cols[watcher_col=n_result_cols++]= &str_watcher_uri_col;
	result_cols[callid_col=n_result_cols++] = &str_call_id_col;
	result_cols[totag_col=n_result_cols++]	= &str_to_tag_col;
	result_cols[fromtag_col=n_result_cols++]= &str_from_tag_col;
	result_cols[cseq_col= n_result_cols++]	= &str_cseq_col;
	result_cols[event_col= n_result_cols++]	= &str_event_col;
	result_cols[record_route_col= n_result_cols++]	= &str_record_route_col;
	result_cols[contact_col= n_result_cols++]	= &str_contact_col;
	result_cols[remote_contact_col= n_result_cols++]	= &str_remote_contact_col;
	result_cols[extra_headers_col= n_result_cols++]	= &str_extra_headers_col;
	result_cols[desired_expires_col= n_result_cols++]	= &str_desired_expires_col;
	result_cols[version_col= n_result_cols++]	= &str_version_col;

	if(!pua_db)
	{
		LM_ERR("null database connection\n");
		return -1;
	}

	if(pua_dbf.use_table(pua_db, &db_table)< 0)
	{
		LM_ERR("in use table\n");
		return -1;
	}

	if (DB_CAPABILITY(pua_dbf, DB_CAP_FETCH)) {
		if(pua_dbf.query(pua_db,0, 0, 0, result_cols,0, n_result_cols, 0,0)< 0)
		{
			LM_ERR("while querying table\n");
			return -1;
		}
		no_rows = estimate_available_rows( 128+128+8+8+4+32+64+64+128+
			128+64+64+16+64, n_result_cols);
		if (no_rows==0) no_rows = 10;

		if(pua_dbf.fetch_result(pua_db, &res, no_rows)<0)
		{
			LM_ERR("Error fetching rows\n");
			return -1;
		}
	} else {
		if(pua_dbf.query(pua_db,0, 0, 0,result_cols,0,n_result_cols,0,&res)< 0)
		{
			LM_ERR("while querrying table\n");
			if(res)
			{
				pua_dbf.free_result(pua_db, res);
				res = NULL;
			}
			return -1;
		}
	}

	if(res== NULL)
		return -1;

	if(res->n<=0)
	{
		LM_INFO("the query returned no result\n");
		pua_dbf.free_result(pua_db, res);
		res = NULL;
		return 0;
	}

	LM_DBG("found %d db entries\n", res->n);

	do {
		for(i =0 ; i< res->n ; i++)
		{
			row = &res->rows[i];
			row_vals = ROW_VALUES(row);
			if(row_vals[expires_col].val.int_val < time(NULL))
				continue;

			pres_uri.s= (char*)row_vals[puri_col].val.string_val;
			pres_uri.len = strlen(pres_uri.s);

			LM_DBG("pres_uri= %.*s\n", pres_uri.len, pres_uri.s);

			memset(&etag,			 0, sizeof(str));
			memset(&tuple_id,		 0, sizeof(str));
			memset(&watcher_uri,	 0, sizeof(str));
			memset(&to_uri,          0, sizeof(str));
			memset(&call_id,		 0, sizeof(str));
			memset(&to_tag,			 0, sizeof(str));
			memset(&from_tag,		 0, sizeof(str));
			memset(&record_route,	 0, sizeof(str));
			memset(&pres_id,         0, sizeof(str));
			memset(&contact,         0, sizeof(str));
			memset(&remote_contact,  0, sizeof(str));
			memset(&extra_headers,   0, sizeof(str));

			pres_id.s= (char*)row_vals[pid_col].val.string_val;
			if(pres_id.s)
				pres_id.len = strlen(pres_id.s);

			if(row_vals[etag_col].val.string_val)
			{
				etag.s= (char*)row_vals[etag_col].val.string_val;
				etag.len = strlen(etag.s);

				tuple_id.s= (char*)row_vals[tuple_col].val.string_val;
				tuple_id.len = strlen(tuple_id.s);
			}

			if(row_vals[watcher_col].val.string_val)
			{
				watcher_uri.s= (char*)row_vals[watcher_col].val.string_val;
				watcher_uri.len = strlen(watcher_uri.s);

				to_uri.s= (char*)row_vals[touri_col].val.string_val;
				if(to_uri.s == NULL)
					to_uri = pres_uri;
				else
					to_uri.len = strlen(to_uri.s);
				LM_DBG("to_uri= %.*s\n", to_uri.len, to_uri.s);
				call_id.s= (char*)row_vals[callid_col].val.string_val;
				call_id.len = strlen(call_id.s);

				to_tag.s= (char*)row_vals[totag_col].val.string_val;
				to_tag.len = strlen(to_tag.s);

				from_tag.s= (char*)row_vals[fromtag_col].val.string_val;
				from_tag.len = strlen(from_tag.s);

				if(row_vals[record_route_col].val.string_val)
				{
					record_route.s= (char*)
						row_vals[record_route_col].val.string_val;
					record_route.len= strlen(record_route.s);
				}

				contact.s= (char*)row_vals[contact_col].val.string_val;
				contact.len = strlen(contact.s);

				remote_contact.s=
					(char*)row_vals[remote_contact_col].val.string_val;
				if(remote_contact.s)
					remote_contact.len = strlen(remote_contact.s);
			}
			extra_headers.s= (char*)row_vals[extra_headers_col].val.string_val;
			if(extra_headers.s)
				extra_headers.len= strlen(extra_headers.s);
			else
				extra_headers.len= 0;

			size= sizeof(ua_pres_t)+ sizeof(str)+ (pres_uri.len+ pres_id.len+
						tuple_id.len)* sizeof(char);

			if(watcher_uri.s)
				size+= sizeof(str)+ to_uri.len + watcher_uri.len+ call_id.len+ to_tag.len+
					from_tag.len+ record_route.len+ contact.len;

			p= (ua_pres_t*)shm_malloc(size);
			if(p== NULL)
			{
				LM_ERR("no more shared memmory");
				goto error;
			}
			memset(p, 0, size);
			size= sizeof(ua_pres_t);

			p->pres_uri= (str*)((char*)p+ size);
			size+= sizeof(str);
			p->pres_uri->s= (char*)p + size;
			memcpy(p->pres_uri->s, pres_uri.s, pres_uri.len);
			p->pres_uri->len= pres_uri.len;
			size+= pres_uri.len;

			if(pres_id.s)
			{
				CONT_COPY(p, p->id, pres_id);
			}

			if(watcher_uri.s && watcher_uri.len)
			{
				p->watcher_uri= (str*)((char*)p+ size);
				size+= sizeof(str);

				p->watcher_uri->s= (char*)p+ size;
				memcpy(p->watcher_uri->s, watcher_uri.s, watcher_uri.len);
				p->watcher_uri->len= watcher_uri.len;
				size+= watcher_uri.len;

				CONT_COPY(p, p->to_uri, to_uri);
				CONT_COPY(p, p->to_tag, to_tag);
				CONT_COPY(p, p->from_tag, from_tag);
				CONT_COPY(p, p->call_id, call_id);

				if(record_route.s && record_route.len)
				{
					CONT_COPY(p, p->record_route, record_route);
				}
				CONT_COPY(p, p->contact, contact);

				p->cseq= row_vals[cseq_col].val.int_val;

				p->remote_contact.s= (char*)shm_malloc(remote_contact.len);
				if(p->remote_contact.s== NULL)
				{
					LM_ERR("No more shared memory\n");
					goto error;
				}
				memcpy(p->remote_contact.s, remote_contact.s, remote_contact.len);
				p->remote_contact.len= remote_contact.len;

				p->version= row_vals[version_col].val.int_val;
			}

			LM_DBG("size= %d\n", size);
			p->event= row_vals[event_col].val.int_val;
			p->expires= row_vals[expires_col].val.int_val;
			p->desired_expires= row_vals[desired_expires_col].val.int_val;
			p->flag|=	row_vals[flag_col].val.int_val;

			memset(&p->etag, 0, sizeof(str));
			if(etag.s && etag.len)
			{
				/* alloc separately */
				p->etag.s= (char*)shm_malloc(etag.len);
				if(p->etag.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}
				memcpy(p->etag.s, etag.s, etag.len);
				p->etag.len= etag.len;
			}

			memset(&p->extra_headers, 0, sizeof(str));
			if(extra_headers.s && extra_headers.len)
			{
				/* alloc separately */
				p->extra_headers.s= (char*)shm_malloc(extra_headers.len);
				if(p->extra_headers.s==  NULL)
				{
					LM_ERR("no more share memory\n");
					goto error;
				}
				memcpy(p->extra_headers.s, extra_headers.s, extra_headers.len);
				p->extra_headers.len= extra_headers.len;
			}

			print_ua_pres(p);
			insert_htable(p);
		} /* end for(all rows)*/

		if (DB_CAPABILITY(pua_dbf, DB_CAP_FETCH)) {
			if(pua_dbf.fetch_result(pua_db, &res, no_rows)<0) {
				LM_ERR( "fetching rows (1)\n");
				goto error;
			}
		} else {
			break;
		}
	} while(RES_ROW_N(res)>0);

	pua_dbf.free_result(pua_db, res);
	res = NULL;

	if(pua_dbf.delete(pua_db, 0, 0 , 0, 0) < 0)
	{
		LM_ERR("while deleting information from db\n");
		goto error;
	}

	return 0;

error:
	if(res)
		pua_dbf.free_result(pua_db, res);

	if(p)
	{
		if(p->remote_contact.s) shm_free(p->remote_contact.s);
		if(p->extra_headers.s) shm_free(p->extra_headers.s);
		if(p->etag.s) shm_free(p->etag.s);
		shm_free(p);
	}
	return -1;
}
コード例 #16
0
ファイル: xcap_server.c プロジェクト: adubovikov/kamailio
/**
 * get the etag from database record for (user@domain, xuri)
 * - return: -1 error; 0 - found; 1 - not found
 *
 */
static int xcaps_get_db_etag(str* user, str *domain, xcap_uri_t *xuri, str *etag)
{
	db_key_t qcols[3];
	db_val_t qvals[3];
	int ncols = 0;
	db_key_t rcols[3];
	int nrcols = 0;
	db1_res_t* db_res = NULL;
	str s;

	/* returned cols from xcap table*/
	rcols[nrcols] = &str_etag_col;
	nrcols++;

	/* query cols in xcap table*/
	qcols[ncols] = &str_username_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *user;
	ncols++;

	qcols[ncols] = &str_domain_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val = *domain;
	ncols++;

	qcols[ncols] = &str_doc_uri_col;
	qvals[ncols].type = DB1_STR;
	qvals[ncols].nul = 0;
	qvals[ncols].val.str_val= xuri->adoc;
	ncols++;

	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0) 
	{
		LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len,
				xcaps_db_table.s);
		goto error;
	}

	if(xcaps_dbf.query(xcaps_db, qcols, NULL, qvals, rcols,
				ncols, nrcols, NULL, &db_res)< 0)
	{
		LM_ERR("in sql query\n");
		goto error;
	}
	if (RES_ROW_N(db_res) <= 0)
	{
		LM_DBG("no document\n");
		goto notfound;
	}
	/* etag */
	switch(RES_ROWS(db_res)[0].values[0].type)
	{
		case DB1_STRING:
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.string_val;
			s.len=strlen(s.s);
		break;
		case DB1_STR:
			s.len=RES_ROWS(db_res)[0].values[0].val.str_val.len;
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.str_val.s;
		break;
		case DB1_BLOB:
			s.len=RES_ROWS(db_res)[0].values[0].val.blob_val.len;
			s.s=(char*)RES_ROWS(db_res)[0].values[0].val.blob_val.s;
		break;
		default:
			s.len=0;
			s.s=NULL;
	}
	if(s.len==0)
	{
		LM_ERR("no etag in db record\n");
		goto error;
	}
	etag->len = snprintf(xcaps_hdr_buf, XCAPS_HDR_SIZE,
			"ETag: \"%.*s\"\r\n", s.len, s.s);
	if(etag->len < 0)
	{
		LM_ERR("error printing etag hdr\n ");
		goto error;
	}
	if(etag->len >= XCAPS_HDR_SIZE)
	{
		LM_ERR("etag buffer overflow\n");
		goto error;
	}

	etag->s = xcaps_hdr_buf;
	etag->s[etag->len] = '\0';

	xcaps_dbf.free_result(xcaps_db, db_res);
	return 0;

notfound:
	xcaps_dbf.free_result(xcaps_db, db_res);
	return 1;

error:
	if(db_res!=NULL)
		xcaps_dbf.free_result(xcaps_db, db_res);
	return -1;
}
コード例 #17
0
ファイル: authorize.c プロジェクト: Jared-Prime/kamailio
static inline int get_ha1(struct username* _username, str* _domain,
			  const str* _table, char* _ha1, db1_res_t** res)
{
	pv_elem_t *cred;
	db_key_t keys[2];
	db_val_t vals[2];
	db_key_t *col;
	str result;

	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->text;
	}

	VAL_TYPE(vals) = VAL_TYPE(vals + 1) = DB1_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;
	}

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

	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;
}
コード例 #18
0
ファイル: xcap_server.c プロジェクト: adubovikov/kamailio
static int xcaps_get_directory(struct sip_msg *msg, str *user, str *domain, str *directory)
{
	db_key_t qcols[2];
	db_val_t qvals[2], *values;
	db_key_t rcols[3];
	db_row_t *rows;
	db1_res_t* db_res = NULL;
	int n_qcols = 0, n_rcols = 0;
	int i, cur_type = 0, cur_pos = 0;
	int doc_type_col, doc_uri_col, etag_col;
	str auid_string = {0, 0};
	struct hdr_field *hdr = msg->headers;
	str server_name = {0, 0};

	qcols[n_qcols] = &str_username_col;
	qvals[n_qcols].type = DB1_STR;
	qvals[n_qcols].nul = 0;
	qvals[n_qcols].val.str_val = *user;
	n_qcols++;

	qcols[n_qcols] = &str_domain_col;
	qvals[n_qcols].type = DB1_STR;
	qvals[n_qcols].nul = 0;
	qvals[n_qcols].val.str_val = *domain;
	n_qcols++;

	rcols[doc_type_col = n_rcols++] = &str_doc_type_col;
	rcols[doc_uri_col = n_rcols++] = &str_doc_uri_col;
	rcols[etag_col = n_rcols++] = &str_etag_col;

	if (xcaps_dbf.use_table(xcaps_db, &xcaps_db_table) < 0)
	{
		LM_ERR("in use_table-[table]= %.*s\n", xcaps_db_table.len,
				xcaps_db_table.s);
		goto error;
	}

	if (xcaps_dbf.query(xcaps_db, qcols, 0, qvals, rcols, n_qcols,
				n_rcols, &str_doc_type_col, &db_res) < 0)
	{
		LM_ERR("in sql query\n");
		goto error;

	}

	if (db_res == NULL)
		goto error;

	directory->s = xcaps_buf.s;
	directory->len = 0;

	directory->len += snprintf(directory->s + directory->len,
					xcaps_buf.len - directory->len,
			"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
			"<xcap-directory xmlns=\"urn:oma:xml:xdm:xcap-directory\">\r\n");

	rows = RES_ROWS(db_res);
	for (i = 0; i < RES_ROW_N(db_res); i++)
	{
		values = ROW_VALUES(&rows[i]);

		if (cur_type != VAL_INT(&values[doc_type_col]))
		{
			if (cur_type != 0)
			{
				directory->len += snprintf(directory->s + directory->len,
								xcaps_buf.len - directory->len,
			"</folder>\r\n");
			}
			cur_type = VAL_INT(&values[doc_type_col]);

			memset(&auid_string, 0, sizeof(str));
			while(xcaps_auid_list[cur_pos].auid.s != NULL)
			{
				if (xcaps_auid_list[cur_pos].type == cur_type)
				{
					auid_string.s = xcaps_auid_list[cur_pos].auid.s;
					auid_string.len = xcaps_auid_list[cur_pos].auid.len;
					break;
				}
				cur_pos++;
			}

			if (auid_string.s == NULL)
			{
				goto error;
			}

			directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
			"<folder auid=\"%.*s\">\r\n",
							auid_string.len, auid_string.s);
		}

		switch(xcaps_directory_scheme)
		{
		case -1:
			directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
			"<entry uri=\"%s://", msg->rcv.proto == PROTO_TLS ? "https" : "http");
			break;
		case 0:
			directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
			"<entry uri=\"http://");
			break;
		case 1:
			directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
			"<entry uri=\"https://");
			break;
		}

		if (xcaps_directory_hostname.len > 0)
		{
			directory->len += snprintf(directory->s + directory->len,
						xcaps_buf.len - directory->len,
			"%.*s", xcaps_directory_hostname.len, xcaps_directory_hostname.s);
		}
		else
		{
			if (parse_headers(msg, HDR_EOH_F, 0) < 0)
			{
				LM_ERR("error parsing headers\n");
				goto error;
			}

			while (hdr != NULL)
			{
				if (cmp_hdrname_strzn(&hdr->name, "Host", 4) == 0)
				{
					server_name = hdr->body;
					break;
				}
				hdr = hdr->next;
			}

			if (server_name.len > 0)
			{
				directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
							"%.*s", server_name.len, server_name.s);
			}
			else
			{
				server_name.s = pkg_malloc(IP6_MAX_STR_SIZE + 6);
				server_name.len = ip_addr2sbuf(&msg->rcv.dst_ip, server_name.s, IP6_MAX_STR_SIZE);
				directory->len += snprintf(directory->s + directory->len,
							xcaps_buf.len - directory->len,
							"%.*s:%d", server_name.len, server_name.s, msg->rcv.dst_port);
				pkg_free(server_name.s);
				server_name.s = 0;
				server_name.len = 0;
			}
		}

		directory->len += snprintf(directory->s + directory->len,
						xcaps_buf.len - directory->len,
		"%s\" etag=\"%s\"/>\r\n",
					VAL_STRING(&values[doc_uri_col]),
					VAL_STRING(&values[etag_col]));
	}

	if (cur_type != 0)
	{
		directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
		"</folder>\r\n");
	}
	directory->len += snprintf(directory->s + directory->len, xcaps_buf.len - directory->len,
		"</xcap-directory>");

	if (db_res != NULL)
		xcaps_dbf.free_result(xcaps_db, db_res);

	return 0;

error:
	if (db_res != NULL)
		xcaps_dbf.free_result(xcaps_db, db_res);
	return -1;
}
コード例 #19
0
ファイル: rls.c プロジェクト: Jared-Prime/kamailio
int rls_restore_db_subs(void)
{
	db_key_t result_cols[24]; 
	db1_res_t *res= NULL;
	db_row_t *row = NULL;	
	db_val_t *row_vals= NULL;
	int i;
	int n_result_cols= 0;
	int pres_uri_col, expires_col, from_user_col, from_domain_col,to_user_col; 
	int callid_col,totag_col,fromtag_col,to_domain_col,sockinfo_col,reason_col;
	int event_col,contact_col,record_route_col, event_id_col, status_col;
	int remote_cseq_col, local_cseq_col, local_contact_col, version_col;
	int watcher_user_col, watcher_domain_col;
	subs_t s;
	str ev_sname;
	pres_ev_t* event= NULL;
	event_t parsed_event;
	unsigned int expires;
	unsigned int hash_code;

	result_cols[pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
	result_cols[expires_col=n_result_cols++] = &str_expires_col;
	result_cols[event_col=n_result_cols++] = &str_event_col;
	result_cols[event_id_col=n_result_cols++] = &str_event_id_col;
	result_cols[to_user_col=n_result_cols++] = &str_to_user_col;
	result_cols[to_domain_col=n_result_cols++] = &str_to_domain_col;
	result_cols[watcher_user_col=n_result_cols++] = &str_watcher_username_col;
	result_cols[watcher_domain_col=n_result_cols++] = &str_watcher_domain_col;
	result_cols[from_user_col=n_result_cols++] = &str_from_user_col;
	result_cols[from_domain_col=n_result_cols++] = &str_from_domain_col;
	result_cols[callid_col=n_result_cols++] = &str_callid_col;
	result_cols[totag_col=n_result_cols++] = &str_to_tag_col;
	result_cols[fromtag_col=n_result_cols++] = &str_from_tag_col;
	result_cols[local_cseq_col= n_result_cols++] = &str_local_cseq_col;
	result_cols[remote_cseq_col= n_result_cols++] = &str_remote_cseq_col;
	result_cols[record_route_col= n_result_cols++] = &str_record_route_col;
	result_cols[sockinfo_col= n_result_cols++] = &str_socket_info_col;
	result_cols[contact_col= n_result_cols++] = &str_contact_col;
	result_cols[local_contact_col= n_result_cols++] = &str_local_contact_col;
	result_cols[version_col= n_result_cols++] = &str_version_col;
	result_cols[status_col= n_result_cols++] = &str_status_col;
	result_cols[reason_col= n_result_cols++] = &str_reason_col;
	
	if(!rls_db)
	{
		LM_ERR("null database connection\n");
		return -1;
	}
	if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
	{
		LM_ERR("in use table\n");
		return -1;
	}

	if(db_fetch_query(&rls_dbf, rls_fetch_rows, rls_db, 0, 0, 0,
				result_cols,0, n_result_cols, 0, &res)< 0)
	{
		LM_ERR("while querrying table\n");
		if(res)
		{
			rls_dbf.free_result(rls_db, res);
			res = NULL;
		}
		return -1;
	}
	if(res== NULL)
		return -1;

	if(res->n<=0)
	{
		LM_INFO("The query returned no result\n");
		rls_dbf.free_result(rls_db, res);
		res = NULL;
		return 0;
	}

	do {
		LM_DBG("found %d db entries\n", res->n);

		for(i =0 ; i< res->n ; i++)
		{
			row = &res->rows[i];
			row_vals = ROW_VALUES(row);
			memset(&s, 0, sizeof(subs_t));

			expires= row_vals[expires_col].val.int_val;
		
			if(expires< (int)time(NULL))
				continue;
	
			s.pres_uri.s= (char*)row_vals[pres_uri_col].val.string_val;
			s.pres_uri.len= strlen(s.pres_uri.s);
		
			s.to_user.s=(char*)row_vals[to_user_col].val.string_val;
			s.to_user.len= strlen(s.to_user.s);

			s.to_domain.s=(char*)row_vals[to_domain_col].val.string_val;
			s.to_domain.len= strlen(s.to_domain.s);

			s.from_user.s=(char*)row_vals[from_user_col].val.string_val;
			s.from_user.len= strlen(s.from_user.s);
		
			s.from_domain.s=(char*)row_vals[from_domain_col].val.string_val;
			s.from_domain.len= strlen(s.from_domain.s);

			s.watcher_user.s=(char*)row_vals[watcher_user_col].val.string_val;
			s.watcher_user.len= strlen(s.watcher_user.s);
		
			s.watcher_domain.s=(char*)row_vals[watcher_domain_col].val.string_val;
			s.watcher_domain.len= strlen(s.watcher_domain.s);


			s.to_tag.s=(char*)row_vals[totag_col].val.string_val;
			s.to_tag.len= strlen(s.to_tag.s);

			s.from_tag.s=(char*)row_vals[fromtag_col].val.string_val;
			s.from_tag.len= strlen(s.from_tag.s);

			s.callid.s=(char*)row_vals[callid_col].val.string_val;
			s.callid.len= strlen(s.callid.s);

			ev_sname.s= (char*)row_vals[event_col].val.string_val;
			ev_sname.len= strlen(ev_sname.s);
		
			event= pres_contains_event(&ev_sname, &parsed_event);
			if(event== NULL)
			{
				LM_ERR("event not found in list\n");
				goto error;
			}
			s.event= event;

			s.event_id.s=(char*)row_vals[event_id_col].val.string_val;
			if(s.event_id.s)
				s.event_id.len= strlen(s.event_id.s);

			s.remote_cseq= row_vals[remote_cseq_col].val.int_val;
			s.local_cseq= row_vals[local_cseq_col].val.int_val;
			s.version= row_vals[version_col].val.int_val;
		
			s.expires= expires- (int)time(NULL);
			s.status= row_vals[status_col].val.int_val;

			s.reason.s= (char*)row_vals[reason_col].val.string_val;
			if(s.reason.s)
				s.reason.len= strlen(s.reason.s);

			s.contact.s=(char*)row_vals[contact_col].val.string_val;
			s.contact.len= strlen(s.contact.s);

			s.local_contact.s=(char*)row_vals[local_contact_col].val.string_val;
			s.local_contact.len= strlen(s.local_contact.s);
	
			s.record_route.s=(char*)row_vals[record_route_col].val.string_val;
			if(s.record_route.s)
				s.record_route.len= strlen(s.record_route.s);
	
			s.sockinfo_str.s=(char*)row_vals[sockinfo_col].val.string_val;
			s.sockinfo_str.len= strlen(s.sockinfo_str.s);

			hash_code= core_hash(&s.pres_uri, &s.event->name, hash_size);
			if(pres_insert_shtable(rls_table, hash_code, &s)< 0)
			{
				LM_ERR("adding new record in hash table\n");
				goto error;
			}
		}
	} while((db_fetch_next(&rls_dbf, rls_fetch_rows, rls_db, &res)==1)
			&& (RES_ROW_N(res)>0));

	rls_dbf.free_result(rls_db, res);

	/* delete all records */
	if(rls_dbf.delete(rls_db, 0,0,0,0)< 0)
	{
		LM_ERR("deleting all records from database table\n");
		return -1;
	}

	return 0;

error:
	if(res)
		rls_dbf.free_result(rls_db, res);
	return -1;

}
コード例 #20
0
ファイル: address.c プロジェクト: dsanders11/opensips
/*
 * Reload address table to new hash table and when done, make new hash table
 * current one.
 */
int reload_address_table(struct pm_part_struct *part_struct)
{
	db_key_t cols[8];
	db_res_t* res = NULL;
	db_row_t* row;
	db_val_t* val;

	struct address_list **new_hash_table;
	struct subnet *new_subnet_table;
	int i, mask, proto, group, port, id;
    struct ip_addr *ip_addr;
	struct net *subnet;
	str str_pattern = {NULL,0}, str_info={NULL,0};
	str str_src_ip, str_proto;

	cols[0] = &ip_col;
	cols[1] = &grp_col;
	cols[2] = &mask_col;
	cols[3] = &port_col;
	cols[4] = &proto_col;
	cols[5] = &pattern_col;
	cols[6] = &info_col;
	cols[7] = &id_col;

	if (part_struct->perm_dbf.use_table(part_struct->db_handle,
											&part_struct->table) < 0) {
		LM_ERR("failed to use address table\n");
		return -1;
	}

	if (part_struct->perm_dbf.query(part_struct->db_handle, NULL, 0, NULL,
													cols, 0, 8, 0, &res) < 0) {
		LM_ERR("failed to query database\n");
		return -1;
	}

	/* Choose new hash table and free its old contents */
	if (*part_struct->hash_table == part_struct->hash_table_1) {
		empty_hash(part_struct->hash_table_2);
		new_hash_table = part_struct->hash_table_2;
	} else {
		empty_hash(part_struct->hash_table_1);
		new_hash_table = part_struct->hash_table_1;
	}

	/* Choose new subnet table */
	if (*part_struct->subnet_table == part_struct->subnet_table_1) {
		empty_subnet_table(part_struct->subnet_table_2);
		new_subnet_table = part_struct->subnet_table_2;
	} else {
		empty_subnet_table(part_struct->subnet_table_1);
		new_subnet_table = part_struct->subnet_table_1;
	}

	row = RES_ROWS(res);
	LM_DBG("number of rows in address table: %d\n", RES_ROW_N(res));

	if (RES_COL_N(res) != 8) {
		LM_ERR("too many columns\n");
		goto error;
	}

	for (i = 0; i < RES_ROW_N(res); i++) {

		val = ROW_VALUES(row + i);
		if ((VAL_TYPE(val)!=DB_STRING && VAL_TYPE(val)!=DB_STR) ||
				VAL_NULL(val)) {
			LM_ERR("invalid IP column type on row %d, skipping..\n", i);
			continue;
		}
		if (VAL_TYPE(val + 1) != DB_INT || VAL_NULL(val + 1) ||
					VAL_INT(val + 1) < 0) {
			LM_ERR("invalid group column type on row %d, skipping..\n", i);
			continue;
		}
		if (VAL_TYPE(val + 2) != DB_INT || VAL_NULL(val + 2) ||
					VAL_INT(val + 2) < 0 || VAL_INT(val + 2) > 32) {
			LM_ERR("invalid mask column type on row %d, skipping..\n", i);
			continue;
		}
		if (VAL_TYPE(val + 3) != DB_INT || VAL_NULL(val + 3)) {
			LM_ERR("invalid port column type on row %d, skipping..\n", i);
			continue;
		}
		if ((VAL_TYPE(val + 4) != DB_STRING && VAL_TYPE(val + 4) != DB_STR) ||
			VAL_NULL(val + 4)) {
			LM_ERR("invalid protocol column type on row %d, skipping..\n", i);
			continue;
		}
		if (VAL_TYPE(val + 5) != DB_STRING && VAL_TYPE(val + 5) != DB_STR) {
			LM_ERR("invalid pattern column type on row %d, skipping..\n", i);
			continue;
		}
		if (VAL_TYPE(val + 6) != DB_STRING && VAL_TYPE(val + 6) != DB_STR) {
			LM_ERR("invalid info column type on row %d, skipping..\n", i);
			goto error;
		}
		id = (unsigned int) VAL_INT(val + 7);

		/* IP string */
		if (VAL_TYPE(val)==DB_STRING) {
			str_src_ip.s = (char*)VAL_STRING(val);
			str_src_ip.len = strlen(str_src_ip.s);
		} else {
			str_src_ip = VAL_STR(val);
		}
		if (str_src_ip.len==0) {
			LM_DBG("empty ip field in address table, ignoring entry"
					" number %d\n", i);
			continue;
		}

		ip_addr = str2ip(&str_src_ip);

		if (!ip_addr) {
			LM_DBG("invalid ip field in address table, ignoring entry "
				"with id %d\n", id);
			continue;
		}

		/* proto string */
		if (VAL_TYPE(val+4)==DB_STRING) {
			str_proto.s = (char*)VAL_STRING(val+4);
			str_proto.len = strlen(str_proto.s);
		} else {
			str_proto = VAL_STR(val+4);
		}

		if (str_proto.len==4 && !strncasecmp(str_proto.s, "none",4)) {
			LM_DBG("protocol field is \"none\" in address table, ignoring"
					" entry with id %d\n", id);
			continue;
		}

		proto = proto_char2int(&str_proto);
		if (proto == -1) {
			LM_DBG("unknown protocol field in address table, ignoring"
					" entry with id %d\n", id);
			continue;
		}

		/* pattern string */
		if (!VAL_NULL(val + 5)) {
			if (VAL_TYPE(val+5)==DB_STRING) {
				str_pattern.s = (char*)VAL_STRING(val+5);
				str_pattern.len = strlen(str_pattern.s);
			} else {
				str_pattern = VAL_STR(val+5);
			}
		} else {
			str_pattern.len = 0;
			str_pattern.s = 0;
		}

		/* info string */
		if (!VAL_NULL(val + 6)) {
			if (VAL_TYPE(val+6)==DB_STRING) {
				str_info.s = (char*)VAL_STRING(val+6);
				str_info.len = strlen(str_info.s);
			} else {
				str_info = VAL_STR(val+6);
			}
		} else {
			str_info.len = 0;
			str_info.s = 0;
		}

		group = (unsigned int) VAL_INT(val + 1);
		port = (unsigned int) VAL_INT(val + 3);
		mask = (unsigned int) VAL_INT(val + 2);

		if (mask == 32) {
			if (hash_insert(new_hash_table, ip_addr, group, port, proto,
				&str_pattern, &str_info) == -1) {
					LM_ERR("hash table insert error\n");
					goto error;
			}
			LM_DBG("Tuple <%.*s, %u, %u, %u, %.*s, %.*s> inserted into "
					"address hash table\n", str_src_ip.len, str_src_ip.s,
					group, port, proto, str_pattern.len, str_pattern.s,
					str_info.len,str_info.s);
		} else {
			subnet = mk_net_bitlen(ip_addr, mask);
			if (subnet_table_insert(new_subnet_table, group, subnet,
				port, proto, &str_pattern, &str_info) == -1) {
					LM_ERR("subnet table problem\n");
					goto error;
				}
			LM_DBG("Tuple <%.*s, %u, %u, %u> inserted into subnet table\n",
					str_src_ip.len, str_src_ip.s, group, mask, port);
		}
	}

	part_struct->perm_dbf.free_result(part_struct->db_handle, res);

	*part_struct->hash_table = new_hash_table;
	*part_struct->subnet_table = new_subnet_table;
	LM_DBG("address table reloaded successfully.\n");

	return 1;
error:
	part_struct->perm_dbf.free_result(part_struct->db_handle, res);
	return -1;
}
コード例 #21
0
ファイル: ul_db_handle.c プロジェクト: TheGrandWazoo/kamailio
int load_handles(db_func_t * dbf, db1_con_t * dbh) {
	static char query[UL_DB_QUERY_LEN];
	db1_res_t * res;
	db_row_t * row;
	ul_db_handle_list_t * element;
	int i, id, query_len;
	str tmp;

	if(!dbf || !dbh){
		LM_ERR("NULL parameter passed \n");
		return -1;
	}

	query_len = 25 + id_col.len + reg_table.len;

	if(query_len > UL_DB_QUERY_LEN) {
		LM_ERR("weird: query larger than %i bytes.\n", UL_DB_QUERY_LEN);
		return -1;
	}

	memset(query, 0, UL_DB_QUERY_LEN);

	if (sprintf(query,
	        "SELECT DISTINCT "
	        "%.*s "
	        "FROM "
	        "%.*s",
	        id_col.len, id_col.s,
	        reg_table.len, reg_table.s) < 0) {
		LM_ERR("could not print query\n");
		return -1;
	}
	tmp.s = query;
	tmp.len = strlen(query);

	if (dbf->raw_query (dbh, &tmp, &res) < 0) {
		LM_ERR("in database query.\n");
		return -1;
	}

	if (RES_ROW_N (res) == 0) {
		dbf->free_result (dbh, res);
		LM_DBG ("no data found\n");
		return 1;
	}

	for (i = 0; i < RES_ROW_N (res); ++i) {
		row = RES_ROWS (res) + i;

		if((element = allocate_handle_list()) == NULL) {
			LM_ERR("couldnt allocate handle.\n");
			goto errout;
		}

		if (VAL_NULL (ROW_VALUES(row) + 0)) {
			LM_ERR("Weird: Empty ID-Field\n");
			goto errout;
		}

		id = VAL_INT (ROW_VALUES(row) + 0);
		if(load_data(dbf, dbh, element->handle, id) < 0){
			LM_ERR("couldn't load handle data.\n");
			goto errout;
		}
		element->next = db_handles;
		db_handles = element;
	}
	dbf->free_result (dbh, res);
	return 0;
errout:
	dbf->free_result (dbh, res);
	return -1;
}
コード例 #22
0
ファイル: dp_db.c プロジェクト: WuKongQC/opensips
/*load rules from DB*/
int dp_load_db(dp_connection_list_p dp_conn)
{
    int i, nr_rows;
    db_res_t * res = 0;
    db_val_t * values;
    db_row_t * rows;
    db_key_t query_cols[DP_TABLE_COL_NO] = {
        &dpid_column,		&pr_column,
        &match_op_column,	&match_exp_column,	&match_flags_column,
        &subst_exp_column,	&repl_exp_column,	&attrs_column,	&timerec_column
    };
    db_key_t order = &pr_column;
    /* disabled condition */
    db_key_t cond_cols[1] = { &disabled_column };
    db_val_t cond_val[1];

    dpl_node_t *rule;
    int no_rows = 10;


    lock_start_write( dp_conn->ref_lock );

    if( dp_conn->crt_index != dp_conn->next_index) {
        LM_WARN("a load command already generated, aborting reload...\n");
        lock_stop_write( dp_conn->ref_lock );
        return 0;
    }

    dp_conn->next_index = dp_conn->crt_index == 0 ? 1 : 0;

    lock_stop_write( dp_conn->ref_lock );

    if (dp_conn->dp_dbf.use_table(*dp_conn->dp_db_handle, &dp_conn->table_name) < 0) {
        LM_ERR("error in use_table\n");
        goto err1;
    }

    VAL_TYPE(cond_val) = DB_INT;
    VAL_NULL(cond_val) = 0;
    VAL_INT(cond_val) = 0;

    if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) {
        if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,cond_cols,
                                 0,cond_val,query_cols,1,
                                 DP_TABLE_COL_NO, order, 0) < 0) {
            LM_ERR("failed to query database!\n");

            goto err1;
        }
        no_rows = estimate_available_rows( 4+4+4+64+4+64+64+128,
                                           DP_TABLE_COL_NO);
        if (no_rows==0) no_rows = 10;
        if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle,
                                        &res, no_rows)<0) {
            LM_ERR("failed to fetch\n");
            if (res)
                dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

            goto err1;
        }
    } else {
        /*select the whole table and all the columns*/
        if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,
                                 cond_cols,0,cond_val,query_cols,1,
                                 DP_TABLE_COL_NO, order, &res) < 0) {
            LM_ERR("failed to query database\n");

            goto err1;
        }
    }

    nr_rows = RES_ROW_N(res);



    if(nr_rows == 0) {
        LM_WARN("no data in the db\n");
        goto end;
    }

    do {
        for(i=0; i<RES_ROW_N(res); i++) {
            rows = RES_ROWS(res);
            values = ROW_VALUES(rows+i);

            if ((rule = build_rule(values)) == NULL) {
                LM_WARN(" failed to build rule -> skipping\n");
                continue;
            }

            rule->table_id = i;

            if(add_rule2hash(rule , dp_conn, dp_conn->next_index) != 0) {
                LM_ERR("add_rule2hash failed\n");
                goto err2;
            }
        }


        if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) {
            if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle,
                                            &res, no_rows)<0) {
                LM_ERR("failure while fetching!\n");
                if (res)
                    dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);
                goto err1;
            }
        } else {
            break;
        }
    }  while(RES_ROW_N(res)>0);


end:


    /*update data*/
    lock_start_write( dp_conn->ref_lock );

    destroy_hash(&dp_conn->hash[dp_conn->crt_index]);

    dp_conn->crt_index = dp_conn->next_index;

    lock_stop_write( dp_conn->ref_lock );

    list_hash(dp_conn->hash[dp_conn->crt_index], dp_conn->ref_lock);

    dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);
    return 0;

err1:

    lock_start_write( dp_conn->ref_lock );

    dp_conn->next_index = dp_conn->crt_index;

    lock_stop_write( dp_conn->ref_lock );

    return -1;

err2:
    if(rule)	destroy_rule(rule);
    destroy_hash(&dp_conn->hash[dp_conn->next_index]);
    dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res);

    lock_start_write( dp_conn->ref_lock );

    dp_conn->next_index = dp_conn->crt_index;
    /* if lock defined - release the exclusive writing access */

    lock_stop_write( dp_conn->ref_lock );
    return -1;
}
コード例 #23
0
ファイル: rtpproxy_db.c プロジェクト: AlessioCasco/kamailio
static int rtpp_load_db(void)
{
	int i;
	struct rtpp_set *rtpp_list = NULL;
	db1_res_t *res = NULL;
	db_val_t *values = NULL;
	db_row_t *rows = NULL;
	db_key_t query_cols[] = {&rtpp_set_name_col, &rtpp_url_col, &rtpp_weight_col, &rtpp_flags_col};

	str set, url;
	int weight, flags;
	int n_rows = 0;
	int n_cols = 4;

	if (rtpp_db_handle == NULL)
	{
		LM_ERR("invalid db handle\n");
		return -1;
	}
	if (rtpp_dbf.use_table(rtpp_db_handle, &rtpp_table_name) < 0)
	{
		LM_ERR("unable to use table '%.*s'\n", rtpp_table_name.len, rtpp_table_name.s);
		return -1;
	}
	if (rtpp_dbf.query(rtpp_db_handle, 0, 0, 0, query_cols, 0, n_cols, 0, &res) < 0)
	{
		LM_ERR("error while running db query\n");
		return -1;
	}

	n_rows = RES_ROW_N(res);
	rows = RES_ROWS(res);
	if (n_rows == 0)
	{
		LM_WARN("No rtpproxy instances in database\n");
		return 0;
	}
	for (i=0; i<n_rows; i++)
	{
		values = ROW_VALUES(rows + i);

		set.s = VAL_STR(values).s;
		set.len = strlen(set.s);
		url.s = VAL_STR(values+1).s;
		url.len = strlen(url.s);
		weight = VAL_INT(values+2);
		flags = VAL_INT(values+3);

		if ((rtpp_list = get_rtpp_set(&set)) == NULL)
		{
			LM_ERR("error getting rtpp_list for set '%.*s'\n", set.len, set.s);
			continue;
		}
		if (insert_rtpp_node(rtpp_list, &url, weight, flags) < 0)
		{
			LM_ERR("error inserting '%.*s' into set '%.*s'\n", url.len, url.s, set.len, set.s);
		}
	}

	rtpp_dbf.free_result(rtpp_db_handle, res);
	return 0;
}
コード例 #24
0
ファイル: uac_reg.c プロジェクト: AndyJRobinson/kamailio
int uac_reg_load_db(void)
{
	db1_con_t *reg_db_con = NULL;
	db_func_t reg_dbf;
	reg_uac_t reg;
	db_key_t db_cols[12] = {
		&l_uuid_column,
		&l_username_column,
		&l_domain_column,
		&r_username_column,
		&r_domain_column,
		&realm_column,
		&auth_username_column,
		&auth_password_column,
		&auth_proxy_column,
		&expires_column,
		&flags_column,
		&reg_delay_column
	};
	db1_res_t* db_res = NULL;
	int i, ret;

	/* binding to db module */
	if(reg_db_url.s==NULL)
	{
		LM_ERR("no db url\n");
		return -1;
	}

	if(db_bind_mod(&reg_db_url, &reg_dbf))
	{
		LM_ERR("database module not found\n");
		return -1;
	}

	if (!DB_CAPABILITY(reg_dbf, DB_CAP_ALL))
	{
		LM_ERR("database module does not "
				"implement all functions needed by the module\n");
		return -1;
	}

	/* open a connection with the database */
	reg_db_con = reg_dbf.init(&reg_db_url);
	if(reg_db_con==NULL)
	{
		LM_ERR("failed to connect to the database\n");
		return -1;
	}
	if (reg_dbf.use_table(reg_db_con, &reg_db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	if (DB_CAPABILITY(reg_dbf, DB_CAP_FETCH)) {
		if(reg_dbf.query(reg_db_con, 0, 0, 0, db_cols, 0, 12, 0, 0) < 0)
		{
			LM_ERR("Error while querying db\n");
			return -1;
		}
		if(reg_dbf.fetch_result(reg_db_con, &db_res, reg_fetch_rows)<0)
		{
			LM_ERR("Error while fetching result\n");
			if (db_res)
				reg_dbf.free_result(reg_db_con, db_res);
			goto error;
		} else {
			if(RES_ROW_N(db_res)==0)
			{
				goto done;
			}
		}
	} else {
		if((ret=reg_dbf.query(reg_db_con, NULL, NULL, NULL, db_cols,
						0, 10, 0, &db_res))!=0
				|| RES_ROW_N(db_res)<=0 )
		{
			reg_dbf.free_result(reg_db_con, db_res);
			if( ret==0)
			{
				return 0;
			} else {
				goto error;
			}
		}
	}

	do {
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			memset(&reg, 0, sizeof(reg_uac_t));;
			/* check for NULL values ?!?! */
			reg_db_set_attr(l_uuid, 0);
			reg_db_set_attr(l_username, 1);
			reg_db_set_attr(l_domain, 2);
			reg_db_set_attr(r_username, 3);
			reg_db_set_attr(r_domain, 4);
			/* realm may be empty */
			if(!VAL_NULL(&RES_ROWS(db_res)[i].values[5])) {
				reg.realm.s = (char*)(RES_ROWS(db_res)[i].values[5].val.string_val);
				reg.realm.len = strlen(reg.realm.s);
			}
			reg_db_set_attr(auth_username, 6);
			reg_db_set_attr(auth_password, 7);
			reg_db_set_attr(auth_proxy, 8);
			reg.expires
				= (unsigned int)RES_ROWS(db_res)[i].values[9].val.int_val;
			reg.flags
				= (unsigned int)RES_ROWS(db_res)[i].values[10].val.int_val;
			reg.reg_delay
				= (unsigned int)RES_ROWS(db_res)[i].values[11].val.int_val;

			if(reg_ht_add(&reg)<0)
			{
				LM_ERR("Error adding reg to htable\n");
				goto error;
			}
		}
		if (DB_CAPABILITY(reg_dbf, DB_CAP_FETCH)) {
			if(reg_dbf.fetch_result(reg_db_con, &db_res, reg_fetch_rows)<0) {
				LM_ERR("Error while fetching!\n");
				if (db_res)
					reg_dbf.free_result(reg_db_con, db_res);
				goto error;
			}
		} else {
			break;
		}
	}  while(RES_ROW_N(db_res)>0);
	reg_dbf.free_result(reg_db_con, db_res);
	reg_dbf.close(reg_db_con);

done:
	return 0;

error:
	if (reg_db_con) {
		reg_dbf.free_result(reg_db_con, db_res);
		reg_dbf.close(reg_db_con);
	}
	return -1;
}
コード例 #25
0
ファイル: udomain.c プロジェクト: 4N7HR4X/kamailio
/*!
 * \brief Loads from DB all contacts for a RUID
 * \param _c database connection
 * \param _d domain
 * \param _aor address of record
 * \return pointer to the record on success, 0 on errors or if nothing is found
 */
urecord_t* db_load_urecord_by_ruid(udomain_t* _d, str *_ruid)
{
	ucontact_info_t *ci;
	db_key_t columns[18];
	db_key_t keys[1];
	db_key_t order;
	db_val_t vals[1];
	db1_res_t* res = NULL;
	db_row_t *row;
	str contact;
	str aor;
	char aorbuf[512];
	str domain;

	urecord_t* r;
	ucontact_t* c;

	keys[0] = &ruid_col;
	vals[0].type = DB1_STR;
	vals[0].nul = 0;
	vals[0].val.str_val = *_ruid;

	columns[0] = &contact_col;
	columns[1] = &expires_col;
	columns[2] = &q_col;
	columns[3] = &callid_col;
	columns[4] = &cseq_col;
	columns[5] = &flags_col;
	columns[6] = &cflags_col;
	columns[7] = &user_agent_col;
	columns[8] = &received_col;
	columns[9] = &path_col;
	columns[10] = &sock_col;
	columns[11] = &methods_col;
	columns[12] = &last_mod_col;
	columns[13] = &ruid_col;
	columns[14] = &instance_col;
	columns[15] = &reg_id_col;
	columns[16] = &user_col;
	columns[17] = &domain_col;

	if (desc_time_order)
		order = &last_mod_col;
	else
		order = &q_col;

	if (ul_db_layer_query(_d,  &vals[0].val.str_val,  &vals[1].val.str_val, keys, 0, vals, columns, 1, 18, order,
				&res) < 0) {
		LM_ERR("db_query failed\n");
		return 0;
	}

	if (RES_ROW_N(res) == 0) {
		LM_DBG("aor %.*s not found in table %.*s\n",_ruid->len, _ruid->s,
				_d->name->len, _d->name->s);
		ul_db_layer_free_result(_d, res);
		return 0;
	}

	r = 0;

	/* use first row - shouldn't be more */
	row = RES_ROWS(res);

	ci = dbrow2info(ROW_VALUES(RES_ROWS(res)), &contact);
	if (ci==0) {
		LM_ERR("skipping record for %.*s in table %s\n",
				_ruid->len, _ruid->s, _d->name->s);
		goto done;
	}

	aor.s = (char*)VAL_STRING(ROW_VALUES(row) + 15);
	aor.len = strlen(aor.s);

	if (use_domain) {
		domain.s = (char*)VAL_STRING(ROW_VALUES(row) + 17);
		if (VAL_NULL(ROW_VALUES(row)+17) || domain.s==0 || domain.s[0]==0){
			LM_CRIT("empty domain record for user %.*s...skipping\n",
					aor.len, aor.s);
			goto done;
		}
		domain.len = strlen(domain.s);
		if(aor.len + domain.len + 2 >= 512) {
			LM_ERR("AoR is too big\n");
			goto done;
		}
		memcpy(aorbuf, aor.s, aor.len);
		aorbuf[aor.len] = '@';
		memcpy(aorbuf + aor.len + 1, domain.s, domain.len);
		aor.len += 1 + domain.len;
		aor.s = aorbuf;
		aor.s[aor.len] = '\0';
	}
	get_static_urecord( _d, &aor, &r);

	if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
		LM_ERR("mem_insert failed\n");
		free_urecord(r);
		ul_db_layer_free_result(_d, res);
		return 0;
	}

	/* We have to do this, because insert_ucontact sets state to CS_NEW
	 * and we have the contact in the database already */
	c->state = CS_SYNC;

done:
	ul_db_layer_free_result(_d, res);
	;
	return r;
}
コード例 #26
0
ファイル: uac_reg.c プロジェクト: AndyJRobinson/kamailio
int uac_reg_db_refresh(str *pl_uuid)
{
	db1_con_t *reg_db_con = NULL;
	db_func_t reg_dbf;
	reg_uac_t reg;
	db_key_t db_cols[12] = {
		&l_uuid_column,
		&l_username_column,
		&l_domain_column,
		&r_username_column,
		&r_domain_column,
		&realm_column,
		&auth_username_column,
		&auth_password_column,
		&auth_proxy_column,
		&expires_column,
		&flags_column,
		&reg_delay_column
	};
	db_key_t db_keys[1] = {&l_uuid_column};
	db_val_t db_vals[1];

	db1_res_t* db_res = NULL;
	int i, ret;

	/* binding to db module */
	if(reg_db_url.s==NULL)
	{
		LM_ERR("no db url\n");
		return -1;
	}

	if(db_bind_mod(&reg_db_url, &reg_dbf))
	{
		LM_ERR("database module not found\n");
		return -1;
	}

	if (!DB_CAPABILITY(reg_dbf, DB_CAP_ALL))
	{
		LM_ERR("database module does not "
				"implement all functions needed by the module\n");
		return -1;
	}

	/* open a connection with the database */
	reg_db_con = reg_dbf.init(&reg_db_url);
	if(reg_db_con==NULL)
	{
		LM_ERR("failed to connect to the database\n");
		return -1;
	}
	if (reg_dbf.use_table(reg_db_con, &reg_db_table) < 0)
	{
		LM_ERR("failed to use_table\n");
		return -1;
	}

	db_vals[0].type = DB1_STR;
	db_vals[0].nul = 0;
	db_vals[0].val.str_val.s = pl_uuid->s;
	db_vals[0].val.str_val.len = pl_uuid->len;

	if((ret=reg_dbf.query(reg_db_con, db_keys, NULL, db_vals, db_cols,
					1 /*nr keys*/, 12 /*nr cols*/, 0, &db_res))!=0
			|| RES_ROW_N(db_res)<=0 )
	{
		reg_dbf.free_result(reg_db_con, db_res);
		if( ret==0)
		{
			return 0;
		} else {
			goto error;
		}
	}

	memset(&reg, 0, sizeof(reg_uac_t));;
	i = 0;
	/* check for NULL values ?!?! */
	reg_db_set_attr(l_uuid, 0);
	reg_db_set_attr(l_username, 1);
	reg_db_set_attr(l_domain, 2);
	reg_db_set_attr(r_username, 3);
	reg_db_set_attr(r_domain, 4);
	/* realm may be empty */
	if(!VAL_NULL(&RES_ROWS(db_res)[i].values[5])) {
		reg.realm.s = (char*)(RES_ROWS(db_res)[i].values[5].val.string_val);
		reg.realm.len = strlen(reg.realm.s);
	}
	reg_db_set_attr(auth_username, 6);
	reg_db_set_attr(auth_password, 7);
	reg_db_set_attr(auth_proxy, 8);
	reg.expires = (unsigned int)RES_ROWS(db_res)[i].values[9].val.int_val;
	reg.h_uuid = reg_compute_hash(&reg.l_uuid);
	reg.h_user = reg_compute_hash(&reg.l_username);
	reg.flags = (unsigned int)RES_ROWS(db_res)[i].values[10].val.int_val;
	reg.reg_delay = (unsigned int)RES_ROWS(db_res)[i].values[11].val.int_val;

	lock_get(_reg_htable_gc_lock);
	if(reg_ht_get_byuuid(pl_uuid)!=NULL)
	{
		if(reg_ht_update_attrs(&reg)<0)
		{
			lock_release(_reg_htable_gc_lock);
			LM_ERR("Error updating reg to htable\n");
			goto error;
		}
	} else {
		if(reg_ht_add(&reg)<0)
		{
			lock_release(_reg_htable_gc_lock);
			LM_ERR("Error adding reg to htable\n");
			goto error;
		}
	}
	lock_release(_reg_htable_gc_lock);

	reg_dbf.free_result(reg_db_con, db_res);
	reg_dbf.close(reg_db_con);

	return 0;

error:
	if (reg_db_con) {
		reg_dbf.free_result(reg_db_con, db_res);
		reg_dbf.close(reg_db_con);
	}
	return -1;
}
コード例 #27
0
ファイル: domainpolicy.c プロジェクト: UIKit0/OpenSIPS
/*
 * input: rule straight from the DDDS + avp-stack.
 *
 * output: adds found rules to the stack and return
 * 	1 on success
 * 	0 on failure
 */
static int check_rule(str *rule, char *service, int service_len, struct avp_stack *stack) {

    /* for the select */
    db_key_t keys[2];
    db_val_t vals[2];
    db_key_t cols[4]; 
    db_res_t* res;
    db_row_t* row;
    db_val_t* val;
    int	i;
    char *type;
    int type_len;

    LM_INFO("checking for '%.*s'.\n", rule->len, ZSW(rule->s));

    if ((service_len != 11) || (strncasecmp("d2p+sip:fed", service, 11) && 
	    strncasecmp("d2p+sip:std", service, 11)  && strncasecmp("d2p+sip:dom", service, 11))) {
    	LM_ERR("can only cope with d2p+sip:fed, d2p+sip:std,and d2p+sip:dom "
				"for now (and not %.*s).\n", service_len, service);
	return(0);
    }

    type = service + 8;
    type_len = service_len - 8;

    if (domainpolicy_dbf.use_table(db_handle, &domainpolicy_table) < 0) {
	    LM_ERR("failed to domainpolicy table\n");
	    return -1;
    }

    keys[0]=&domainpolicy_col_rule;
    keys[1]=&domainpolicy_col_type;
    cols[0]=&domainpolicy_col_rule;
    cols[1]=&domainpolicy_col_type;
    cols[2]=&domainpolicy_col_att;
    cols[3]=&domainpolicy_col_val;

    VAL_TYPE(&vals[0]) = DB_STR;
    VAL_NULL(&vals[0]) = 0;
    VAL_STR(&vals[0]).s = rule->s;
    VAL_STR(&vals[0]).len = rule->len;

    VAL_TYPE(&vals[1]) = DB_STR;
    VAL_NULL(&vals[1]) = 0;
    VAL_STR(&vals[1]).s = type;
    VAL_STR(&vals[1]).len = type_len;

    /*
     * SELECT rule, att, val from domainpolicy where rule = "..."
     */

    if (domainpolicy_dbf.query(db_handle, keys, 0, vals, cols, 2, 4, 0, &res) < 0
		    ) {
	    LM_ERR("querying database\n");
	    return -1;
    }
    
    LM_INFO("querying database OK\n");

    if (RES_ROW_N(res) == 0) {
	    LM_DBG("rule '%.*s' is not know.\n", 
		rule->len, ZSW(rule->s));
	    domainpolicy_dbf.free_result(db_handle, res);
	    return 0;
    } else {
	    LM_DBG("rule '%.*s' is known\n", rule->len, ZSW(rule->s));

	    row = RES_ROWS(res);

	    for(i = 0; i < RES_ROW_N(res); i++) {
			if (ROW_N(row + i) != 4) {
	    	    LM_ERR("unexpected cell count\n");
				return(-1);
			}

			val = ROW_VALUES(row + i);

			if ((VAL_TYPE(val) != DB_STRING) || 
				(VAL_TYPE(val+1) != DB_STRING) ||
				(VAL_TYPE(val+2) != DB_STRING) ||
				(VAL_TYPE(val+3) != DB_STRING)) {
					LM_ERR("unexpected cell types\n");
			    return(-1);
			}

			if (VAL_NULL(val+2) || VAL_NULL(val+3)) {
				LM_INFO("db returned NULL values. Fine with us.\n");
				continue;
			}

			LM_INFO("DB returned %s/%s \n",VAL_STRING(val+2),VAL_STRING(val+3));


			if (!stack_push(stack, (char *) VAL_STRING(val+2), 
					(char *) VAL_STRING(val+3))) {
			    return(-1);
			}
	    }
	    domainpolicy_dbf.free_result(db_handle, res);
	    return 1;
    }
}
コード例 #28
0
int pdt_load_db()
{
	db_key_t db_cols[] = {prefix_column, domain_column};
	str p, d;
	db_res_t* db_res = NULL;
	int i;


	if(db_con==NULL)
	{
		LOG(L_ERR, "PDT:pdt_load_db: no db connection\n");
		return -1;
	}

	if (pdt_dbf.use_table(db_con, db_table) < 0)
	{
		LOG(L_ERR, "PDT:pdt_load_db: Error in use_table\n");
		return -1;
	}

	if(pdt_dbf.query(db_con, NULL, NULL, NULL, db_cols,
				0, 2, prefix_column, &db_res)==0)
	{
		for(i=0; i<RES_ROW_N(db_res); i++)
		{
			/* check for NULL values ?!?! */
			p.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
			p.len = strlen(p.s);

			d.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val);
			d.len = strlen(d.s);

			if(p.s==NULL || d.s==NULL || p.len<=0 || d.len<=0)
			{
				LOG(L_ERR, "PDT:pdt_load_db: Error - bad values in db\n");
				goto error;
			}

			if(pdt_check_pd(_dhash, &p, &d)!=0)
			{
				LOG(L_ERR,
				"PDT:pdt_load_db: prefix [%.*s] or domain <%.*s> duplicated\n",
					p.len, p.s, d.len, d.s);
				goto error;;
			}

			if(pdt_add_to_tree(_ptree, &p, &d)!=0)
			{
				LOG(L_ERR, "PDT:pdt_load_db: Error adding info in tree\n");
				goto error;
			}

			if(pdt_add_to_hash(_dhash, &p, &d)!=0)
			{
				LOG(L_ERR, "PDT:pdt_load_db: Error adding info in hash\n");
				goto error;
			}
 		}
	}

	pdt_dbf.free_result(db_con, db_res);
	return 0;

error:
	pdt_dbf.free_result(db_con, db_res);
	return -1;
}
コード例 #29
0
ファイル: db_checks.c プロジェクト: KISSMonX/opensips
/*
 * 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;
	}
}
コード例 #30
0
ファイル: dbcassa_base.cpp プロジェクト: adubovikov/kamailio
/**
 * Execute a raw SQL query.
 * \param _h handle for the database
 * \param _s raw query string
 * \param _r result set for storage
 * \return zero on success, negative value on failure
 */
int db_cassa_raw_query(const db1_con_t* _h, const str* _s, db1_res_t** _r)
{
	db1_res_t* db_res = 0;
	str table_name;
	dbcassa_table_p tbc;
	std::vector<oac::CqlRow>  res_cql_rows;

	if (!_h || !_r) {
		LM_ERR("Invalid parameter value\n");
		return -1;
	}
	
	if (get_table_from_query(_s, &table_name) < 0) { 
		LM_ERR("Error parsing table name in CQL string");
		return -1;
	}

	LM_DBG("query table=%.*s\n", table_name.len, table_name.s);
	LM_DBG("CQL=%s\n", _s->s);

	tbc = dbcassa_db_get_table(&CON_CASSA(_h)->db_name, &table_name);
        if(!tbc) {
                LM_ERR("table %.*s does not exist!\n", table_name.len, table_name.s);
                return -1;
        }

	std::string cql_query(_s->s);

	oac::CqlResult cassa_cql_res;

	try {
		CON_CASSA(_h)->con->execute_cql_query(cassa_cql_res, cql_query , oac::Compression::NONE);
	} catch (const oac::InvalidRequestException &irx) {
		LM_ERR("Invalid Request caused error details: %s.\n", irx.why.c_str());
	} catch (const at::TException &tx) {
		LM_ERR("T Exception %s\n", tx.what());
	} catch (const std::exception &ex) {
		LM_ERR("Failed: %s\n", ex.what());
	} catch (...) {
		LM_ERR("Failed to open connection to Cassandra cluster\n");
	}

	if (!cassa_cql_res.__isset.rows) {
		LM_ERR("The resultype rows was not set, no point trying to parse result.\n");
		goto error;
	}

	res_cql_rows = cassa_cql_res.rows;

	/* TODO Handle the other types */
	switch(cassa_cql_res.type) {
		case 1:  LM_DBG("Result set is an ROW Type.\n");
			break;
		case 2: LM_DBG("Result set is an VOID Type.\n");
			break;
		case 3: LM_DBG("Result set is an INT Type.\n");
			break;
	}

	db_res = db_new_result();
	if (!db_res) {
		LM_ERR("no memory left\n");
		goto error;
	}

	if(res_cql_rows.size() == 0) {
		LM_DBG("The query returned no result\n");
		RES_ROW_N(db_res) = 0;
		RES_COL_N(db_res)= 0;
		*_r = db_res;
		goto done;
	}

	if (cql_get_columns(cassa_cql_res, db_res, tbc) < 0) {
		LM_ERR("Error getting column names.");
		goto error;
	}

	if (cql_convert_row(cassa_cql_res, db_res) < 0) {
		LM_ERR("Error converting rows");
		goto error;
	}

	*_r = db_res;
done:
	dbcassa_lock_release(tbc);

	LM_DBG("Exited with success\n");
	return 0;

error:
	if(db_res)
		db_free_result(db_res);
	
	dbcassa_lock_release(tbc);
	return -1;
}