diff --git a/src/modules/ims_registrar_scscf/doc/ims_registrar_scscf_admin.xml b/src/modules/ims_registrar_scscf/doc/ims_registrar_scscf_admin.xml index 07aac7d8a73..124c5a14ded 100644 --- a/src/modules/ims_registrar_scscf/doc/ims_registrar_scscf_admin.xml +++ b/src/modules/ims_registrar_scscf/doc/ims_registrar_scscf_admin.xml @@ -438,7 +438,7 @@
<function moreinfo="none">save(async_reply_route, - domain)</function> + domain, mode, flags) The function processes a REGISTER message. It can add, remove or modify usrloc records depending on Contact and Expires HFs in the @@ -462,6 +462,16 @@ domain- Logical domain within registrar. + + + mode- Optional and unused legacy parameter. + + + + flags- Optional parameter. Valid values: + 0x01 - Realm is not used when extracting Private Identity from the + Authorization header. + This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE diff --git a/src/modules/ims_registrar_scscf/ims_registrar_scscf_mod.c b/src/modules/ims_registrar_scscf/ims_registrar_scscf_mod.c index c402ac3985e..8022011e592 100644 --- a/src/modules/ims_registrar_scscf/ims_registrar_scscf_mod.c +++ b/src/modules/ims_registrar_scscf/ims_registrar_scscf_mod.c @@ -133,6 +133,8 @@ static int w_lookup_path_to_contact(struct sip_msg* _m, char* contact_uri); /*! \brief Fixup functions */ static int domain_fixup(void** param, int param_no); static int assign_save_fixup3_async(void** param, int param_no); +static int free_uint_fixup(void** param, int param_no); +static int save_fixup3(void** param, int param_no); static int unreg_fixup(void** param, int param_no); static int fetchc_fixup(void** param, int param_no); /*! \brief Functions */ @@ -215,6 +217,8 @@ static pv_export_t mod_pvs[] = { */ static cmd_export_t cmds[] = { {"save", (cmd_function) w_save, 2, assign_save_fixup3_async, 0, REQUEST_ROUTE | ONREPLY_ROUTE}, + {"save", (cmd_function) w_save, 3, assign_save_fixup3_async, 0, REQUEST_ROUTE | ONREPLY_ROUTE}, + {"save", (cmd_function) w_save, 4, save_fixup3, free_uint_fixup, REQUEST_ROUTE | ONREPLY_ROUTE}, {"lookup", (cmd_function) w_lookup, 1, domain_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {"lookup", (cmd_function) w_lookup_ue_type, 2, domain_fixup, 0, REQUEST_ROUTE | FAILURE_ROUTE}, {"lookup_path_to_contact", (cmd_function) w_lookup_path_to_contact, 1, fixup_var_str_12, 0, REQUEST_ROUTE}, @@ -620,7 +624,11 @@ AAAMessage* callback_cdp_request(AAAMessage *request, void *param) { * Wrapper to save(location) */ static int w_save(struct sip_msg* _m, char* _route, char* _d, char* mode, char* _cflags) { - return save(_m, _d, _route); + if(_cflags){ + return save(_m, _d, _route, ((int)(*_cflags))); + } + + return save(_m, _d, _route, 0); } static int w_assign_server_unreg(struct sip_msg* _m, char* _route, char* _d, char* _direction) { @@ -701,6 +709,68 @@ static int assign_save_fixup3_async(void** param, int param_no) { return 0; } +static int unit_fixup(void** param, int param_no) +{ + str s; + unsigned int* num; + + if(*param){ + num = (unsigned int*)pkg_malloc(sizeof(unsigned int)); + *num = 0; + + s.s = *param; + s.len = strlen(s.s); + + if (likely(str2int(&s, num) == 0)) { + *param = (void*)(long)num; + }else{ + LM_ERR("failed to convert to int\n"); + pkg_free(num); + return E_UNSPEC; + } + }else{ + return E_UNSPEC; + } + + return 0; +} + +static int free_uint_fixup(void** param, int param_no) +{ + if(*param && param_no == 2){ + pkg_free(*param); + *param = 0; + } + return 0; +} + +static int save_fixup3(void** param, int param_no) { + if (strlen((char*) *param) <= 0) { + LM_ERR("empty parameter %d not allowed\n", param_no); + return -1; + } + + if (param_no == 1) { //route name - static or dynamic string (config vars) + if (fixup_spve_null(param, param_no) < 0) + return -1; + return 0; + } else if (param_no == 2) { + udomain_t* d; + + if (ul.register_udomain((char*) *param, &d) < 0) { + LM_ERR("Error doing fixup on save"); + return -1; + } + *param = (void*) d; + } else if (param_no == 3) { + return 0; + } else if (param_no == 4) { + return unit_fixup(param, param_no); + } + + return 0; +} + /*! \brief * Convert char* parameter to udomain_t* pointer * Convert char* parameter to pv_elem_t* pointer diff --git a/src/modules/ims_registrar_scscf/save.c b/src/modules/ims_registrar_scscf/save.c index 877d5074998..e625cb25e33 100644 --- a/src/modules/ims_registrar_scscf/save.c +++ b/src/modules/ims_registrar_scscf/save.c @@ -84,6 +84,8 @@ extern int store_data_on_dereg; /**< should we store SAR user data on de-registr extern int ue_unsubscribe_on_dereg; extern int user_data_always; +#define DO_NOT_USE_REALM_FOR_PRIVATE_IDENTITY 0x01 + /* \brief * Return randomized expires between expires-range% and expires. * RFC allows only value less or equal to the one provided by UAC. @@ -1276,13 +1278,13 @@ int assign_server_unreg(struct sip_msg* _m, char* str1, str* direction, char* ro */ //int save(struct sip_msg* msg, udomain_t* _d) { -int save(struct sip_msg* msg, char* str1, char *route) { +int save(struct sip_msg* msg, char* str1, char *route, int _cflags) { int expires; int require_user_data = 0; int data_available; contact_t* c; int st; - str public_identity, private_identity, realm; + str public_identity, private_identity, realm={0,0}; int sar_assignment_type = AVP_IMS_SAR_NO_ASSIGNMENT; str route_name; @@ -1342,12 +1344,15 @@ int save(struct sip_msg* msg, char* str1, char *route) { rerrno = R_SAR_FAILED; goto error; } - realm = cscf_get_realm_from_uri(public_identity); - if (realm.len <= 0 || !realm.s) { - LM_ERR("can't get realm\n"); - rerrno = R_SAR_FAILED; - goto error; - } + + if (!(_cflags & DO_NOT_USE_REALM_FOR_PRIVATE_IDENTITY)) { + realm = cscf_get_realm_from_uri(public_identity); + if (realm.len <= 0 || !realm.s) { + LM_ERR("can't get realm\n"); + rerrno = R_SAR_FAILED; + goto error; + } + } private_identity = cscf_get_private_identity(msg, realm); if (private_identity.len <= 0 || !private_identity.s) { diff --git a/src/modules/ims_registrar_scscf/save.h b/src/modules/ims_registrar_scscf/save.h index dd2ee38f932..df6e14b9ba1 100644 --- a/src/modules/ims_registrar_scscf/save.h +++ b/src/modules/ims_registrar_scscf/save.h @@ -58,7 +58,7 @@ */ int assign_server_unreg(struct sip_msg* _m, char* str1, str* direction, char* route); -int save(struct sip_msg* msg, char* str1, char* route); +int save(struct sip_msg* msg, char* str1, char* route, int _cflags); int unregister(struct sip_msg* _m, char* _d, char* _uri);