From f8054f164b10a7b42a5250856ec83dca71ad3545 Mon Sep 17 00:00:00 2001
From: Maxim Mamontov <faust.madf@gmail.com>
Date: Sat, 3 Mar 2012 23:42:04 +0200
Subject: [PATCH] Validate data for a forbidden combination of alwaysOnline and
 ips

---
 .../configuration/rpcconfig/user_helper.cpp   | 58 +++++++++++++------
 .../plugins/configuration/sgconfig/parser.cpp | 31 ++++++++--
 2 files changed, 66 insertions(+), 23 deletions(-)

diff --git a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
index fceaa3ab..ce339573 100644
--- a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
+++ b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
@@ -136,15 +136,24 @@ std::map<std::string, xmlrpc_c::value> structVal(
 
 std::map<std::string, xmlrpc_c::value>::iterator it;
 
-if ((it = structVal.find("password")) != structVal.end())
+bool check = false;
+bool alwaysOnline = ptr->GetProperty().alwaysOnline;
+if ((it = structVal.find("aonline")) != structVal.end())
     {
-    std::string value(xmlrpc_c::value_string(it->second));
-    if (ptr->GetProperty().password.Get() != value)
-        if (!ptr->GetProperty().password.Set(value,
-                                         admin,
-                                         login,
-                                         &store))
-            return true;
+    check = true;
+    alwaysOnline = xmlrpc_c::value_boolean(it->second);
+    }
+bool onlyOneIP = ptr->GetProperty().ips.ConstData().OnlyOneIP();
+if ((it = structVal.find("ips")) != structVal.end())
+    {
+    check = true;
+    onlyOneIP = StrToIPS(xmlrpc_c::value_string(it->second)).OnlyOneIP();
+    }
+
+if (check && alwaysOnline && !onlyOneIP)
+    {
+    printfd(__FILE__, "Requested change leads to a forbidden state: AlwaysOnline with multiple IP's\n");
+    return true;
     }
 
 if ((it = structVal.find("ips")) != structVal.end())
@@ -158,6 +167,28 @@ if ((it = structVal.find("ips")) != structVal.end())
         return true;
     }
 
+if ((it = structVal.find("aonline")) != structVal.end())
+    {
+    bool value(xmlrpc_c::value_boolean(it->second));
+    if (ptr->GetProperty().alwaysOnline.Get() != value)
+        if (!ptr->GetProperty().alwaysOnline.Set(value,
+                                             admin,
+                                             login,
+                                             &store))
+            return true;
+    }
+
+if ((it = structVal.find("password")) != structVal.end())
+    {
+    std::string value(xmlrpc_c::value_string(it->second));
+    if (ptr->GetProperty().password.Get() != value)
+        if (!ptr->GetProperty().password.Set(value,
+                                         admin,
+                                         login,
+                                         &store))
+            return true;
+    }
+
 if ((it = structVal.find("address")) != structVal.end())
     {
     std::string value(IconvString(xmlrpc_c::value_string(it->second), "UTF-8", "KOI8-RU"));
@@ -257,17 +288,6 @@ if ((it = structVal.find("passive")) != structVal.end())
             return true;
     }
 
-if ((it = structVal.find("aonline")) != structVal.end())
-    {
-    bool value(xmlrpc_c::value_boolean(it->second));
-    if (ptr->GetProperty().alwaysOnline.Get() != value)
-        if (!ptr->GetProperty().alwaysOnline.Set(value,
-                                             admin,
-                                             login,
-                                             &store))
-            return true;
-    }
-
 if ((it = structVal.find("disableddetailstat")) != structVal.end())
     {
     bool value(xmlrpc_c::value_boolean(it->second));
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser.cpp b/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
index c63edfe0..bfe2f7bc 100644
--- a/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
+++ b/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
@@ -13,6 +13,7 @@
 #include "stg/tariffs.h"
 #include "stg/user_property.h"
 #include "stg/settings.h"
+#include "stg/logger.h"
 #include "parser.h"
 
 #define  UNAME_LEN      (256)
@@ -996,6 +997,7 @@ switch (res)
 //-----------------------------------------------------------------------------
 int PARSER_CHG_USER::AplayChanges()
 {
+printfd(__FILE__, "PARSER_CHG_USER::AplayChanges()\n");
 USER_PTR u;
 
 res = 0;
@@ -1005,12 +1007,29 @@ if (users->FindByName(login, &u))
     return -1;
     }
 
+bool check = false;
+bool alwaysOnline = u->GetProperty().alwaysOnline;
+if (!ucr->alwaysOnline.res_empty())
+    {
+    check = true;
+    alwaysOnline = ucr->alwaysOnline.const_data();
+    }
+bool onlyOneIP = u->GetProperty().ips.ConstData().OnlyOneIP();
 if (!ucr->ips.res_empty())
-    if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
-        res = -1;
+    {
+    check = true;
+    onlyOneIP = ucr->ips.const_data().OnlyOneIP();
+    }
 
-if (!ucr->address.res_empty())
-    if (!u->GetProperty().address.Set(ucr->address.const_data(), currAdmin, login, store))
+if (check && alwaysOnline && !onlyOneIP)
+    {
+    printfd(__FILE__, "Requested change leads to a forbidden state: AlwaysOnline with multiple IP's\n");
+    GetStgLogger()("%s Requested change leads to a forbidden state: AlwaysOnline with multiple IP's", currAdmin->GetLogStr().c_str());
+    return -1;
+    }
+
+if (!ucr->ips.res_empty())
+    if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
         res = -1;
 
 if (!ucr->alwaysOnline.res_empty())
@@ -1018,6 +1037,10 @@ if (!ucr->alwaysOnline.res_empty())
                                       currAdmin, login, store))
         res = -1;
 
+if (!ucr->address.res_empty())
+    if (!u->GetProperty().address.Set(ucr->address.const_data(), currAdmin, login, store))
+        res = -1;
+
 if (!ucr->creditExpire.res_empty())
     if (!u->GetProperty().creditExpire.Set(ucr->creditExpire.const_data(),
                                       currAdmin, login, store))
-- 
2.44.2