Assigning JobObject to process with non-zero session id launched from a SYSTEM service - c++

I have a Windows SYSTEM service which needs to launch a new process in the context of the logged-in user. Along with this, I need to create a Job for the new process with certain limits.
I am extracting the process token of explorer.exe and duplicating it to create a primary token. I use this token in CreateProcessAsUser to create the new process running in the context of the user with a session id which is non-zero. When I assign the Job to this process, AssignProcessToJobObject function fails with Access denied error. Specifically, I am not able to set JOBOBJECT_BASIC_UI_RESTRICTIONS limits (JOBOBJECT_EXTENDED_LIMIT_INFORMATION works though).
The process is created as suspended and after assigning the job, I am resuming the thread.
When I use the token of the current process (i.e. SYSTEM service with session id 0) instead of explorer.exe, everything works fine.
I am testing this on Windows 10

Related

Camunda process versioning using "Process Instance Modification" migrate call activities

In our project we have problem with camunda process versioning.
We have read some guides and decided to use Process Instance Modification over Process Instance Migration due to limitations that the last approach has.
As we see Process Instance Migration does not allow us to change current variables (based on their previous value, and current wait point we stay), sometimes we only want to change variables because we change delegate executions code and we know that business model (BPMN) haven't bean changed.
So currently I am trying to develop migration framework based on Process Instance Modification.
And first issue I encounter is:
How properly migrate process instance which currently stays on wait point in Call Activity?
For example, I have process:
I start it. One exectuions stays on wait point before Message 1 event. Another gets into Call activity:
And stays there before Message 3 and Message 4.
By using Process Instance Modification I stop processes in Call Activity and then start them again (changing variables, and bpmn model to the latest). How can I attach them to the parent process instance which called Call activity in the first place, to make it return back to the parent process instance (which called Call activity) and proceed with processing (executing Task 6). What if I want to migrate parent process as well?

C++. Get logged in user name from Linux daemon

is there a way to get logged in user name from linux daemon?
I tried
seteuid(1000);
std::string userName = getlogin();
But seems that this call fails and my application is terminated after.
The general situation is following: some script that runs my daemon process. Inside of this daemon I start another UI process (lets call it A). Then in process A I'm trying to get logged in user name with way, described earlier. And my process A is terminated after getlogin call. Is there any reliable way to get logged in user name from process A?
getlogin() reads the login information from the utmp file, so it won't work if the process isn't associated with a terminal.
I assume from the seteuid call in your example that process A is running with the effective user ID of the original user.
If you don't have a terminal, but have the uid you need to use the "passwd" database (often, but not always, backed by the /etc/passwd file):
struct passwd *pw = getpwuid(geteuid());
string userName = pw->name;

CreateProcessAsUser creates blank/black window

I'm using CreateProcessAsUser to create a process under user-specified credentials.
I'm posting what are hopefully the relevant parts of the code. Let me know if you want to see anything more.
First LogonUser to get the token:
result = LogonUser(
username,
wcschr(username, '#') ? NULL : (domain ? domain : L"."),
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hrunastoken);
I then load the profile, set the lpDesktop value of the STARTUPINFO structure to NULL (which makes it use the desktop of the calling process), and call CreateProcessAsUser:
result = CreateProcessAsUser(
hrunastoken,
NULL,
apptorun,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
envblock ? envblock : NULL,
NULL,
&si,
&pi);
This works fine - it logs in and creates the process successfully, and the process "works". The problem is that the windows it creates are black, as in this screenshot of a notepad process started with my program:
Possibly relevant context:
My account is a local account on a Windows 7 machine with full admin rights, and I am logged on with that account. I used psexec (Sysinternals utility) to open a command prompt running interactively under the local system account. I am launching my program from that command prompt. The credentials I am passing to it are from my account.
I have not done anything with permissions to windowstations/desktops; I assume the process I create should have rights to those as the process is being created in my session and using the same account I'm already logged in with - albeit going through the SYSTEM account first. Using Process Explorer, I don't see any difference in the permissions on the values and handles to windowstation/desktop by the process opened via my program vs opened normally. Maybe that's completely irrelevant.
I also cannot use CreateProcessWithLogonW function because it must work when run from the SYSTEM account - that function as well as the "runas" program that comes with Windows don't work under SYSTEM.
Funnily enough, I can't use my current method to open processes unless I'm running it under the SYSTEM account, as "a required privilege is not held by the client", so I can't compare the windows created when starting my program under my account vs the SYSTEM account...
The default DACL for window stations and desktops grant full access to the logon SID (which is unique to the current logon session) rather than to the user's SID. (The user's SID also appears in the DACL for the window station but has only limited permissions. It does not appear in the desktop DACL.)
The call to LogonUser generates a new session (and associated logon SID) rather than reusing the existing one, so your process does not have access to the desktop, and only has minimal access to the window station. (Actually I'm slightly puzzled as to how the process manages to run at all; when I tried to reproduce your results the process exited immediately with exit code 0xC0000142, as expected.)
The second piece of code in this answer shows how to change the DACL on the window station and desktop to allow the process to run properly. (This may not be the best solution, however, depending on your specific goals.)

Trying to interpret user session states on Windows OS

If I call the following API from a local service running on Windows 7:
WTS_SESSION_INFO* pWSI;
DWORD nCntWSI;
WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, NULL, 1, &pWSI, &nCntWSI);
and then go through all returned WTS_SESSION_INFO structs in pWSI and check WTS_CONNECTSTATE_CLASS State members, can someone explain what is the difference between WTSActive and WTSConnected?
Connected means the user has connected and has been (or soon will be) presented with a login screen but hasn't completed it and been verified yet. He might be typing his password, for example.
If the user has locked the workstation, it's been locked by a screensaver, or he has switched to another user account, it doesn't end his session. The user remains logged in and his session would remain marked active. So being connected but not active means there are no processes running under that user's account. (The one caveat being there could be a service or other process running in a separate session under that user's credentials, but that's a different matter.)

How to get the logged on user from a process running as root?

I have a program running as root and call another program to run(A).
I want A to run when the user logs on. I've used command: su - 'username' -c A,
or in the A main function, I've called: setuid(current_uid_logged).
But I don't know the way to get the user-name of the logged on user, or the uid in the root process.
Ways that I've tried: getenv("USERNAME") or getlogin() always return root account.
I've confused with getlogin(), my program is running when kernel start and wait for user login (I have a thread to wait a Finder process (Mac OSX) running to detect user logged on), wait 10 seconds and call getlogin() but sometime, it returned root but can return user login. I think Finder process is running when user logged on.
But when I call my app to run with sudo command, getlogin() always returns current user logged on.
How do I do this?
getlogin(3) returns the name of the user who owns the process's controlling terminal. This has nothing to do with the username of whoever might log in to the GUI of the operating system. Instead, getlogin(3) and getuid(2) will only ever return the name / uid of the user account that started the program -- they have more to do with the process history than with any user sitting in front of the computer.
There are similar stories with the environment variables USER and LOGNAME -- if either one was set in a process, it was by a process higher in the process's call tree. It too cannot be influenced by whichever user eventually sits in front of the computer.
I'm sure there is some mechanism to discover the currently-logged-on user on an OS X machine, but it won't be a traditional Unix API that provides it to you.
how about uid_t getuid()?
more details at http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/getuid.2.html