Elevate privileges at Runtime

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Virja
In need of some credit
In need of some credit
Posts: 9
Joined: Fri Jun 07, 2019 8:45 pm
Location: I am Virchanza.
Contact:

Elevate privileges at Runtime

Post by Virja » Thu Feb 06, 2020 1:55 pm

Hi guys, I posted to this forum about 9 or 10 years ago under the name "Virchanza". It would be nice if I could get that account back.

I found all the source code to my old program 'Dynamo' and I'm now continuing development on it, hoping to bring out a new version before Summer.

When my application is first run, I want to elevate privileges to "root" or "Administrator". If there isn't any code in wxWidgets yet to do this, then we should start writing it.

Here's what I have so far:
(I've taken the MS-Windows code from this page: https://www.codeproject.com/Articles/32 ... ng-runtime)

Code: Select all

#ifdef WIN32

BOOL IsRunAsAdministrator()
{
    BOOL fIsRunAsAdmin = FALSE;
    DWORD dwError = ERROR_SUCCESS;
    PSID pAdministratorsGroup = NULL;

    // Allocate and initialize a SID of the administrators group.
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    if (!AllocateAndInitializeSid(
        &NtAuthority, 
        2, 
        SECURITY_BUILTIN_DOMAIN_RID, 
        DOMAIN_ALIAS_RID_ADMINS, 
        0, 0, 0, 0, 0, 0, 
        &pAdministratorsGroup))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Determine whether the SID of administrators group is enabled in 
    // the primary access token of the process.
    if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

Cleanup:
    // Centralized cleanup for all allocated resources.
    if (pAdministratorsGroup)
    {
        FreeSid(pAdministratorsGroup);
        pAdministratorsGroup = NULL;
    }

    // Throw the error if something failed in the function.
    if (ERROR_SUCCESS != dwError)
    {
        throw dwError;
    }

    return fIsRunAsAdmin;
}

void MyApp::Elevate_Privileges_Now(void)
{
	BOOL bAlreadyRunningAsAdministrator = FALSE;
	try
	{
		bAlreadyRunningAsAdministrator = IsRunAsAdministrator();
	}
	catch(...)
	{
		std::cout << "Failed to determine if application was running with admin rights" << std::endl;
		DWORD dwErrorCode = GetLastError();
		TCHAR szMessage[256];
		_stprintf_s(szMessage, ARRAYSIZE(szMessage), _T("Error code returned was 0x%08lx"),dwErrorCode);
		std::cout << szMessage << std::endl;
	}
	if(!bAlreadyRunningAsAdministrator)
	{
		wchar_t szPath[MAX_PATH];
		if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)))
		{
			// Launch itself as admin
			SHELLEXECUTEINFO sei = { sizeof(sei) };
			sei.lpVerb = L"runas";
			sei.lpFile = szPath;
			sei.hwnd = NULL;
			sei.nShow = SW_NORMAL;

			if (!ShellExecuteEx(&sei))
			{
				DWORD dwError = GetLastError();
				if (dwError == ERROR_CANCELLED)
				{
					// The user refused to allow privileges elevation.
					std::cout << "End user did not allow elevation" << std::endl;
				}
			}
			else
			{
				_exit(1);  // Quit itself
			}
		}
	}
}

#else

void App_Dynamo::Elevate_Privileges_Now(void)
{
	// How to you programatically elevate to root in Linux ? ? ? 
}

#endif

This account was temporarily used by "Virchanza" for a few days in Spring 2020 after a 9-year absence from the forum.

User avatar
doublemax
Moderator
Moderator
Posts: 15174
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Elevate privileges at Runtime

Post by doublemax » Thu Feb 06, 2020 2:46 pm

Hi guys, I posted to this forum about 9 or 10 years ago under the name "Virchanza". It would be nice if I could get that account back.
That account still exists. If you forgot the password, you can request a new one, if you still have access to the email account from back then.
I want to elevate privileges to "root" or "Administrator". If there isn't any code in wxWidgets yet to do this, then we should start writing it.
If you'd like to add this functionality to wxWidgets itself, please discuss this on the wx-dev group: https://groups.google.com/forum/#!forum/wx-dev
Use the source, Luke!

Virja
In need of some credit
In need of some credit
Posts: 9
Joined: Fri Jun 07, 2019 8:45 pm
Location: I am Virchanza.
Contact:

Re: Elevate privileges at Runtime

Post by Virja » Thu Feb 06, 2020 4:15 pm

doublemax wrote:
Thu Feb 06, 2020 2:46 pm
That account still exists. If you forgot the password, you can request a new one, if you still have access to the email account from back then.

The email account I used back then was with "lavabit.com" but they've since been shut down. I can't remember the password. Is there any way to recover the account, e.g. with security questions?
This account was temporarily used by "Virchanza" for a few days in Spring 2020 after a 9-year absence from the forum.

Virja
In need of some credit
In need of some credit
Posts: 9
Joined: Fri Jun 07, 2019 8:45 pm
Location: I am Virchanza.
Contact:

Re: Elevate privileges at Runtime

Post by Virja » Fri Feb 07, 2020 10:08 am

Does anyone have some Linux code for elevating privileges? It's actually quite difficult to find anything about this if you do a web search (because 99% of the returned hits are for a user trying to run, as root, a GUI program that they downloaded).

I might have to look at the source code for a program like "GParted" to see how it elevates privileges as soon as you open it.
This account was temporarily used by "Virchanza" for a few days in Spring 2020 after a 9-year absence from the forum.

DavidHart
Site Admin
Site Admin
Posts: 4005
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Re: Elevate privileges at Runtime

Post by DavidHart » Fri Feb 07, 2020 11:45 am

Hi,

I have some in my program: see ExecInPty::ExecuteInPty() in https://sourceforge.net/p/fourpane/git4 ... /Misc.cpp
(which is the second time this week I've pointed to that function :? )

Regards,

David

Virja
In need of some credit
In need of some credit
Posts: 9
Joined: Fri Jun 07, 2019 8:45 pm
Location: I am Virchanza.
Contact:

Re: Elevate privileges at Runtime

Post by Virja » Fri Feb 07, 2020 12:18 pm

DavidHart wrote:
Fri Feb 07, 2020 11:45 am
Hi,

I have some in my program: see ExecInPty::ExecuteInPty() in https://sourceforge.net/p/fourpane/git4 ... e/Misc.cpp

(which is the second time this week I've pointed to that function :? )

Regards,

David
Your link says "Page Not Found"
This account was temporarily used by "Virchanza" for a few days in Spring 2020 after a 9-year absence from the forum.

DavidHart
Site Admin
Site Admin
Posts: 4005
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Re: Elevate privileges at Runtime

Post by DavidHart » Fri Feb 07, 2020 1:20 pm

Sorry, that was a bad copy/paste from the previous thread. I've edited the post, and the link works now.

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Re: Elevate privileges at Runtime

Post by Virchanza » Thu Feb 13, 2020 1:35 pm

David, I see that your code can start a child process as root. What I really want to do though is to take the current process and elevate it to root.

If it's not possible to elevate a process to root, then here's my next idea:

(1) Take my Dynamo application and embed it within another exectuable. Let's call this other program "dynostart".
(2) When dynostart is run, it creates a shared memory object, and then it copies the raw binary values of my dynamo application into this shared memory object. This shared memory object will be accessible at "/dev/shm/dynamo_binary". Because everything is a file in Linux, I can then set the execution bit on this "/dev/shm/dynamo_binary" and then try to start it as root.

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Re: Elevate privileges at Runtime

Post by Virchanza » Thu Feb 13, 2020 3:21 pm

I got this to work in Linux just now with the following code for the starter program:

Code: Select all

#include <stdlib.h> 
#include <string.h> 
#include <sys/shm.h> 
#include <sys/mman.h> 
#include <sys/stat.h>        /* For mode constants */ 
#include <sys/types.h> 
#include <fcntl.h>           /* For O_* constants */ 
#include <unistd.h> 

extern char unsigned const g_prog[3521531u]; 

int main(void) 
{ 
   /* create the shared memory object */ 
    int const f = shm_open("/prog_binary", O_CREAT | O_RDWR, 0666); 
    
    /* configure the size of the shared memory object */ 
    ftruncate(f, sizeof g_prog); 
  
    /* memory map the shared memory object */ 
    void *const ptr = mmap(0, sizeof g_prog, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, f, 0); 
  
    /* write to the shared memory object */ 
    memcpy(ptr, g_prog, sizeof g_prog); 
    
    /* unmap the memory */ 
    munmap(ptr, sizeof g_prog);
    
    /* close the file do you don't get error "Text file busy" */ 
    close(f);
  
    /* Mark the file as executable */ 
    system("chmod +x /dev/shm/prog_binary"); 

    /* Run the main program */ 
    system("/dev/shm/prog_binary"); 
         
    for ( ; /* ever */ ; ) 
    { 
        /* Do Nothing */ 
        ; 
    } 
         
    return 0; 
} 

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Re: Elevate privileges at Runtime

Post by Virchanza » Thu Feb 13, 2020 3:52 pm

It displays a nice GUI interface for the user to enter their superuser password if I change the system call to:

"pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY /dev/shm/prog_binary"

This is exactly what I'm looking for but now I just want to try make it so that the binary data for my main program is in memory only once (instead of twice). It's in memory twice because I copy from my global char array into the shared memory object. Ideally I'd like to somehow just map the shared memory object to my global char array, but I don't know if that's possible.

Virchanza
Experienced Solver
Experienced Solver
Posts: 78
Joined: Sun Jul 19, 2009 6:12 am

Re: Elevate privileges at Runtime

Post by Virchanza » Fri Feb 14, 2020 9:34 am

One of the drawbacks of this approach of using a starter program is that my application will be in memory three times. However if I wanted to be a real miser with RAM then I could get my main application to reuse the memory that is wasted by the starter program.

Post Reply