[sr-dev] git:master: auth_db(k): new function is_subscriber(uri, dbtable, flags)

Daniel-Constantin Mierla miconda at gmail.com
Tue Oct 16 21:33:52 CEST 2012


Module: sip-router
Branch: master
Commit: a9f1f9e3cd62d296bcbf4c3618da96d077aacd86
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a9f1f9e3cd62d296bcbf4c3618da96d077aacd86

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at 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>
 




More information about the sr-dev mailing list