We have a java process running as the local system user on windows that needs to access a file that is owned by another user on the system. From what I understand the local system user should have permissions to impersonate that user. To do this we pass the tid and pid of a program that is accessing the file and get the user information (a token) from that. Then we set the token on the current thread. Something like this:
DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityImpersonation,TokenImpersonation,&hTokenDup);
SetThreadToken(NULL, hTokenDup);
Where hToken is obtained by opening the thread and then process via their ids.
The problem is when I try to access a file that is only accesible by the user and no one else I am unable to read it. I get an access denied error. So the question is whether or not I should be able to access this file via impersonation and if so is this the correct to impersonate another user given a threadid and pid. I guess also would I see different behavior between windows 7 and windows xp.
For starters, you should always test the return values of your Windows API calls.
Only then will you be sure that the token has indeed been copied and assigned to your process.
Impersonation requires some privileges, which I'm not really not sure you'd have if you're a simple user. I suspect the DuplicateTokenEx function fails.
Try again with administrator privileges (use the "Run as..." tool), and let us know how it goes.
Related
I need to grab parameters from jcmd for process, which started by other user on same PC. But I can't do it using admin account. I also tried to use 'runas' function, but have same result.
Is there a way to catch this process, except using the same user?
have the answer. Java locates it perf files in user temp folder, besides, it cleaning stopped process files on each jcmd request. That's why you can't get perf.counter data from other user, also you cant use perf file of other user under your account.
Another trouble is that if you want to use windows task scheduller for that purposes, you MUST run this task ONLY, when user is logged. Other way you will have permission exception.
I have been trying to write a script batch file or an exe to perform login. It should perform a basic operation- just login my windows 7 pc which is not in a network. I have a jar file running on the background. I want to write a script with a password to login my own windows 7 pc.
I have already looked into some utilities Logon.exe
The above utility is not working in my pc shows some error like
Windows Logon version 1.04
Copyright (c) 2003-2010 SoftTree Technologies, Inc.
Unable to install logon service (OpenSCManager failed).
Logon failed.
Somewhere its told that the file should be run as admin.
This is my code:
Process process = new ProcessBuilder("C:\\Logon.exe","-p","welcome").start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
And I have also tried using AutoLogon using LogonExpert
The above tool is working perfectly. But my need is to login only using java and when needed.
Please help me guys...
What you want to do is feasible, but you must play by the rules, which don't include Java. Here is a little history, why your current attempt does not work, and how you can fix it.
It won't be easy.
A little history
First, there was a fundamental change in the way Windows acquire credentials starting with Windows Vista. That logon.exe utility you mentioned uses the old architecture. Back then, you could do pretty much anything you wanted, as anything fiddling with the logon architecture ran as a DLL in Winlogon's process. You might have already found a few custom GINA, like this one I wrote. They are ignored in recent versions of Windows.
Nowadays, Winlogon asks LogonUI to acquire credentials. LogonUI is a process that will hosts Credential Providers. A credential provider is represented by a "tile" on the logon screen. There is a few COM interfaces to implement so that LogonUI asks you for credentials.
The important things to remember are:
You must implement a COM interface to interact with the logon process
You get to decide what UI you present, or no UI at all
Implementing a COM interface pretty much excludes Java.
The problem you are facing right now
Logging a user in means getting a security token for him. But logging a user interactively means that you must tell Winlogon to open the door. The only process Winlogon will listen to for that is LogonUI.
In other words, even if you had code that can create a security token, you won't be able to use it to unlock the desktop.
The Windows API to create a security token is LogonUser, by the way.
How you can fix it
You must write a Credential Provider. I never heard of way to do it in Java, this is too platform specific and non-portable. All of the documentation if for C++, but I heard that it can be done in .Net. A good starting place is the Credential Providers samples in the Platform SDK.
When your Credential Provider initialzes, you will spawn a thread that waits for some event, like a Bluetooth device showing up. Running a service will work, as long as you can communicate back to your CP.
You also need to save a pointer to LogonUI's event mechanism in your implementation of ICredentialProvider::Advise.
When your hardware detection thread detects your bluetooth device, have it call ICredentialProviderEvents::CredentialsChanged. It will tell LogonUI to go through all of the Credential Providers again. When called, you must answer that you are the default auto-logon provider.
Phew! And we have not logged on, yet!
The last step is to retreive the password you save for that user, and send it to LogonUI in when ICredentialProviderCredential::GetSerialization is called.
LogonUI will take it from there. It will instruct Winlogon to call an authentication package for you and log the user in.
This SO answer says the same thing, but it is a little terse. This MSDM article is old be more complete than my answer.
+Encrypting and managing the user's password is left as an exercice ;) but you might want to take a look at the Data Protection API.
You could also use the auto logon function that already exists.
Log in as admin and execute (WIN-R) this:
control userpasswords2
Uncheck Users must enter a user name and password to use this computer.
Your PC will still be safe from remote access.
As ixe013 answer explained the native way to accomplish interactive logon (also check this SO Q&A), I took sometime to study logonExpert tool which already doing the job successfully based on your feedback, the tool written in Borland Delphi (checked with PEiD).
I am not sure if you noticed le.exe cmd tool, which give you the ability to invoke it on demand in similar fashion to logon.exe. (found by reading help chm file).
though my answer not adding valuable technical highlights, I assumed that you might missed cmd tool option.
disclaimer: i have no relation at all with logonexpert.
Edit: I just discovered that MS SysinternalsSuite include autologon tool which can be invoked from cmd (autologon user domain password).
Inside Jenkins Jobs & Builds folder, I am creating a text file and writing some content through Java program. As I am part of corporate network, I am inside firewall with many security rules where I have been restricted to write/update the program files directory under C: drive. Although I am administrator in my local machine, however the company policies are still applied which is denying me access to write/delete any files from the Jenkins directory. I see Jenkins is nicely reading/modifying/writing any files/folders without any issues which is believed to the typical behavior of Jenkins's USER.
Question 1: Is there any way I can use this Jenkins's user through my code so I can avail access on to these directories?
Question 2: Are there ways to solve this issue through Java code? (Note: I have tried writing a file with Run as Administration java code as well)
Kindly let me know if I am missing any details,.any help is highly appreciated.
It's about the user who launched the jenkins server, who might have the permissions to access the directories.
You can use the same user for your operations if available.
Question 1: Is there any way I can use this Jenkins's user through my code so I can avail access on to these directories?
Jenkins users - Jenkins server can have its own users and privileges can be set for each users differently. You cannot use these users outside of Jenkins server.
You can use the user who launched the Jenkins server, must be a user at OS level.
Question 2: Are there ways to solve this issue through Java code? (Note: I have tried writing a file with Run as Administration java code as well)
Again, only OS level users can be used and not the Jenkins users(users created inside Jenkins server)
If you want your application to run with same credentials as Jenkins user, then hold Shift+Right Click your application, select "Run as different user", provide Jenkins's user credentials and press OK.
If you are launching your Java application from command line, do the Shift+Right Click on the cmd.exe first, and once again select "Run as different user"
If you want to impersonate a Windows user from within code, then you should really reword your question body and title (and remove Jenkins references as it has nothing to do with this). But even in this case, you need to know the credentials of the user you are trying to impersonate
I have been using the Files.getOwner() to try and make a log of folders being made on a network however doing so returns an id as below.
S-1-5-21-1027050117-121514058-1707179805-77926 (Unknown)
What would be the best way to get the login name of the owner instead of the id above?
You can try System.getProperty("user.name"); This will return the environment variable USERNAME.
On Windows 7 with JDK 8 when I run the following Java code
System.out.println(Files.getOwner(Paths.get("C:\\test\\test.txt")));
on a text file I just created, I get the following output:
chris-PC\chris_2 (User)
Where chris-PC is my computer name and chris_2 is my Windows user account. When I googled this problem I found this post where someone has the same issue as you with a samba mapped drive. The response given there is as follows:
As far as I know, this is an internal user ID which Windows displays when it cannot - for >some reason - translate it to the real user name.
I don't know how Samba provides file and folder owners to Windows, but
I'd say that Windows are unable to find that user. That user exists on
unix, it probably doesn't have any relationship to the Windows machine
accessing the share. You'd probably have to set both systems in a way
which would allow them to share user definitions (eg. put them both to
a Windows domain) to be able to display the user name on Windows.
(Just guessing.)
So, I'm not sure if this problem can be reasonably solved.
I want my program to start before the user logs into the computer. This means that I would like to start my program before the user logs into the computer by entering the password.
In fact my program is one which senses the person in front of the computer and get him logged into the computer using the password which would have already been provided by the user before. For this I would have to put up a screen during the log in process.
Also please help me out about how use the user password to get him logged in.
You need to install your program in such a way that it run as a service on operating system.
Using a third party tool like advanced installed, you could easily do this. Its as simple as a creating a wizard. Check here - http://www.advancedinstaller.com/user-guide/tutorial-java-service.html#preparing
Regarding your second goal, you perhaps want to build something like a 'Fingerprint login' which is common on laptop PC now-a-days.
In the same manner, you need to have some way to capture an identifying data of the user. say a face recognition through a webcam. Your service should get input from the webcam and able to identify the person. Then using the logon service of the operating system, it may supply the pre-input password to automatically login into the system.