From: Maxim Mamontov <faust.madf@gmail.com>
Date: Fri, 26 Jul 2013 16:24:10 +0000 (+0300)
Subject: Check that IP is not in use before changing.
X-Git-Tag: 2.409~358
X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/4f1aca7dfb6adf867713ad48e14ad79080e13cfa?ds=sidebyside

Check that IP is not in use before changing.
---

diff --git a/include/stg/user_ips.h b/include/stg/user_ips.h
index e68190c5..264b5896 100644
--- a/include/stg/user_ips.h
+++ b/include/stg/user_ips.h
@@ -70,7 +70,7 @@ public:
     std::string GetIpStr() const;
     bool IsIPInIPS(uint32_t ip) const;
     bool OnlyOneIP() const;
-    int  Count() const;
+    size_t  Count() const;
     void Add(const IP_MASK &im);
     void Erase();
 
@@ -129,9 +129,9 @@ return s.str();
 }
 //-----------------------------------------------------------------------------
 inline
-int USER_IPS::Count() const
+size_t USER_IPS::Count() const
 {
-return static_cast<int>(ips.size());
+return ips.size();
 }
 //-----------------------------------------------------------------------------
 inline
diff --git a/include/stg/users.h b/include/stg/users.h
index 2ba23833..b97a9be5 100644
--- a/include/stg/users.h
+++ b/include/stg/users.h
@@ -53,6 +53,7 @@ public:
 
     virtual int  FindByIPIdx(uint32_t ip, USER_PTR * user) const = 0;
     virtual bool IsIPInIndex(uint32_t ip) const = 0;
+    virtual bool IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const = 0;
 
     virtual int  OpenSearch() = 0;
     virtual int  SearchNext(int handle, USER_PTR * u) = 0;
diff --git a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
index 665a04f4..89c41587 100644
--- a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
+++ b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
@@ -161,6 +161,18 @@ if ((it = structVal.find("ips")) != structVal.end())
     {
     USER_IPS ips;
     ips = StrToIPS(xmlrpc_c::value_string(it->second));
+
+    for (size_t i = 0; i < ips.Count(); ++i)
+        {
+        CONST_USER_PTR user;
+        uint32_t ip = ips[i].ip;
+        if (users.IsIPInUse(ip, login, &user))
+            {
+            printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+            return true;
+            }
+        }
+
     if (!ptr->GetProperty().ips.Set(ips,
                                 admin,
                                 login,
diff --git a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.h b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.h
index 83f70b5c..4e1dd796 100644
--- a/projects/stargazer/plugins/configuration/rpcconfig/user_helper.h
+++ b/projects/stargazer/plugins/configuration/rpcconfig/user_helper.h
@@ -14,8 +14,9 @@ class TARIFFS;
 class USER_HELPER
 {
 public:
-    USER_HELPER(USER_PTR & p)
-        : ptr(p)
+    USER_HELPER(USER_PTR & p, USERS & us)
+        : ptr(p),
+          users(us)
     {
     }
 
@@ -28,6 +29,7 @@ public:
                      TARIFFS * tariffs);
 private:
     USER_PTR & ptr;
+    USERS & users;
 };
 
 #endif
diff --git a/projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp b/projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
index 5b39cf1e..9eabced6 100644
--- a/projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
+++ b/projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
@@ -39,7 +39,7 @@ if (users->FindByName(login, &u))
     return;
     }
 
-USER_HELPER uhelper(u);
+USER_HELPER uhelper(u, *users);
 
 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
     {
@@ -172,7 +172,7 @@ while (1)
 
     xmlrpc_c::value info;
 
-    USER_HELPER uhelper(u);
+    USER_HELPER uhelper(u, *users);
 
     uhelper.GetUserInfo(&info, hidePassword);
 
@@ -216,7 +216,7 @@ if (users->FindByName(login, &u))
     return;
     }
 
-USER_HELPER uhelper(u);
+USER_HELPER uhelper(u, *users);
 
 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
     {
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser.cpp b/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
index 1f7757d2..8e11a157 100644
--- a/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
+++ b/projects/stargazer/plugins/configuration/sgconfig/parser.cpp
@@ -1025,9 +1025,23 @@ 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());
+    res = -1;
     return -1;
     }
 
+for (size_t i = 0; i < ucr->ips.const_data().Count(); ++i)
+    {
+    CONST_USER_PTR user;
+    uint32_t ip = ucr->ips.const_data().operator[](i).ip;
+    if (users->IsIPInUse(ip, login, &user))
+        {
+        printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+        GetStgLogger()("%s trying to assign an IP %s to '%s' that is currently in use by '%s'", currAdmin->GetLogStr().c_str(), inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+        res = -1;
+        return -1;
+        }
+    }
+
 if (!ucr->ips.res_empty())
     if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
         res = -1;
diff --git a/projects/stargazer/plugins/store/firebird/firebird_store_users.cpp b/projects/stargazer/plugins/store/firebird/firebird_store_users.cpp
index 8b21907e..e48fd0d8 100644
--- a/projects/stargazer/plugins/store/firebird/firebird_store_users.cpp
+++ b/projects/stargazer/plugins/store/firebird/firebird_store_users.cpp
@@ -337,7 +337,7 @@ try
     st->Execute();
 
     st->Prepare("insert into tb_allowed_ip (fk_user, ip, mask) values (?, ?, ?)");
-    for(i = 0; i < conf.ips.Count(); i++)
+    for(size_t i = 0; i < conf.ips.Count(); i++)
         {
         st->Set(1, uid);
         st->Set(2, (int32_t)conf.ips[i].ip);
diff --git a/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp b/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp
index 4cd64418..0722cc4c 100644
--- a/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp
+++ b/projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp
@@ -1525,7 +1525,7 @@ if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 PQclear(result);
 
-for (int i = 0; i < ips.Count(); ++i)
+for (size_t i = 0; i < ips.Count(); ++i)
     {
     std::ostringstream query;
     query << "INSERT INTO tb_allowed_ip "
diff --git a/projects/stargazer/users_impl.cpp b/projects/stargazer/users_impl.cpp
index 17d1e4f7..dfdc8634 100644
--- a/projects/stargazer/users_impl.cpp
+++ b/projects/stargazer/users_impl.cpp
@@ -695,6 +695,24 @@ std::map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
 return it != ipIndex.end();
 }
 //-----------------------------------------------------------------------------
+bool USERS_IMPL::IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+std::list<USER_IMPL>::const_iterator iter;
+iter = users.begin();
+while (iter != users.end())
+    {
+    if (iter->GetLogin() != login && iter->GetProperty().ips.Get().IsIPInIPS(ip))
+        {
+        if (user != NULL)
+            *user = &(*iter);
+        return true;
+        }
+    ++iter;
+    }
+return false;
+}
+//-----------------------------------------------------------------------------
 void USERS_IMPL::AddNotifierUserAdd(NOTIFIER_BASE<USER_PTR> * n)
 {
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
diff --git a/projects/stargazer/users_impl.h b/projects/stargazer/users_impl.h
index 69f3fbae..0c2af78d 100644
--- a/projects/stargazer/users_impl.h
+++ b/projects/stargazer/users_impl.h
@@ -103,6 +103,7 @@ public:
     int             FindByIPIdx(uint32_t ip, USER_PTR * user) const;
     int             FindByIPIdx(uint32_t ip, USER_IMPL ** user) const;
     bool            IsIPInIndex(uint32_t ip) const;
+    bool            IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const;
 
     int             OpenSearch();
     int             SearchNext(int handler, USER_PTR * user);