From 1f02da5c8cc9dc711ded015059ae85a5126dd269 Mon Sep 17 00:00:00 2001
From: Stefan Sayer <stefan.sayer@googlemail.com>
Date: Fri, 13 Jan 2017 23:30:01 +0100
Subject: [PATCH] db_reg_agent: add username_with_domain option to use auth
 user with domain part

implements M758
---
 apps/db_reg_agent/DBRegAgent.cpp        | 39 +++++++++++++++++++++++----------
 apps/db_reg_agent/DBRegAgent.h          |  2 ++
 apps/db_reg_agent/etc/db_reg_agent.conf |  5 +++++
 doc/Readme.db_reg_agent.txt             |  7 ++++++
 4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/apps/db_reg_agent/DBRegAgent.cpp b/apps/db_reg_agent/DBRegAgent.cpp
index f004807..c9c3702 100644
--- a/apps/db_reg_agent/DBRegAgent.cpp
+++ b/apps/db_reg_agent/DBRegAgent.cpp
@@ -52,7 +52,9 @@ bool DBRegAgent::delete_failed_deregistrations = false;
 bool DBRegAgent::save_contacts = true;
 bool DBRegAgent::db_read_contact = false;
 string DBRegAgent::contact_hostport;
+bool DBRegAgent::username_with_domain = false;
 string DBRegAgent::outbound_proxy;
+
 bool DBRegAgent::save_auth_replies = false;
 
 unsigned int DBRegAgent::error_retry_interval = 300;
@@ -146,6 +148,9 @@ int DBRegAgent::onLoad()
   db_read_contact =
     cfg.getParameter("db_read_contact", "no") == "yes";
 
+  username_with_domain =
+    cfg.getParameter("username_with_domain", "no") == "yes";
+
   save_auth_replies =
     cfg.getParameter("save_auth_replies", "no") == "yes";
 
@@ -391,15 +396,21 @@ void DBRegAgent::createRegistration(long subscriber_id,
 				    const string& realm,
 				    const string& contact) {
 
+  string auth_user = user;
+  string _user = user;
+  if (username_with_domain && user.find('@')!=string::npos) {
+    _user = user.substr(0, user.find('@'));
+  }
+
   string contact_uri = contact;
   if (contact_uri.empty() && !contact_hostport.empty()) {
-    contact_uri = "sip:"+ user + "@" + contact_hostport;
+    contact_uri = "sip:"+ _user + "@" + contact_hostport;
   }
 
   string handle = AmSession::getNewId();
-  SIPRegistrationInfo reg_info(realm, user,
-			       user, // name
-			       user, // auth_user
+  SIPRegistrationInfo reg_info(realm, _user,
+			       _user, // name
+			       auth_user,
 			       pass,
 			       outbound_proxy, // proxy
 			       contact_uri // contact
@@ -466,27 +477,33 @@ void DBRegAgent::updateRegistration(long subscriber_id,
 				    const string& realm,
 				    const string& contact) {
 
+  string auth_user = user;
+  string _user = user;
+  if (username_with_domain && user.find('@')!=string::npos) {
+    _user = user.substr(0, user.find('@'));
+  }
+
   registrations_mut.lock();
   map<long, AmSIPRegistration*>::iterator it=registrations.find(subscriber_id);
   if (it == registrations.end()) {
     registrations_mut.unlock();
     WARN("updateRegistration - registration %ld %s@%s unknown, creating\n",
-	 subscriber_id, user.c_str(), realm.c_str());
-    createRegistration(subscriber_id, user, pass, realm, contact);
+	 subscriber_id, _user.c_str(), realm.c_str());
+    createRegistration(subscriber_id, _user, pass, realm, contact);
     scheduleRegistration(subscriber_id);
     return;
   }
 
   bool need_reregister = it->second->getInfo().domain != realm
-    || it->second->getInfo().user != user
+    || it->second->getInfo().user != _user
     || it->second->getInfo().pwd  != pass
     || it->second->getInfo().contact != contact;
 
   string old_realm = it->second->getInfo().domain;
   string old_user = it->second->getInfo().user;
-  it->second->setRegistrationInfo(SIPRegistrationInfo(realm, user,
-						      user, // name
-						      user, // auth_user
+  it->second->setRegistrationInfo(SIPRegistrationInfo(realm, _user,
+						      _user, // name
+						      auth_user,
 						      pass,
 						      outbound_proxy,   // proxy
 						      contact)); // contact
@@ -494,7 +511,7 @@ void DBRegAgent::updateRegistration(long subscriber_id,
   if (need_reregister) {
     DBG("user/realm for registration %ld changed (%s@%s -> %s@%s). "
 	"Triggering immediate re-registration\n",
-	subscriber_id, old_user.c_str(), old_realm.c_str(), user.c_str(), realm.c_str());
+	subscriber_id, old_user.c_str(), old_realm.c_str(), _user.c_str(), realm.c_str());
     scheduleRegistration(subscriber_id);
   }
 }
diff --git a/apps/db_reg_agent/DBRegAgent.h b/apps/db_reg_agent/DBRegAgent.h
index 868d999..660b558 100644
--- a/apps/db_reg_agent/DBRegAgent.h
+++ b/apps/db_reg_agent/DBRegAgent.h
@@ -138,6 +138,8 @@ class DBRegAgent
 
   static string contact_hostport;
 
+  static bool username_with_domain;
+
   static string outbound_proxy;
 
   static bool save_auth_replies;
diff --git a/apps/db_reg_agent/etc/db_reg_agent.conf b/apps/db_reg_agent/etc/db_reg_agent.conf
index 54875cb..fd341b5 100644
--- a/apps/db_reg_agent/etc/db_reg_agent.conf
+++ b/apps/db_reg_agent/etc/db_reg_agent.conf
@@ -20,6 +20,11 @@ joined_query="select subscribers.subscriber_id as subscriber_id, subscribers.use
 #example with contact:
 # joined_query="select subscribers.subscriber_id as subscriber_id, subscribers.user as user, subscribers.pass as pass, subscribers.realm as realm, subscribers.contact as contact, registrations.registration_status as registration_status, registrations.expiry as expiry, registrations.last_registration as last_registration from subscribers left join registrations on subscribers.subscriber_id=registrations.subscriber_id;"
 
+# Does the user column (used as auth user) contain the domain?
+# in this case it will be stripped when constructing From/To/contact
+#username_with_domain default: no
+#username_with_domain=yes
+
 # outbound_proxy=<sip_uri>
 # set the outbound proxy to send registrations through
 #
diff --git a/doc/Readme.db_reg_agent.txt b/doc/Readme.db_reg_agent.txt
index 4ccb794..be1bf17 100644
--- a/doc/Readme.db_reg_agent.txt
+++ b/doc/Readme.db_reg_agent.txt
@@ -65,6 +65,13 @@ specified by setting option db_read_contact=yes and providing a contact in the
 subscriber.contact column, and passing it with createRegistration/updateRegistration DI
 function.
 
+Auth username
+-------------
+If the username for authentication needs to include the domain, the option
+username_with_domain should be set to 'yes' and the auth user including the domain
+should be provisioned in the database. SEMS will strip the domain from the value of
+the 'user' column before using it as the user part when constructing To/From/contact.
+
 Database 
 --------
 There may be two separate tables, subscriptions and registrations (status). SEMS inserts
-- 
2.10.1 (Apple Git-78)

