Module: sip-router Branch: master Commit: a9f1f9e3cd62d296bcbf4c3618da96d077aacd86 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a9f1f9e3...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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>
16 okt 2012 kl. 21:33 skrev Daniel-Constantin Mierla miconda@gmail.com:
s_subscriber(uri, dbtable, flags)
- check if URI corresponds to a subscriber record in dbtable and load
credentials for it
I think this is a good function that I immediately see a need for. Makes perfect sense.
Thank you!
/O