Module: sip-router
Branch: master
Commit: a9f1f9e3cd62d296bcbf4c3618da96d077aacd86
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a9f1f9e…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Tue Oct 16 21:28:46 2012 +0200
auth_db(k): new function is_subscriber(uri, dbtable, flags)
- check if URI corresponds to a subscriber record in dbtable and load
credentials for it
---
modules_k/auth_db/README | 35 +++++++++++++++
modules_k/auth_db/authdb_mod.c | 63 +++++++++++++++++++++++++++
modules_k/auth_db/authorize.c | 72 +++++++++++++++++++++++++++++++
modules_k/auth_db/authorize.h | 5 ++
modules_k/auth_db/doc/auth_db_admin.xml | 52 ++++++++++++++++++++++
5 files changed, 227 insertions(+), 0 deletions(-)
diff --git a/modules_k/auth_db/README b/modules_k/auth_db/README
index e77eac1..fc6fa4e 100644
--- a/modules_k/auth_db/README
+++ b/modules_k/auth_db/README
@@ -58,6 +58,7 @@ Jan Janak
4.3. proxy_authenticate(realm, table)
4.4. proxy_authorize(realm, table)
4.5. auth_check(realm, table, flags)
+ 4.6. is_subscriber(uri, dbtable, flags)
List of Examples
@@ -73,6 +74,7 @@ Jan Janak
1.10. www_authorize usage
1.11. proxy_authorize usage
1.12. auth_check usage
+ 1.13. is_subscriber usage
Chapter 1. Admin Guide
@@ -103,6 +105,7 @@ Chapter 1. Admin Guide
4.3. proxy_authenticate(realm, table)
4.4. proxy_authorize(realm, table)
4.5. auth_check(realm, table, flags)
+ 4.6. is_subscriber(uri, dbtable, flags)
1. Overview
@@ -301,6 +304,7 @@ modparam("auth_db", "version_table", 0)
4.3. proxy_authenticate(realm, table)
4.4. proxy_authorize(realm, table)
4.5. auth_check(realm, table, flags)
+ 4.6. is_subscriber(uri, dbtable, flags)
4.1. www_authenticate(realm, table)
@@ -420,3 +424,34 @@ if (!auth_check("$fd", "subscriber",
"1")) {
exit;
}
...
+
+4.6. is_subscriber(uri, dbtable, flags)
+
+ The function checks if there is a subscriber corresponding to the AoR
+ in uri parameter. It uses same database connection as for
+ authentication functions.
+
+ In addition, if the subscriber record is found, then the
+ load_credentials attributes are loaded. An use case can be loading the
+ credential attributes for callee.
+
+ Meaning of the parameters is as follows:
+ * uri - a valid SIP URI value to identify the subscriber. The string
+ may contain pseudo variables.
+ * dbtable - Table to be used to lookup username and domain from URI
+ (usually subscriber table). The string may contain pseudo
+ variables.
+ * flags - set of flags to control the behaviour of the function. If
+ it is 1, then the function will use the domain part of the URI to
+ perform the database table search.
+ The parameter may be a pseudo variable.
+
+ This function can be used from ANY_ROUTE.
+
+ Example 1.13. is_subscriber usage
+...
+if (!is_subscriber("$ru", "subscriber", "1")) {
+ # callee is not a local subscriber
+ ...
+}
+...
diff --git a/modules_k/auth_db/authdb_mod.c b/modules_k/auth_db/authdb_mod.c
index 03d1721..6425d88 100644
--- a/modules_k/auth_db/authdb_mod.c
+++ b/modules_k/auth_db/authdb_mod.c
@@ -43,6 +43,7 @@
#include "../../mod_fix.h"
#include "../../trim.h"
#include "../../mem/mem.h"
+#include "../../parser/parse_uri.h"
#include "../../modules/auth/api.h"
#include "authorize.h"
@@ -68,6 +69,8 @@ static int child_init(int rank);
static int mod_init(void);
+static int w_is_subscriber(sip_msg_t *msg, char *_uri, char* _table,
+ char *_flags);
static int auth_fixup(void** param, int param_no);
static int auth_check_fixup(void** param, int param_no);
int parse_aaa_pvs(char *definition, pv_elem_t **pv_def, int *cnt);
@@ -122,6 +125,8 @@ static cmd_export_t cmds[] = {
REQUEST_ROUTE},
{"auth_check", (cmd_function)auth_check, 3, auth_check_fixup,
0,
REQUEST_ROUTE},
+ {"is_subscriber", (cmd_function)w_is_subscriber, 3, auth_check_fixup,
0,
+ ANY_ROUTE},
{"bind_auth_db", (cmd_function)bind_auth_db, 0, 0, 0,
0},
{0, 0, 0, 0, 0, 0}
@@ -232,6 +237,64 @@ static void destroy(void)
}
+/**
+ * check if the subscriber identified by _uri has a valid record in
+ * database table _table
+ */
+static int w_is_subscriber(sip_msg_t *msg, char *_uri, char* _table,
+ char *_flags)
+{
+ str suri;
+ str stable;
+ int iflags;
+ int ret;
+ sip_uri_t puri;
+
+ if(msg==NULL || _uri==NULL || _table==NULL || _flags==NULL) {
+ LM_ERR("invalid parameters\n");
+ return AUTH_ERROR;
+ }
+
+ if (get_str_fparam(&suri, msg, (fparam_t*)_uri) < 0) {
+ LM_ERR("failed to get uri value\n");
+ return -1;
+ }
+
+ if (suri.len==0) {
+ LM_ERR("invalid uri parameter - empty value\n");
+ return -1;
+ }
+ if(parse_uri(suri.s, suri.len, &puri)<0){
+ LM_ERR("invalid uri parameter format\n");
+ return -1;
+ }
+
+ if (get_str_fparam(&stable, msg, (fparam_t*)_table) < 0) {
+ LM_ERR("failed to get table value\n");
+ return -1;
+ }
+
+ if (stable.len==0) {
+ LM_ERR("invalid table parameter - empty value\n");
+ return -1;
+ }
+
+ if(fixup_get_ivalue(msg, (gparam_p)_flags, &iflags)!=0)
+ {
+ LM_ERR("invalid flags parameter\n");
+ return -1;
+ }
+
+ LM_DBG("uri [%.*s] table [%.*s] flags [%d]\n", suri.len, suri.s,
+ stable.len, stable.s, iflags);
+ ret = fetch_credentials(msg, &puri.user, (iflags==1)?&puri.host:NULL,
+ &stable);
+
+ if(ret>=0)
+ return 1;
+ return ret;
+}
+
/*
* Convert the char* parameters
*/
diff --git a/modules_k/auth_db/authorize.c b/modules_k/auth_db/authorize.c
index f79c70c..4f4a28e 100644
--- a/modules_k/auth_db/authorize.c
+++ b/modules_k/auth_db/authorize.c
@@ -52,6 +52,78 @@
#include "authdb_mod.h"
+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;
+}
+
static inline int get_ha1(struct username* _username, str* _domain,
const str* _table, char* _ha1, db1_res_t** res)
{
diff --git a/modules_k/auth_db/authorize.h b/modules_k/auth_db/authorize.h
index 1cf3caa..12a71f1 100644
--- a/modules_k/auth_db/authorize.h
+++ b/modules_k/auth_db/authorize.h
@@ -52,6 +52,11 @@ int www_authenticate(struct sip_msg* _msg, char* _realm, char*
_table);
int auth_check(struct sip_msg* _m, char* _realm, char* _table, char *_flags);
/*
+ * Fetch credentials for a specific user
+ */
+int fetch_credentials(sip_msg_t *msg, str *user, str* domain, str *table);
+
+/*
* Bind to AUTH_DB API
*/
int bind_auth_db(auth_db_api_t* api);
diff --git a/modules_k/auth_db/doc/auth_db_admin.xml
b/modules_k/auth_db/doc/auth_db_admin.xml
index 8f21b2f..76b13d1 100644
--- a/modules_k/auth_db/doc/auth_db_admin.xml
+++ b/modules_k/auth_db/doc/auth_db_admin.xml
@@ -528,6 +528,58 @@ if (!auth_check("$fd", "subscriber",
"1")) {
</section>
+ <section>
+ <title>
+ <function moreinfo="none">is_subscriber(uri, dbtable,
flags)</function>
+ </title>
+ <para>The function checks if there is a subscriber corresponding to
+ the AoR in uri parameter. It uses same database connection as for
+ authentication functions.
+ </para>
+ <para>
+ In addition, if the subscriber record is found, then the load_credentials
+ attributes are loaded. An use case can be loading the credential attributes
+ for callee.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>uri</emphasis> - a valid SIP URI value to identify
+ the subscriber. The string may contain pseudo variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>dbtable</emphasis> - Table to be used to lookup
+ username and domain from URI (usually subscriber table). The string
+ may contain pseudo variables.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>flags</emphasis> - set of flags to control the
+ behaviour of the function. If it is 1, then the function will
+ use the domain part of the URI to perform the database table search.
+ </para>
+ <para>
+ The parameter may be a pseudo variable.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ This function can be used from ANY_ROUTE.
+ </para>
+ <example>
+ <title>is_subscriber usage</title>
+ <programlisting format="linespecific">
+...
+if (!is_subscriber("$ru", "subscriber", "1")) {
+ # callee is not a local subscriber
+ ...
+}
+...
+</programlisting>
+ </example>
+ </section>
+
</section>
</chapter>