diff --git a/daemon/src/client/presencemanager.cpp b/daemon/src/client/presencemanager.cpp
index 01784e7d56b37c87d7995106fe83c55c754195a9..ecf79d52bf5e6f077e8809a84e1ae28c64937281 100644
--- a/daemon/src/client/presencemanager.cpp
+++ b/daemon/src/client/presencemanager.cpp
@@ -61,8 +61,15 @@ PresenceManager::subscribeBuddy(const std::string& accountID, const std::string&
     if (!sipaccount)
         ERROR("Could not find account %s",accountID.c_str());
     else{
-        DEBUG("%subscribePresence (acc:%s, buddy:%s)",flag? "S":"Uns", accountID.c_str(), uri.c_str());
-        sipaccount->getPresence()->subscribeClient(uri,flag);
+        SIPPresence *pres = sipaccount->getPresence();
+        if (pres)
+        {
+            if((pres->isEnabled()) && pres->isSupported(PRESENCE_FUNCTION_SUBSCRIBE))
+            {
+                DEBUG("%subscribePresence (acc:%s, buddy:%s)",flag? "S":"Uns", accountID.c_str(), uri.c_str());
+                pres->subscribeClient(uri,flag);
+            }
+        }
     }
 }
 
@@ -77,8 +84,15 @@ PresenceManager::publish(const std::string& accountID, const bool& status, const
     if (!sipaccount)
         ERROR("Could not find account %s.",accountID.c_str());
     else{
-        DEBUG("Send Presence (acc:%s, status %s).",accountID.c_str(),status? "online":"offline");
-        sipaccount->getPresence()->sendPresence(status, note);
+        SIPPresence *pres = sipaccount->getPresence();
+        if (pres)
+        {
+            if((pres->isEnabled()) && pres->isSupported(PRESENCE_FUNCTION_PUBLISH))
+            {
+                DEBUG("Send Presence (acc:%s, status %s).",accountID.c_str(),status? "online":"offline");
+                pres->sendPresence(status, note);
+            }
+        }
     }
 }
 
diff --git a/daemon/src/sip/pres_sub_client.cpp b/daemon/src/sip/pres_sub_client.cpp
index 63c769a92e92083a46b48f0afeaaa659a80f8ecd..70848a14628d928f22e8ec0936a9e408c4736eee 100644
--- a/daemon/src/sip/pres_sub_client.cpp
+++ b/daemon/src/sip/pres_sub_client.cpp
@@ -95,6 +95,8 @@ PresSubClient::pres_client_evsub_on_state(pjsip_evsub *sub, pjsip_event *event)
                 pres_client->getURI().c_str(),
                 PJ_TRUE);
 
+        pres->getAccount()->supportPresence(PRESENCE_FUNCTION_SUBSCRIBE, PJ_TRUE);
+
     } else if (state == PJSIP_EVSUB_STATE_TERMINATED) {
         int resub_delay = -1;
         pj_strdup_with_null(pres_client->pool_, &pres_client->term_reason_, pjsip_evsub_get_termination_reason(sub));
@@ -166,12 +168,8 @@ PresSubClient::pres_client_evsub_on_state(pjsip_evsub *sub, pjsip_event *event)
                 std::string account_host = std::string(pj_gethostname()->ptr, pj_gethostname()->slen);
                 std::string sub_host = sip_utils::getHostFromUri(pres_client->getURI());
 
-                if((!subscribe_allowed) && (account_host == sub_host)
-                        && pres_client->getPresence()->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)){ // avoid mutiple details reload
+                if((!subscribe_allowed) && (account_host == sub_host))
                     pres_client->getPresence()->getAccount()->supportPresence(PRESENCE_FUNCTION_SUBSCRIBE, PJ_FALSE);
-                    Manager::instance().saveConfig();
-                    Manager::instance().getClient()->getConfigurationManager()->accountsChanged();
-                }
 
             } else if (pjsip_method_cmp(&tsx->method, &pjsip_notify_method) == 0) {
                 if (pres_client->isTermReason("deactivated") || pres_client->isTermReason("timeout")) {
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 4db0dc6f82b9cd3cb5c14d9d33217c35b893a7f5..c829111df73c7ff39859d140c211ad3085aca8bb 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -45,6 +45,7 @@
 
 #ifdef SFL_PRESENCE
 #include "sippresence.h"
+#include "client/configurationmanager.h"
 #endif
 
 #include <unistd.h>
@@ -505,6 +506,12 @@ void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
     std::string pres;
     mapNode.getValue(PRESENCE_ENABLED_KEY, &pres);
     enablePresence(pres == Conf::TRUE_STR);
+    mapNode.getValue(PRESENCE_PUBLISH_SUPPORTED_KEY, &pres);
+    if (presence_)
+        presence_->support(PRESENCE_FUNCTION_PUBLISH, pres == Conf::TRUE_STR);
+    mapNode.getValue(PRESENCE_SUBSCRIBE_SUPPORTED_KEY, &pres);
+    if (presence_)
+        presence_->support(PRESENCE_FUNCTION_SUBSCRIBE, pres == Conf::TRUE_STR);
 #endif
 
     std::string dtmfType;
@@ -888,6 +895,7 @@ void SIPAccount::registerVoIPLink()
 
 #ifdef SFL_PRESENCE
     getPresence()->subscribeClient(getFromUri(), true); //self presence subscription
+    getPresence()->sendPresence(true,""); // try to publish whatever the status is.
 #endif
 }
 
@@ -1507,32 +1515,38 @@ SIPPresence * SIPAccount::getPresence() const
 void
 SIPAccount::enablePresence(const bool& enabled)
 {
-    DEBUG("Presence enable for :%s : %s.",
+    DEBUG("Presence enable for %s : %s.",
             accountID_.c_str(),
             enabled? Conf::TRUE_STR : Conf::FALSE_STR);
 
-    if (presence_){
+    if (presence_)
         presence_->enable(enabled);
-        if(enabled)// try to publish and subscribe by default when presence is enabled
-        {
-            supportPresence(PRESENCE_FUNCTION_PUBLISH, enabled);
-            supportPresence(PRESENCE_FUNCTION_SUBSCRIBE, enabled);
-        }
-    }
 }
 
 /**
- *  Enable the presence function (PUBLISH/SUBSCRIBE)
+ *  Set the presence (PUBLISH/SUBSCRIBE) support flags
+ *  and process the change.
  */
 void
 SIPAccount::supportPresence(int function, const bool& enabled)
 {
-    DEBUG("Presence support for :%s (%s: %s).",
+    if(getPresence()->isSupported(function) == enabled)
+        return;
+
+    DEBUG("Presence support for %s (%s: %s).",
             accountID_.c_str(),
             (function==PRESENCE_FUNCTION_PUBLISH)? "publish" : "subscribe",
             enabled? Conf::TRUE_STR : Conf::FALSE_STR);
     if (presence_)
         presence_->support(function, enabled);
+
+    // force presence to disable when nothing is supported
+    if(!(getPresence()->isSupported(PRESENCE_FUNCTION_PUBLISH)) &&
+       !(getPresence()->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)))
+        enablePresence(false);
+
+    Manager::instance().saveConfig();
+    Manager::instance().getClient()->getConfigurationManager()->accountsChanged();
 }
 #endif
 
diff --git a/daemon/src/sip/sippresence.cpp b/daemon/src/sip/sippresence.cpp
index f028afdf0f00cd610097150e5fea48190a5865cf..6e8262faf1b7622c64565ec8cf14a7dc3b6c4463 100644
--- a/daemon/src/sip/sippresence.cpp
+++ b/daemon/src/sip/sippresence.cpp
@@ -180,8 +180,8 @@ void SIPPresence::sendPresence(bool status, const std::string &note)
 {
     updateStatus(status, note);
 
-    if ((not publish_supported_) or (not enabled_))
-        return;
+    //if ((not publish_supported_) or (not enabled_))
+    //    return;
 
     if (acc_->isIP2IP())
         notifyPresSubServer(); // to each subscribers
@@ -210,14 +210,15 @@ void SIPPresence::reportPresSubClientNotification(const std::string& uri, pjsip_
 
 void SIPPresence::subscribeClient(const std::string& uri, bool flag)
 {
-    std::string account_host = std::string(pj_gethostname()->ptr, pj_gethostname()->slen);
-    std::string sub_host = sip_utils::getHostFromUri(uri);
-
     /* if an account has a server that doesn't support SUBSCRIBE, it's still possible
      * to subscribe to someone on another server */
+    /*
+    std::string account_host = std::string(pj_gethostname()->ptr, pj_gethostname()->slen);
+    std::string sub_host = sip_utils::getHostFromUri(uri);
     if (((not subscribe_supported_) && (account_host == sub_host))
             or (not enabled_))
         return;
+    */
 
     /* Check if the buddy was already subscribed */
     for (const auto & c : sub_client_list_) {
@@ -400,8 +401,6 @@ SIPPresence::publish_cb(struct pjsip_publishc_cbparam *param)
                     "Publish not supported.");
 
             pres->getAccount()->supportPresence(PRESENCE_FUNCTION_PUBLISH, PJ_FALSE);
-            Manager::instance().saveConfig();
-            Manager::instance().getClient()->getConfigurationManager()->accountsChanged();
         }
 
     } else {
@@ -412,6 +411,8 @@ SIPPresence::publish_cb(struct pjsip_publishc_cbparam *param)
             pjsip_publishc_destroy(param->pubc);
             pres->publish_sess_ = NULL;
         }
+
+        pres->getAccount()->supportPresence(PRESENCE_FUNCTION_PUBLISH, PJ_TRUE);
     }
 }