[mapguide-commits] r9201 - in sandbox/jng/cmdline: Common/Foundation/System Server/src/Core

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Jun 7 06:51:00 PDT 2017


Author: jng
Date: 2017-06-07 06:51:00 -0700 (Wed, 07 Jun 2017)
New Revision: 9201

Modified:
   sandbox/jng/cmdline/Common/Foundation/System/Resources.cpp
   sandbox/jng/cmdline/Common/Foundation/System/Resources.h
   sandbox/jng/cmdline/Server/src/Core/Server.cpp
   sandbox/jng/cmdline/Server/src/Core/Server.h
   sandbox/jng/cmdline/Server/src/Core/main.cpp
Log:
Add support for a "setpwd" command-line operation. The use case for this feature is to change the passwords for built-in users in a headless fashion before starting up the mgserver/daemon proper. It also addresses #581. 

This is important for security when MapGuide is used within a container (eg. Docker) or an automated environment provisioning context where being able to programmatically change passwords for built-in users from their designated defaults is currently cumbersome as the Site Administrator requires manual operation and the only known way to programmatically change the password is through MgSite, but using this API requires a running mgserver and thus requires coordinating the server to be online first before being able to use this particular API.

A small side-effect of changing passwords using this approach is that it will blank out other properties of the user, such as its user name (not related to its user id) and description. To preserve such information, we would have to first call EnumerateUsers and manually parse the XML response for the matching user and call UpdateUser with the new password and the preserved user information. This information is inconsequential in the grand scheme so having it blanked out through this setpwd command is deemed by me to be an acceptable trade-off for simplicity of the implementation.

Modified: sandbox/jng/cmdline/Common/Foundation/System/Resources.cpp
===================================================================
--- sandbox/jng/cmdline/Common/Foundation/System/Resources.cpp	2017-06-05 15:10:47 UTC (rev 9200)
+++ sandbox/jng/cmdline/Common/Foundation/System/Resources.cpp	2017-06-07 13:51:00 UTC (rev 9201)
@@ -130,6 +130,11 @@
 const STRING MgResources::ServerCmdLoadPackageDescription = L"  loadpackage <package file path>\n"\
                                                             L"      Loads the package at the given path.\n\n";
 
+const STRING MgResources::ServerCmdSetPwd               = L"setpwd"; // Do not translate
+const STRING MgResources::ServerCmdSetPwdInfo           = L"Setting the password for the specified user\n\n";
+const STRING MgResources::ServerCmdSetPwdDescription    = L"  setpwd <mapguide_username> <password>\n"\
+                                                          L"      Sets the password for the specified username.\n\n";
+
 const STRING MgResources::ServerCmdUnrecognizedInfo     = L"Unrecognized option: \"%s\".\n";
 
 const STRING MgResources::ServerCmdInstallFailed        = L"Failed to install the server service: \"%s\".\nError: %s";

Modified: sandbox/jng/cmdline/Common/Foundation/System/Resources.h
===================================================================
--- sandbox/jng/cmdline/Common/Foundation/System/Resources.h	2017-06-05 15:10:47 UTC (rev 9200)
+++ sandbox/jng/cmdline/Common/Foundation/System/Resources.h	2017-06-07 13:51:00 UTC (rev 9201)
@@ -219,6 +219,9 @@
     static const STRING ServerCmdLoadPackage;
     static const STRING ServerCmdLoadPackageInfo;
     static const STRING ServerCmdLoadPackageDescription;
+    static const STRING ServerCmdSetPwd;
+    static const STRING ServerCmdSetPwdInfo;
+    static const STRING ServerCmdSetPwdDescription;
     static const STRING ServerCmdUninstall;
     static const STRING ServerCmdUninstallInfo;
     static const STRING ServerCmdUninstallDescription;

Modified: sandbox/jng/cmdline/Server/src/Core/Server.cpp
===================================================================
--- sandbox/jng/cmdline/Server/src/Core/Server.cpp	2017-06-05 15:10:47 UTC (rev 9200)
+++ sandbox/jng/cmdline/Server/src/Core/Server.cpp	2017-06-07 13:51:00 UTC (rev 9201)
@@ -31,6 +31,8 @@
 #include "ServerFeatureTransactionPool.h"
 #include "ServerResourceService.h"
 
+#include "ServerSiteService.h"
+
 #include "Stylizer.h"
 #include "Bounds.h"
 #include "Renderer.h"
@@ -80,6 +82,7 @@
     m_bTestMode = false;
     m_bTestFdo = false;
     m_bLoadPackage = false;
+    m_bSetPwd = false;
 
 #ifdef _DEBUG
     m_nClientRequestLimit = -1;   // -1 = No limit. DEBUG ONLY
@@ -269,7 +272,22 @@
                 m_strPackageFilePath = L"";
             }
         }
+        else if (ACE_OS::strcasecmp(parameter, MG_WCHAR_TO_TCHAR(MgResources::ServerCmdSetPwd)) == 0)
+        {
+            // Password changing mode
+            m_bSetPwd = true;
 
+            m_strUser = L"";
+            m_strPassword = L"";
+            if (argc > 2)
+            {
+                m_strUser = MG_TCHAR_TO_WCHAR(argv[2]);
+            }
+            if (argc > 3)
+            {
+                m_strPassword = MG_TCHAR_TO_WCHAR(argv[3]);
+            }
+        }
         delete[] parameter;
     }
 }
@@ -554,6 +572,69 @@
             nResult = -1;
         }
     }
+    else if (m_bSetPwd)
+    {
+        try
+        {
+            // Let the site manager know that the check servers background thread needs to stop
+            MgSiteManager* siteManager = MgSiteManager::GetInstance();
+            siteManager->StopCheckServersThread();
+
+            // Set the user information for the current thread to be administrator.
+            //
+            // This is server-local, so no authentication is done. The MgServiceManager just needs to know the user when
+            // services are requested.
+            Ptr<MgUserInformation> adminUserInfo = new MgUserInformation(MgUser::Administrator, L"");
+            MgUserInformation::SetCurrentUserInfo(adminUserInfo);
+
+            MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+            Ptr<MgServerSiteService> pService = dynamic_cast<MgServerSiteService*>(serviceManager->RequestService(MgServiceType::SiteService));
+            if (NULL == (MgServerSiteService*)pService)
+            {
+                throw new MgServiceNotAvailableException(L"MgServer.svc", __LINE__, __WFILE__, NULL, L"", NULL);
+            }
+
+            if (m_strUser.empty()) //Need to have passed username
+            {
+                ACE_DEBUG((LM_INFO, ACE_TEXT("No username specified.\n")));
+                nResult = -1;
+            }
+            else if (m_strPassword.empty()) //Need to have passed pwd
+            {
+                ACE_DEBUG((LM_INFO, ACE_TEXT("No password specified.\n")));
+                nResult = -1;
+            }
+            else
+            {
+                //Anonymous has no password, so there's nothing to set
+                if (m_strUser == MgUser::Anonymous)
+                {
+                    ACE_DEBUG((LM_INFO, ACE_TEXT("Cannot change password for Anonymous.\n")));
+                    nResult = -1;
+                }
+                else
+                {
+                    ACE_DEBUG((LM_INFO, ACE_TEXT("Changing password for user: %W...\n\n"), m_strUser.c_str()));
+                    pService->UpdateUser(m_strUser, L"", L"", m_strPassword, L"");
+                    ACE_DEBUG((LM_INFO, ACE_TEXT("Password changed.\n")));
+                }
+            }
+        }
+        catch (MgException* e)
+        {
+            ACE_DEBUG((LM_ERROR, ACE_TEXT("Unable to load the specified package.\n")));
+            ACE_DEBUG((LM_ERROR, ACE_TEXT("%W\n"), e->GetStackTrace(pServerManager->GetDefaultMessageLocale()).c_str()));
+            SAFE_RELEASE(e);
+
+            nResult = -1;
+        }
+        catch (...)
+        {
+            ACE_DEBUG((LM_ERROR, ACE_TEXT("Unable to load the specified package.\n")));
+
+            nResult = -1;
+        }
+    }
     else
     {
         try

Modified: sandbox/jng/cmdline/Server/src/Core/Server.h
===================================================================
--- sandbox/jng/cmdline/Server/src/Core/Server.h	2017-06-05 15:10:47 UTC (rev 9200)
+++ sandbox/jng/cmdline/Server/src/Core/Server.h	2017-06-07 13:51:00 UTC (rev 9201)
@@ -121,6 +121,9 @@
     ///////////////////////////////////////////////////////
     /// Member data
 private:
+    bool m_bSetPwd;
+    STRING m_strUser;
+    STRING m_strPassword;
     bool m_bLoadPackage;
     STRING m_strPackageFilePath;
     bool m_bTestMode;

Modified: sandbox/jng/cmdline/Server/src/Core/main.cpp
===================================================================
--- sandbox/jng/cmdline/Server/src/Core/main.cpp	2017-06-05 15:10:47 UTC (rev 9200)
+++ sandbox/jng/cmdline/Server/src/Core/main.cpp	2017-06-07 13:51:00 UTC (rev 9201)
@@ -296,7 +296,7 @@
             }
             else if (ACE_OS::strcasecmp(parameter, MG_WCHAR_TO_TCHAR(MgResources::ServerCmdLoadPackage)) == 0)
             {
-                // Run the fdo unit tests
+                // Run the package loading
                 ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdLoadPackageInfo));
 
                 // Run the server as a regular application
@@ -309,6 +309,21 @@
 
                 bRunServerService = false;
             }
+            else if (ACE_OS::strcasecmp(parameter, MG_WCHAR_TO_TCHAR(MgResources::ServerCmdSetPwd)) == 0)
+            {
+                // Run the password setting
+                ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdSetPwdInfo));
+
+                // Run the server as a regular application
+                nResult = SERVER::instance()->init(argc, argv);
+                if (0 == nResult)
+                {
+                    nResult = SERVER::instance()->open();
+                    SERVER::instance()->fini();
+                }
+
+                bRunServerService = false;
+            }
             else
             {
                 // Unrecognized command line option
@@ -435,6 +450,7 @@
     ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdTestFdoDescription));
     ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdTestDescription));
     ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdLoadPackageDescription));
+    ACE_OS::printf(MG_WCHAR_TO_CHAR(MgResources::ServerCmdSetPwdDescription));
 
 #ifdef _WIN32
     // Windows only commands



More information about the mapguide-commits mailing list