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 <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
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>
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to