working on getting the run as service tool to work again.
authorChris Koeritz <fred@gruntose.com>
Fri, 11 Jul 2014 17:49:03 +0000 (13:49 -0400)
committerChris Koeritz <fred@gruntose.com>
Fri, 11 Jul 2014 17:49:03 +0000 (13:49 -0400)
nucleus/library/security/dll_security.h [new file with mode: 0644]
nucleus/library/security/makefile [new file with mode: 0644]
nucleus/library/security/nt_security.cpp [new file with mode: 0644]
nucleus/library/security/nt_security.h [new file with mode: 0644]
nucleus/library/security/security_library.cpp [new file with mode: 0644]
nucleus/library/security/win32_security.cpp [new file with mode: 0644]
nucleus/library/security/win32_security.h [new file with mode: 0644]
nucleus/library/security/windows_firewall.cpp [new file with mode: 0644]
nucleus/library/security/windows_firewall.h [new file with mode: 0644]
nucleus/tools/simple_utilities/makefile
nucleus/tools/simple_utilities/run_as_service.cpp [new file with mode: 0644]

diff --git a/nucleus/library/security/dll_security.h b/nucleus/library/security/dll_security.h
new file mode 100644 (file)
index 0000000..da26a14
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef SECURITY_DLL_DEFINITIONS
+#define SECURITY_DLL_DEFINITIONS
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : security DLL helper                                               *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*  Purpose:                                                                   *
+*                                                                             *
+*    Allows the security support to work within a DLL.                        *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2008-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#include "basis/build_configuration.h"
+
+// windows class tags for the data structures library:
+// define BUILD_SECURITY when you are creating the dll and
+// define USE_HOOPLE_DLLS when you are importing a class from the dll.
+#ifdef BUILD_SECURITY
+  #define    HOOPLE_DLL_EXPORT_CLASS
+  #define HOOPLE_DLL_EXPORT_FUNCTION
+#elif defined(USE_HOOPLE_DLLS)
+  #define    HOOPLE_DLL_IMPORT_CLASS
+  #define HOOPLE_DLL_IMPORT_FUNCTION
+#else
+  #define SECURITY_CLASS_STYLE
+  #define SECURITY_FUNCTION_STYLE
+#endif
+
+#endif
+
diff --git a/nucleus/library/security/makefile b/nucleus/library/security/makefile
new file mode 100644 (file)
index 0000000..6b96330
--- /dev/null
@@ -0,0 +1,12 @@
+CONSOLE_MODE = true
+
+include cpp/variables.def
+
+PROJECT = security
+TYPE = library
+ifeq "$(OP_SYSTEM)" "WIN32"
+  SOURCE = nt_security.cpp win32_security.cpp windows_firewall.cpp
+endif
+TARGETS = security.lib
+
+include cpp/rules.def
diff --git a/nucleus/library/security/nt_security.cpp b/nucleus/library/security/nt_security.cpp
new file mode 100644 (file)
index 0000000..e8f5579
--- /dev/null
@@ -0,0 +1,380 @@
+
+
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : nt_security                                                       *
+*  Author : Sue Richeson                                                      *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 1999-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+#include "nt_security.h"
+#include "win32_security.h"
+
+#include <basis/astring.h>
+
+#include <lm.h>
+
+// LSA success status value.
+#ifndef STATUS_SUCCESS
+  #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
+#endif
+
+nt_security::nt_security()
+: m_sDirServiceProvider(NIL)
+{
+  // Eventually, construction of nt_security should determine if WinNT://
+  // or LDAP://, etc is the service provider and set a private member variable  
+  // with the appropriate distinguished name qualifier.
+  m_sDirServiceProvider = new astring("WinNT://");
+}
+//---------------------------------------------------------------------------
+
+
+nt_security::~nt_security()
+{
+  if (m_sDirServiceProvider)
+    delete m_sDirServiceProvider;
+}
+
+
+//---------------------------------------------------------------------------
+
+bool nt_security::iequalsUsername(astring name1, astring name2)
+{
+    return normalizeUsername(name1) == normalizeUsername(name2);
+}
+
+const astring &nt_security::normalizeUsername(astring &username)
+{
+    username.replace_all('/', '\\');
+    username.replace_all('|', ':');
+    username.to_lower();
+    return username;
+}
+
+  //---------------------------------------------------------------------------
+
+astring nt_security::DomainBinding(const astring &domain)
+{
+  astring tempstring = *m_sDirServiceProvider + domain;
+  return (tempstring);
+}
+//---------------------------------------------------------------------------
+
+
+astring nt_security::DomainUserBinding(const astring &domain, const astring &user_name)
+{
+  astring tempstring = *m_sDirServiceProvider + domain + astring("/") + user_name;
+  return (tempstring);
+}
+//---------------------------------------------------------------------------
+
+// This piece of code is borrowed from the following July 1999 MSDN article
+//     HOWTO: Look Up Current User Name and Domain Name
+//     ID: Q155698 
+//NOTE: It has been modified for inclusion in this class and it is NT-specific.
+
+bool nt_security::GetUserAndDomainName(astring &UserName, astring &DomainName)
+{
+  return win32_security::GetUserAndDomainName(UserName, DomainName);
+}
+
+
+//---------------------------------------------------------------------------
+// The following routines were taken from the lsapriv sample application by
+// Scott Field on the MSDN January 2001.
+//---------------------------------------------------------------------------
+
+/*---------------------------------------------------------------------------
+This function attempts to obtain a SID representing the supplied
+account on the supplied system.
+
+If the function succeeds, the return value is the SID. A buffer is
+allocated which contains the SID representing the supplied account.
+This buffer should be freed when it is no longer needed by calling
+HeapFree(GetProcessHeap(), 0, buffer)
+
+If the function fails, the return SID is NULL.
+
+Scott Field (sfield)    12-Jul-95
+Sue Richeson   27-FEB-2001  Mods for use in LightLink.
+Chris Koeritz  02-JAN-2008  changed some more for use within hoople.
+---------------------------------------------------------------------------*/
+
+PSID nt_security::GetUserSID(const astring &user_name)
+{
+    PSID psid = NULL;
+    char * ReferencedDomain = NULL;
+    DWORD cbSid = 128;    // initial allocation attempt
+    DWORD cchReferencedDomain = 16; // initial allocation size
+    SID_NAME_USE peUse;
+    bool bSuccess = false;
+
+    try 
+    {   //
+        // initial memory allocations
+        //
+        psid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
+        if (psid != NULL)
+        {
+            ReferencedDomain = (char *)HeapAlloc(GetProcessHeap(), 0, cchReferencedDomain * sizeof(TCHAR));
+            if (ReferencedDomain != NULL)
+            {
+                // Obtain the SID of the specified account on the specified system.
+                //
+                bSuccess = true;
+                while (!LookupAccountName(NULL, // machine to lookup account on
+                    to_unicode_temp(user_name),  // account to lookup
+                    psid,               // SID of interest
+                    &cbSid,             // size of SID
+                    to_unicode_temp(ReferencedDomain),  // domain where found.
+                    &cchReferencedDomain,
+                    &peUse)) 
+                {
+                    if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
+                    {
+                        // reallocate memory
+                        //
+                        psid = (PSID)HeapReAlloc(GetProcessHeap(), 0, psid, cbSid);
+                        if(psid != NULL)
+                        {
+                            ReferencedDomain = (char *)HeapReAlloc(GetProcessHeap(), 0,
+                                                                   ReferencedDomain,
+                                                                   cchReferencedDomain * sizeof(TCHAR));
+                            if (ReferencedDomain == NULL)
+                            {
+                                break;
+                                bSuccess = false;
+                            }
+                        }
+                        else
+                        {
+                            break;
+                            bSuccess = false;
+                        }
+                    }
+                    else
+                    {
+                        break;
+                        bSuccess = false;
+                    }
+                } // end while
+            } // if ReferencedDomain
+        } // if psid
+    }
+    catch(...) 
+    {
+        bSuccess = false;
+    }
+
+    // Cleanup and indicate failure, if appropriate.
+    //
+    if (ReferencedDomain != NULL)
+        HeapFree(GetProcessHeap(), 0, ReferencedDomain);
+
+    if (!bSuccess) 
+    {
+        if (psid != NULL) 
+        {
+            HeapFree(GetProcessHeap(), 0, psid);
+            psid = NULL;
+        }
+    }
+
+    return psid;
+}
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::OpenPolicy(const astring &serverName, DWORD DesiredAccess, PLSA_HANDLE pPolicyHandle)
+{
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status;
+    DWORD winerror = 0;
+
+    // Always initialize the object attributes to all zeroes.
+    //
+    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
+
+    transcode_to_utf16 temp_server(serverName);
+    LSA_UNICODE_STRING server;
+    server.Buffer = (PWSTR)(UTF16 *)temp_server;
+    server.Length = serverName.length() * (int)sizeof(UTF16);
+    server.MaximumLength = (serverName.length() +1) * (int)sizeof(UTF16);
+
+    // Attempt to open the policy.
+    Status = LsaOpenPolicy(&server, &ObjectAttributes, DesiredAccess, pPolicyHandle);
+    if (STATUS_SUCCESS != Status)
+    {
+        winerror = LsaNtStatusToWinError(Status);
+        ClosePolicy(pPolicyHandle);
+        return winerror;
+    }
+    else
+        return winerror;
+}
+//---------------------------------------------------------------------------
+
+
+void nt_security::ClosePolicy(PLSA_HANDLE policyHandle)
+{
+    if (policyHandle != NULL)
+        LsaClose(policyHandle);
+}
+//---------------------------------------------------------------------------
+
+
+/*
+void nt_security::InitLsaString(LPWSTR inString, PLSA_UNICODE_STRING LsaString)
+{
+    DWORD StringLength;
+
+    if (inString == NULL) 
+    {
+        LsaString->Buffer = NULL;
+        LsaString->Length = 0;
+        LsaString->MaximumLength = 0;
+        return;
+    }
+
+    StringLength = wcslen(inString);
+    LsaString->Buffer = inString;
+    LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
+    LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
+}
+*/
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,       // open policy handle
+                                            PSID AccountSid,               // SID to grant privilege to
+                                            const astring &PrivilegeName,  // privilege to grant (Unicode)
+                                            bool bEnable)                  // enable or disable
+{
+    NTSTATUS Status;
+    DWORD winerror = 0;
+
+    // Create a LSA_UNICODE_STRING for the privilege name.
+    //
+    transcode_to_utf16 temp_priv(PrivilegeName);
+    LSA_UNICODE_STRING privs;
+    privs.Buffer = (PWSTR)(UTF16 *)temp_priv;
+    privs.Length = PrivilegeName.length() * (int)sizeof(UTF16);
+    privs.MaximumLength = (PrivilegeName.length() +1) * (int)sizeof(UTF16);
+
+    // grant or revoke the privilege, accordingly
+    //
+    if (bEnable) 
+    {
+        Status = LsaAddAccountRights(PolicyHandle,       // open policy handle
+                                     AccountSid,         // target SID
+                                     &privs,   // privileges
+                                     1);                 // privilege count
+    }
+    else 
+    {
+        Status = LsaRemoveAccountRights(PolicyHandle,       // open policy handle
+                                        AccountSid,         // target SID
+                                        FALSE,              // do not disable all rights
+                                        &privs,   // privileges
+                                        1);                 // privilege count
+    }
+
+    if (Status == STATUS_SUCCESS)
+        return winerror;
+    else
+    {
+        winerror = LsaNtStatusToWinError(Status);
+        return winerror;
+    }
+}
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::SetPrivilegeOnUser(const astring &domain,
+                                         const astring &user,
+                                         const astring &privilege,
+                                         bool bEnable)
+{
+    LSA_HANDLE policyHandle;
+    PSID psid = NULL;
+    DWORD winerror = 0;
+
+    // Open the policy on the target machine.
+    //
+    winerror = OpenPolicy(domain, (POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES), &policyHandle);
+    if (winerror != 0)
+        return winerror;
+
+    // Obtain the SID of the user/group.
+    // Note that we could target a specific machine, but we don't.
+    // Specifying NULL for target machine searches for the SID in the
+    // following order: well-known, Built-in and local, primary domain,
+    // trusted domains.
+    //
+    psid = GetUserSID(user);
+    if (psid == NULL)
+    {
+        ClosePolicy(&policyHandle);
+        return ERROR_NO_SUCH_USER;
+    }
+
+    // Grant the SeServiceLogonRight to users represented by psid.
+    //
+    winerror = SetPrivilegeOnAccount(policyHandle, psid, privilege, bEnable);
+
+    // Close the policy handle.
+    //
+    ClosePolicy(&policyHandle);
+
+    //
+    // Free memory allocated for SID.
+    //
+    if (psid != NULL) 
+        HeapFree(GetProcessHeap(), 0, psid);
+
+    return winerror;
+}
+
+DWORD nt_security::AddUserToGroup(const astring &user_name, const astring &group_name)
+{
+   LOCALGROUP_MEMBERS_INFO_3 lgmi3;
+   DWORD dwLevel = 3;
+   DWORD totalEntries = 1;
+   NET_API_STATUS nStatus;
+
+// fwprintf(stderr, L"Usage: %s ServerName GroupName MemberAccountName-(DomainName\\AccountName)\n", argv[0]);
+
+   // Set up the LOCALGROUP_MEMBERS_INFO_3 structure.
+   // Assign the member account name in form of DomainName\AccountName
+   transcode_to_utf16 temp_user(user_name);
+   lgmi3.lgrmi3_domainandname = (LPWSTR)(UTF16 *)temp_user;
+
+   // Call the NetLocalGroupAddMembers() function, specifying level 3.
+   // Level 0 can use SID
+   transcode_to_utf16 temp_group(group_name);
+   nStatus = NetLocalGroupAddMembers(L"", (LPWSTR)(UTF16 *)temp_group, dwLevel,
+       (LPBYTE)&lgmi3, totalEntries);
+
+//printf("got error code %d\n" , nStatus);
+
+   if (nStatus == ERROR_MEMBER_IN_ALIAS) nStatus = 0;  // not an error.
+
+   return nStatus;
+}
+
+#endif  //win32
+
+
+
diff --git a/nucleus/library/security/nt_security.h b/nucleus/library/security/nt_security.h
new file mode 100644 (file)
index 0000000..6a36728
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef NT_SECURITY_CLASS
+#define NT_SECURITY_CLASS
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : nt_security                                                       *
+*  Author : Sue Richeson                                                      *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*  Purpose:                                                                   *
+*                                                                             *
+*    Provides a Win32 oracle for security questions.                          *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 1999-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+
+
+#include <basis/utf_conversion.h>
+
+
+#include <Ntsecapi.h>
+
+// Forward class declarations
+#include <basis/astring.h>
+
+class nt_security  
+{
+public:
+  nt_security();
+  virtual ~nt_security();
+
+  static bool iequalsUsername(astring name1, astring name2);
+    // Compares the two names for equality.  Treats backslash (\) and
+    // forward slash (/} as equal.  Ignores case.  Treats the pipe (|) and
+    // colon (:) as equal.
+
+  static const astring &normalizeUsername(astring &username);
+    // Makes the username all lowercase, converts any forward slash (/)
+    // characters to back slashes (\), and converts any pipe characters (|)
+    // to colon (:) characters.
+
+  bool GetUserAndDomainName(astring &UserName, astring &DomainName);
+    // This function is NT-specific.  It returns the user account name and
+    // domain name of the currently logged in user on the machine on which
+    // this class is executing.
+
+  astring DomainBinding(const astring &domain);
+    // This method will constsruct a distinguished name for the domain received.
+  astring DomainUserBinding(const astring &domain, const astring &user_name);
+    // This method will construct a distinguished name based on the domain and 
+    // user name received.
+
+  DWORD SetPrivilegeOnUser(const astring &domain, const astring &user,
+          const astring &privilege, bool bEnable);
+    // Sets or disables the privilege for the user in the given domain.
+    // Can also be used to set the privilege on a group in the given domain.
+    // Returns 0 if successful.  Returns Win32 error code if it fails.
+    // Domain - can be blank, in which case the local machine is assumed; can be a machine
+    //   name or a network domain name (although, having privilege to change a 
+    //   priv in a network domain is highly unlikely and will probably result in 
+    //   failure, false, return of this method). Ex:  "Legolas",  "Buildotron"
+    // User - the account name for which to change the privilege.  It can include the 
+    //   domain also.  Example user names:  "Fred", "Legolas/Bubba", "Buildotron/swbuld"
+    //   Can also be a group name.  Examples:  "Administrators", "Legolas/Users"
+    // privilege - name of the privilege to be enable/disabled.
+    //   For a list of privilges, consult winnt.h, and search for SE_ASSIGNPRIMARYTOKEN_NAME.
+    //   For a list of logon rights consult ntsecapi.h, and search for SE_BATCH_LOGON_NAME.
+    // bEnable - true to enable the privilege; false to disable the privilege
+
+  DWORD AddUserToGroup(const astring &user_name, const astring &group_name);
+    // adds the "user_name" to the local group "group_name".  this only makes
+    // the change on the local machine where this is run.
+
+protected:
+
+  PSID GetUserSID(const astring &user_name);
+    // Retrieves the security descriptor (SID) for "user_name".
+    // PSID is NULL if the method fails.
+
+  DWORD OpenPolicy(const astring &serverName, DWORD DesiredAccess,
+          PLSA_HANDLE pPolicyHandle);
+    // Open the LSA policy on the given machine.
+    // Returns 0 if successful.  Returns Win32 error code if it fails.
+
+  void ClosePolicy(PLSA_HANDLE policyHandle);
+    // Close the given LSA policy handle.
+
+  DWORD SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle,    // open policy handle
+      PSID AccountSid,              // SID to grant privilege to
+      const astring &PrivilegeName, // privilege to grant
+      bool bEnable);                // enable or disable
+    // Enable or disable the stated privilege on the given account.
+    // Returns 0 if successful.  Returns Win32 error code if it fails.
+    // PolicyHandle - must already have been opened prior to calling this method.
+    // AccountSid - must already have been obtained prior to calling this method.
+    // PrivilegeName - must be a valid security privilege name (case sensitive)
+    //      For a list of privilges, consult winnt.h, and search for SE_ASSIGNPRIMARYTOKEN_NAME.
+    //      For a list of logon rights consult ntsecapi.h, and search for SE_BATCH_LOGON_NAME.
+    // bEnable - true to enable the privilege; false to disable the privilege
+
+private:
+  astring *m_sDirServiceProvider;  //!< the directory service provider name.
+};
+
+#endif
+
+#endif
+
diff --git a/nucleus/library/security/security_library.cpp b/nucleus/library/security/security_library.cpp
new file mode 100644 (file)
index 0000000..4a2d506
--- /dev/null
@@ -0,0 +1,11 @@
+
+
+
+
+#include "nt_security.cpp"
+#include "win32_security.cpp"
+#include "windows_firewall.cpp"
+
+
+
+
diff --git a/nucleus/library/security/win32_security.cpp b/nucleus/library/security/win32_security.cpp
new file mode 100644 (file)
index 0000000..e62a65c
--- /dev/null
@@ -0,0 +1,141 @@
+
+
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : win32_security                                                    *
+*  Author : Sue Richeson                                                      *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2000-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+#include "win32_security.h"
+
+#include <basis/utf_conversion.h>
+#include <basis/astring.h>
+
+#include <comdef.h>
+#include <lm.h>
+
+// This piece of code is borrowed from the following July 1999 MSDN article
+//   HOWTO: Look Up Current User Name and Domain Name, ID: Q155698 
+//NOTE: It has been modified for inclusion here and it is Win32-specific.
+
+bool win32_security::GetUserAndDomainName(astring &UserName, astring &DomainName)
+{
+   HANDLE hToken;
+
+   // Initialize the return parameters.
+   UserName = "";
+   DomainName = "";
+
+   #define MY_BUFSIZE 512  // highly unlikely to exceed 512 bytes
+   UCHAR InfoBuffer[ MY_BUFSIZE + 1 ];
+   DWORD cbInfoBuffer = MY_BUFSIZE;
+   SID_NAME_USE snu;
+
+   BOOL bSuccess;
+
+   if(!OpenThreadToken(
+       GetCurrentThread(),
+       TOKEN_QUERY,
+       TRUE,
+       &hToken
+       )) {
+
+       if(GetLastError() == ERROR_NO_TOKEN) {
+
+           // 
+           // attempt to open the process token, since no thread token
+           // exists
+           // 
+
+           if(!OpenProcessToken(
+               GetCurrentProcess(),
+               TOKEN_QUERY,
+               &hToken
+               )) return FALSE;
+
+       } else {
+
+           // 
+           // error trying to get thread token
+           // 
+
+           return FALSE;
+       }
+   }
+
+   bSuccess = GetTokenInformation( hToken,
+                                   TokenUser,
+                                   InfoBuffer,
+                                   cbInfoBuffer,
+                                   &cbInfoBuffer);
+
+   if(!bSuccess) {
+       if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
+           // 
+           // alloc buffer and try GetTokenInformation() again
+           // 
+
+           CloseHandle(hToken);
+           return FALSE;
+
+       } else {
+
+           // 
+           // error getting token info
+           // 
+
+           CloseHandle(hToken);
+           return FALSE;
+       }
+   }
+
+   CloseHandle(hToken);
+
+   TCHAR User[MY_BUFSIZE + 1];;
+   DWORD cchUserName = MY_BUFSIZE;
+   TCHAR Domain[MY_BUFSIZE +  1];
+   DWORD cchDomainName = MY_BUFSIZE;
+                      
+    bSuccess = LookupAccountSid(NULL,
+                           ((PTOKEN_USER)InfoBuffer)->User.Sid,
+                           User,
+                           &cchUserName,
+                           Domain,
+                           &cchDomainName,
+                           &snu);
+
+    if (bSuccess)
+    {
+        UserName = from_unicode_temp(User);
+        DomainName = from_unicode_temp(Domain);
+    }
+
+   return bSuccess;
+}
+
+astring win32_security::full_user()
+{
+  astring user, temp_domain;
+  GetUserAndDomainName(user, temp_domain);
+  user += astring("[") + temp_domain + "]";
+  return user;
+}
+
+#endif // windows.
+
+
+
+
diff --git a/nucleus/library/security/win32_security.h b/nucleus/library/security/win32_security.h
new file mode 100644 (file)
index 0000000..5ccde03
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef WIN32_SECURITY_CLASS
+#define WIN32_SECURITY_CLASS
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : win32_security                                                    *
+*  Author : Sue Richeson                                                      *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*  Purpose:                                                                   *
+*                                                                             *
+*    Some helper functions for security calls.  These are lower level than    *
+*  nt_security and only require bare OS calls.                                *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2000 By Author.  This program is free software; you can       *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+
+
+// forward.
+#include <basis/astring.h>
+
+class win32_security
+{
+public:
+  static bool GetUserAndDomainName(astring &UserName, astring &DomainName);
+    //!< returns user account and windows domain of logged in user.
+
+  static astring full_user();
+    //!< returns user and domain combined into a parsable form: user[domain]
+};
+
+#endif // windows.
+
+#endif // outer guard.
+
diff --git a/nucleus/library/security/windows_firewall.cpp b/nucleus/library/security/windows_firewall.cpp
new file mode 100644 (file)
index 0000000..677531d
--- /dev/null
@@ -0,0 +1,151 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : windows firewall wrapper                                          *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2009-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#include "windows_firewall.h"
+
+
+#include <basis/functions.h>
+
+using namespace portable;
+
+// so far this is a good assumption about where to find netsh.
+astring netsh_app() { return env_string("WINDIR") + "/System32/netsh.exe"; }
+
+int windows_firewall::poke_firewall_hole(const astring &program_name,
+    const astring &exception_name, const astring &hole_description)
+{
+  astring cmdline;
+#ifdef __WIN32__
+  known_operating_systems kind = determine_OS();
+  if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+    // newer style firewall with advfirewall.
+//::MessageBox(0, "poke app srv2k8", "yodel", MB_OK);
+    cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
+        "action=allow program=\"%s\" enable=yes profile=any "
+        "description=\"%s\"", exception_name.s(), program_name.s(),
+        hole_description.s());
+  } else {
+    // older xp style firewall (if that).
+//::MessageBox(0, "poke app xp", "yodel", MB_OK);
+    cmdline = a_sprintf("-c firewall add allowedprogram program=\"%s\" "
+        "name=\"%s\" mode=enable scope=all profile=all", program_name.s(),
+        exception_name.s());
+  }
+
+  basis::u_int kid_id;
+  basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+      portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+      | portable::SHELL_EXECUTE, kid_id);
+  return to_return;
+#else
+  if (!program_name || !exception_name || !hole_description) {}  // no problem.
+  return 1;  // failure on this platform.
+#endif
+}
+
+int windows_firewall::remove_firewall_hole(const astring &program_name,
+    const astring &exception_name)
+{
+#ifdef __WIN32__
+  astring cmdline;
+
+  known_operating_systems kind = determine_OS();
+  if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+//::MessageBox(0, "removing app srv2k8", "yodel", MB_OK);
+    // newer style firewall with advfirewall.
+    cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" ",
+        exception_name.s());
+  } else {
+//::MessageBox(0, "removing app xp", "yodel", MB_OK);
+    // older xp style firewall (if that).
+    cmdline = a_sprintf("-c firewall delete allowedprogram program=\"%s\" "
+        "profile=all", program_name.s());
+  }
+
+  basis::u_int kid_id;
+  basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+      portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+      | portable::SHELL_EXECUTE, kid_id);
+  return to_return;
+#else
+  if (!program_name || !exception_name) {}  // no problem.
+  return 1;  // failure on this platform.
+#endif
+}
+
+int windows_firewall::poke_firewall_hole(int port_number,
+    const astring &exception_name, const astring &hole_description,
+    const astring &protocol)
+{
+#ifdef __WIN32__
+  astring cmdline;
+
+  known_operating_systems kind = determine_OS();
+  if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+    // newer style firewall with advfirewall.
+//::MessageBox(0, "poke port srv2k8", "yodel", MB_OK);
+    cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
+        "action=allow protocol=\"%s\" enable=yes profile=any "
+        "description=\"%s\" localport=%d",
+        exception_name.s(), protocol.s(), hole_description.s(), port_number);
+  } else {
+    // older xp style firewall (if that).
+//::MessageBox(0, "poke port xp", "yodel", MB_OK);
+    cmdline = a_sprintf("-c firewall add portopening port=%d "
+        "name=\"%s\" protocol=%s mode=enable scope=all profile=all",
+        port_number, exception_name.s(), protocol.s());
+  }
+
+  basis::u_int kid_id;
+  basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+      portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+      | portable::SHELL_EXECUTE, kid_id);
+  return to_return;
+#else
+  if (!port_number || !exception_name || !protocol || !hole_description) {}  // no problem.
+  return 1;  // failure on this platform.
+#endif
+}
+
+int windows_firewall::remove_firewall_hole(int port_number,
+    const astring &exception_name, const astring &protocol)
+{
+#ifdef __WIN32__
+  astring cmdline;
+
+  known_operating_systems kind = determine_OS();
+  if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+//::MessageBox(0, "removing port srv2k8", "yodel", MB_OK);
+    // newer style firewall with advfirewall.
+    cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" "
+        "localport=%d protocol=%s", exception_name.s(),
+        port_number, protocol.s());
+  } else {
+//::MessageBox(0, "removing port xp", "yodel", MB_OK);
+    // older xp style firewall (if that).
+    cmdline = a_sprintf("-c firewall delete portopening protocol=%s "
+        "port=%d profile=all", protocol.s(), port_number);
+  }
+
+  basis::u_int kid_id;
+  basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+      portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+      | portable::SHELL_EXECUTE, kid_id);
+  return to_return;
+#else
+  if (!port_number || !exception_name || !protocol) {}  // no problem.
+  return 1;  // failure on this platform.
+#endif
+}
+
diff --git a/nucleus/library/security/windows_firewall.h b/nucleus/library/security/windows_firewall.h
new file mode 100644 (file)
index 0000000..37133df
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef WINDOWS_FIREWALL_CLASS
+#define WINDOWS_FIREWALL_CLASS
+
+/*****************************************************************************\
+*                                                                             *
+*  Name   : windows firewall wrapper                                          *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2009-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+
+
+#include <basis/astring.h>
+
+class windows_firewall
+{
+public:
+  // adds a firewall hole for an executable called "program_name" (which should
+  // be the full path) using a rule called "exception_name".  the description
+  // for the firewall exception should be in "hole_description" (and it's only
+  // used on vista or server 2008 or later).
+  // in this and the other methods, a zero return indicates success.  any other
+  // return indicates a failure.
+  static int poke_firewall_hole(const astring &program_name,
+      const astring &exception_name, const astring &hole_description);
+
+  // this version will open an exception for a port rather than a program.
+  static int poke_firewall_hole(int port_number,
+      const astring &exception_name, const astring &hole_description,
+      const astring &protocol);
+
+  // removes a previously poked firewall hole for an application.
+  static int remove_firewall_hole(const astring &program_name,
+      const astring &exception_name);
+
+  // removes a previously poked exception for a port.
+  static int remove_firewall_hole(int port_number,
+      const astring &exception_name, const astring &protocol);
+};
+
+#endif //outer guard
+
index ee68357811df140877f0705774f594fcca6e1715..0fe5e849c1a5e08eb2752d5679eac317f77e82b0 100644 (file)
@@ -6,6 +6,7 @@ PROJECT = simplistic_utils
 TYPE = application
 TARGETS = create_guid.exe playsound.exe short_path.exe sleep_ms.exe \
   zap_process.exe 
+#run_as_service.exe 
 ifeq "$(OMIT_VERSIONS)" ""
   SOURCE += simple_utils_version.rc
 endif
diff --git a/nucleus/tools/simple_utilities/run_as_service.cpp b/nucleus/tools/simple_utilities/run_as_service.cpp
new file mode 100644 (file)
index 0000000..1f1edf4
--- /dev/null
@@ -0,0 +1,115 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : run_as_service                                                    *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 2000-$now By Author.  This program is free software; you can  *
+* redistribute it and/or modify it under the terms of the GNU General Public  *
+* License as published by the Free Software Foundation; either version 2 of   *
+* the License or (at your option) any later version.  This is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+#include <loggers/console_logger.h>
+#include <filesystem/filename.h>
+#include <structures/static_memory_gremlin.h>
+#include <security/nt_security.h>
+
+HOOPLE_STARTUP_CODE;
+
+//////////////
+
+bool run_as_service(char *user, log_base &out)
+{
+#ifdef __WIN32__
+  // ensure that the user has the "logon as a service" right.
+  nt_security secu;
+  long err = secu.SetPrivilegeOnUser("", user, "SeServiceLogonRight", true);
+  if (err) {
+    // that didn't work; probably the user name is bad?
+    out.log(astring(astring::SPRINTF, "There was a problem giving "
+        "\"%s\" the \"Logon as a Service\" right:\r\n%s", user,
+        critical_events::system_error_text(err).s()));
+    return false;
+  }
+#else
+  astring junk = user;
+  out.eol();
+  junk += "";
+#endif
+  return true;
+}
+
+int main(int argc, char *argv[])
+{
+  console_logger out;
+  if (argc < 2) {
+    out.log(filename(argv[0]).rootname() + " usage:\n\
+The first parameter must be a user name that will be given the\n\
+\"login as a service\" access rights.\n");
+    return 1;
+  }
+  bool did_it = run_as_service(argv[1], out);
+  if (did_it)
+    out.log(astring("Success giving \"") + argv[1] + "\" the 'login as service' rights.");
+  else
+    out.log(astring("Failed in giving \"") + argv[1] + "\" the 'login as service' rights!");
+  return !did_it;
+}
+
+#ifdef __BUILD_STATIC_APPLICATION__
+  // static dependencies found by buildor_gen_deps.sh:
+  #include <basis/byte_array.cpp>
+  #include <basis/callstack_tracker.cpp>
+  #include <basis/utf_conversion.cpp>
+  #include <basis/definitions.cpp>
+  #include <basis/earth_time.cpp>
+  #include <basis/guards.cpp>
+  #include <basis/astring.cpp>
+  #include <basis/log_base.cpp>
+  #include <basis/memory_checker.cpp>
+  #include <basis/mutex.cpp>
+  #include <basis/contracts.h>
+  #include <basis/outcome.cpp>
+  #include <basis/packable.cpp>
+  #include <basis/portable.cpp>
+  #include <basis/trap_new.addin>
+  #include <basis/untrap_new.addin>
+  #include <basis/utility.cpp>
+  #include <basis/version_record.cpp>
+  #include <structures/bit_vector.cpp>
+  #include <structures/byte_hasher.cpp>
+  #include <structures/configurator.cpp>
+  #include <structures/hash_table.h>
+  #include <structures/pointer_hash.h>
+  #include <structures/stack.h>
+  #include <structures/static_memory_gremlin.cpp>
+  #include <structures/string_hash.h>
+  #include <structures/string_hasher.cpp>
+  #include <structures/string_table.cpp>
+  #include <structures/symbol_table.h>
+  #include <structures/table_configurator.cpp>
+  #include <loggers/console_logger.cpp>
+  #include <loggers/file_logger.cpp>
+  #include <loggers/locked_logger.cpp>
+  #include <loggers/null_logger.cpp>
+  #include <loggers/program_wide_logger.cpp>
+  #include <filesystem/byte_filer.cpp>
+  #include <application/command_line.cpp>
+  #include <opsystem/critical_events.cpp>
+  #include <filesystem/directory.cpp>
+  #include <filesystem/filename.cpp>
+  #include <configuration/ini_configurator.cpp>
+  #include <opsystem/ini_parser.cpp>
+  #include <configuration/application_configuration.cpp>
+  #include <application/rendezvous.cpp>
+  #include <security/nt_security.cpp>
+  #include <security/win32_security.cpp>
+  #include <textual/byte_formatter.cpp>
+  #include <textual/parser_bits.cpp>
+  #include <textual/string_manipulation.cpp>
+  #include <configuration/variable_tokenizer.cpp>
+#endif // __BUILD_STATIC_APPLICATION__
+