I have no idea whats going on, and I don't have a domain setup to test with (I don't even have a Vista install to test on ATM)
Shortcuts on Vista
119 posts
FYI:
I did some further research (trial and error...).
The error has nothing to do with whether the user is in a domain or not.
It just seems that CreateProcessWithLogonW does not work when the installer is in a user related folder (e.g. Desktop, Documents, etc.). If I copy the installer to some other place (e.g. Programms, Public, etc.) the installer works just fine.
I added some messageboxes to the uac.dll but CreateProcessWithLogonW did not give me any errors.
I did some further research (trial and error...).
The error has nothing to do with whether the user is in a domain or not.
It just seems that CreateProcessWithLogonW does not work when the installer is in a user related folder (e.g. Desktop, Documents, etc.). If I copy the installer to some other place (e.g. Programms, Public, etc.) the installer works just fine.
I added some messageboxes to the uac.dll but CreateProcessWithLogonW did not give me any errors.
Originally posted by MarcOfChaosI just tested it on my Vista machine.
But the thing gets even stranger: I tested the installer from my desktop. When I copy the same installer to some other folder (e.g. \programms) UAC::RunElevated runs perfectly (RunAs Dialog is being displayed and the installer is restarted with the correct privileges). Btw: It also does not work when I run it under \users.
Maybe it is some kind of special virtualization with Vista.
Any ideas what is causing this?
I ran my installer on a limited Vista user account. If I ran it from a non-user folder, I got the Run As dialog. I put in the Administrator name and password, which Windows accepted. But my NSIS/UAC plugin code reported that admin access is required.
When I moved it to the users desktop folder, I received the error 6 as you mentioned. 🙁
Please describe your exact setup (Vista SKU, UAC on or off, type of user, exact directory it fails in)
Try this debug build: http://stashbox.org/19884/UAC.dll and watch the (unhelpful?) debug output with DebugView ( http://www.microsoft.com/technet/sys...debugview.mspx )
Are you sure the problem is with CreateProcessWithLogonW? you could comment out #define FEAT_CUSTOMRUNASDLG in uac.h to disable that code, but in my experience, Vista does nothing if you call ShellExecute(0,"runas") if the current user is not in the admin group and UAC is off (thats why I had to call CreateProcessWithLogonW in the first place)
Try this debug build: http://stashbox.org/19884/UAC.dll and watch the (unhelpful?) debug output with DebugView ( http://www.microsoft.com/technet/sys...debugview.mspx )
Are you sure the problem is with CreateProcessWithLogonW? you could comment out #define FEAT_CUSTOMRUNASDLG in uac.h to disable that code, but in my experience, Vista does nothing if you call ShellExecute(0,"runas") if the current user is not in the admin group and UAC is off (thats why I had to call CreateProcessWithLogonW in the first place)
Anders,
Your reply seemed to be directed at MarcOfChaos, but with your blessings, I'd like to help do what I can on this problem as well. I would really like to get this plugin working. Prior to receiving said blessings, I'm going to help anyways. 🙂
Attached is a .zip file containng two log files generated from DebugView.
Setup:
Vista SKU - Vista Home Premium
UAC is on
User - A Standard User (I named my standard user account "Peon")
standarduser_regularfolder.LOG is an example of me trying to run your UAC_AdminOnly sample from my C:\download\nsis\ folder. I put in my info into a Run As dialog, it said it needed admin access, so I tried again, it said it needed admin access, so I clicked cancel, and received the NSIS script message that it's aborting.
standarduser_userfolder.LOG is an example of me trying to run your UAC_AdminOnly sample from my C:\Users\Peon folder. I put in my admin info into the Run As dialog. I then got 2 message boxes (if you want the message box info, let me know...it was something about line 53 and line 60 i think), then the NSIS script gave the error: "Unable to elevate , error 6"
One last thing. I went into the log files and changed my actual password to simply "password". I don't want you seeing my real password :P
Your reply seemed to be directed at MarcOfChaos, but with your blessings, I'd like to help do what I can on this problem as well. I would really like to get this plugin working. Prior to receiving said blessings, I'm going to help anyways. 🙂
Attached is a .zip file containng two log files generated from DebugView.
Setup:
Vista SKU - Vista Home Premium
UAC is on
User - A Standard User (I named my standard user account "Peon")
standarduser_regularfolder.LOG is an example of me trying to run your UAC_AdminOnly sample from my C:\download\nsis\ folder. I put in my info into a Run As dialog, it said it needed admin access, so I tried again, it said it needed admin access, so I clicked cancel, and received the NSIS script message that it's aborting.
standarduser_userfolder.LOG is an example of me trying to run your UAC_AdminOnly sample from my C:\Users\Peon folder. I put in my admin info into the Run As dialog. I then got 2 message boxes (if you want the message box info, let me know...it was something about line 53 and line 60 i think), then the NSIS script gave the error: "Unable to elevate , error 6"
One last thing. I went into the log files and changed my actual password to simply "password". I don't want you seeing my real password :P
Hm, when UAC is on, you are not supposed to get my runas dialog, but the normal vista elevation dialog. My detection for this must be messed up. Would be great if you could drop by the nsis irc channel so I could create some test builds for you
or try http://stashbox.org/19898/UAC.dll
or try http://stashbox.org/19898/UAC.dll
Anders,
I'd be happy to test that out and jump int the IRC channels to help you out (I really appreciate the time you're putting into this).
But for now, I have to go. I've got tickets to the Utah Jazz vs. Golden State Warriors Game 1. 🙂
(Also, I just double checked to verify UAC was on. When I ran a normal NSIS installer on my standard user account, I did get a UAC dialog asking for an administrators password.
When I ran a NSIS installer with your UAC plugin under the same user account, I did get the Run As dialog.)
I'd be happy to test that out and jump int the IRC channels to help you out (I really appreciate the time you're putting into this).
But for now, I have to go. I've got tickets to the Utah Jazz vs. Golden State Warriors Game 1. 🙂
(Also, I just double checked to verify UAC was on. When I ran a normal NSIS installer on my standard user account, I did get a UAC dialog asking for an administrators password.
When I ran a NSIS installer with your UAC plugin under the same user account, I did get the Run As dialog.)
Hello,
Sorry for my late reply. I am currently a little busy (who is not? 😉)
Find attached the logfiles and error messages of the 2 debug builds.
I tested on Win Vista Ultimate with activated UAC.
Just like helix400 I changed the passwords and usernames.
Sorry for my late reply. I am currently a little busy (who is not? 😉)
Find attached the logfiles and error messages of the 2 debug builds.
I tested on Win Vista Ultimate with activated UAC.
Just like helix400 I changed the passwords and usernames.
Hi Anders, I have three improvement suggestions:
1. The built-in RunAs-dialog for Vista is english only. This dialog should be "multi-language" (e.g. by loading text strings from some ini file in $PLUGINSDIR).
2. Currently we do not a RunAs-dialog which allows all users etc. We always want the user to login using an admin account. So the dialog might be changed: other texts, maybe a combo box where (local?) admin usernames are pre-filled etc. The "current user" setting (radio selection) seems quite useless here.
3. The XP/2000-RunAs-dialog is not optimal for installers because it has worse defaults. A good own dialog (see points 1 and 2) for Vista could be used for XP/2000, too. The dialog should mention the need for elevation (so we do not need a messagebox with explaining texts before).
We just need some text explaining why this dialog appeared and what the user is expected to do, a possibility to enter a username (Administrator account should be preselected) and a password input field.
1. The built-in RunAs-dialog for Vista is english only. This dialog should be "multi-language" (e.g. by loading text strings from some ini file in $PLUGINSDIR).
2. Currently we do not a RunAs-dialog which allows all users etc. We always want the user to login using an admin account. So the dialog might be changed: other texts, maybe a combo box where (local?) admin usernames are pre-filled etc. The "current user" setting (radio selection) seems quite useless here.
3. The XP/2000-RunAs-dialog is not optimal for installers because it has worse defaults. A good own dialog (see points 1 and 2) for Vista could be used for XP/2000, too. The dialog should mention the need for elevation (so we do not need a messagebox with explaining texts before).
We just need some text explaining why this dialog appeared and what the user is expected to do, a possibility to enter a username (Administrator account should be preselected) and a password input field.
Just an idea: I don't know whether the system RunAs-dialog in Windows 2000/XP supports other authentication methods than password. Think of a fingerprint reader...
thanks everyone for testing, I will need to find a new way to detect if i need my runas dialog
Please report the output of this console app: http://stashbox.org/19958/TokenElevation.exe (Based on code from http://blogs.msdn.com/cjacks/archive...ows-Vista.aspx )
Please report the output of this console app: http://stashbox.org/19958/TokenElevation.exe (Based on code from http://blogs.msdn.com/cjacks/archive...ows-Vista.aspx )
Hi,
Did some further research:
TokenElevationTypeDefault only means that the user does not have a split token. This should be true for 'nearly' every user that is not an administrator.
I also found a clue on how to determine whether UAC is enabled.
One could try to check in the registry whether the policy is enabled or not.
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA
Possible values: Enabled (1), Disabled(0)
Hope this helps...
Did some further research:
TokenElevationTypeDefault only means that the user does not have a split token. This should be true for 'nearly' every user that is not an administrator.
I also found a clue on how to determine whether UAC is enabled.
One could try to check in the registry whether the policy is enabled or not.
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA
Possible values: Enabled (1), Disabled(0)
Hope this helps...
Hi,
find attached the screenshots of the TokenElevation.exe.
find attached the screenshots of the TokenElevation.exe.
I tested TokenElevation as well. I got different result when I ran the app from a regular folder with a standard user account. Screenshots are attached below.
Just an update for those following the thread. I worked with Anders more today. He got a version working where the UAC dialog pops up when it should (when UAC is turned on), and the Run As dialog pops up when it should (when UAC is turned off). In all situations, the test apps worked. There's still the issue of the installer window popping up behind active windows...he'll work on that later.
Ok, I created a wiki page @ http://nsis.sourceforge.net/UAC_plug-in , only done limited testing, but I hope its fixed, please report back
Sorry, but I got kind of lost as to how this plug-in helps to create shortcuts in the user's own start menu instead of the all users one. Can anyone give me a bit of guidance? Thanks.
It's more of an overall UAC thing, which has a nice side effect of solving the Vista user shortcuts problem.
The way this plugin works is the following:
1) First, the NSIS script needs to say it wants user privileges, not admin privileges.
2) The NSIS installer launches, and quickly calls its .onInit code (no form has shown by this point yet). That code makes a new process and attempts to elevate it to admin mode. Anders calls the first process the outer process, and this second process the inner process.
3) If needed, a UAC or Run As dialog is shown. After that, the inner process should be elevated to admin access. Then this admin/inner process can display. This is the main installer app that users will see. At this time, two processes are running. One as a user, another as an admin.
4) Now that you have an admin process, you can continue to let your script do its thing. If you ever need to do something at a user level, you do it through the UAC plugin. For example, UAC::Exec can execute something with user privileges and not admin privileges.
With all this in place, you can do some system calls to create a shortcut as a user. Personally, I think the UAC plugin should have some extra features added on, such as UAC::CreateUserShortcut or something like that. But then, Anders has been working really hard on just getting the bugs worked out of the current plugin...I'm just happy he's providing a fairly clean solution compared to the really ugly alternatives out there in the Vista world.
The way this plugin works is the following:
1) First, the NSIS script needs to say it wants user privileges, not admin privileges.
2) The NSIS installer launches, and quickly calls its .onInit code (no form has shown by this point yet). That code makes a new process and attempts to elevate it to admin mode. Anders calls the first process the outer process, and this second process the inner process.
3) If needed, a UAC or Run As dialog is shown. After that, the inner process should be elevated to admin access. Then this admin/inner process can display. This is the main installer app that users will see. At this time, two processes are running. One as a user, another as an admin.
4) Now that you have an admin process, you can continue to let your script do its thing. If you ever need to do something at a user level, you do it through the UAC plugin. For example, UAC::Exec can execute something with user privileges and not admin privileges.
With all this in place, you can do some system calls to create a shortcut as a user. Personally, I think the UAC plugin should have some extra features added on, such as UAC::CreateUserShortcut or something like that. But then, Anders has been working really hard on just getting the bugs worked out of the current plugin...I'm just happy he's providing a fairly clean solution compared to the really ugly alternatives out there in the Vista world.
I see... thanks for the nice, detailed overview. Now to figure out how to actually make those shortcuts using UAC::Exec...
You should not use UAC::Exec for that, use ExecCodeSegment
UAC_RealWorldExample.nsi does:
Function CreateShortcuts
CreateShortcut "$Desktop\${APPNAME}.lnk" "$Windir\Notepad.exe"
FunctionEnd
Section "Desktop Shortcut"
GetFunctionAddress $0 CreateShortcuts
UAC::ExecCodeSegment $0
SectionEnd
the CreateShortcuts function will execute as the original user (You get no feedback in the install log, hopefully I will implement some kind of DetailPrint that "works the other way")
UAC_RealWorldExample.nsi does:
Function CreateShortcuts
CreateShortcut "$Desktop\${APPNAME}.lnk" "$Windir\Notepad.exe"
FunctionEnd
Section "Desktop Shortcut"
GetFunctionAddress $0 CreateShortcuts
UAC::ExecCodeSegment $0
SectionEnd
the CreateShortcuts function will execute as the original user (You get no feedback in the install log, hopefully I will implement some kind of DetailPrint that "works the other way")
So... just to make sure I'm understanding this correctly... basically we encapsulate the stuff we want to do as the original user in a function, then use UAC::ExecCodeSegment on the function address to execute the stuff?
Sounds pretty simple... thanks a lot!
Sounds pretty simple... thanks a lot!
yes, the only problem is that you get no output in the install log since its actually executing in a hidden installer
With Anders permission, I've added more documentation to the plug-in page at: http://nsis.sourceforge.net/UAC_plug-in
Some of it was based off comments mentioned in this thread. So if you find yourself saying "Hey, I said that!", it's because you did. 🙂
Some of it was based off comments mentioned in this thread. So if you find yourself saying "Hey, I said that!", it's because you did. 🙂
@Anders: I hope you consider my RunAs dialog ideas. Here's another feature request (which is quite obvious):
Allow communication from outer to inner installer. It would be nice if the ExecCodeSegment could return values. Either by allowing ExecCodeSegment the other way, too (outer calls inner => return values by a callback). Or by exchanging values internally using some UAC stack (UAC::Push, UAC::Pop, callable by both instances). Or something else.
The outer installer runs with user privileges, so it is a bit difficult to exchange information using some workaround (registry location). They both use different TMP (pluginsdir). Perhaps there is a possibility via windows API. I think about something like PeekMessage / PostThreadMessage (but those might interfere the GUI event handling...)
Allow communication from outer to inner installer. It would be nice if the ExecCodeSegment could return values. Either by allowing ExecCodeSegment the other way, too (outer calls inner => return values by a callback). Or by exchanging values internally using some UAC stack (UAC::Push, UAC::Pop, callable by both instances). Or something else.
The outer installer runs with user privileges, so it is a bit difficult to exchange information using some workaround (registry location). They both use different TMP (pluginsdir). Perhaps there is a possibility via windows API. I think about something like PeekMessage / PostThreadMessage (but those might interfere the GUI event handling...)
Yeah, I have already thought about adding stack support. The problem is, you can't send a message the other way without reducing the security of the admin instance
As for changes to the run-as dialog, those are way down on the list, you are only supposed to see that dialog if you are non admin with uac off. And I'm not sure if using my dialog is smart on 2k/xp, I don't know how much it changes if the machine has a custom GINA and stuff like that. Maybe I could implement some sort of show function callback and you could do whatever you want to my dialog
This thing was really just to support starting a process on the finish page, not sure how smart it is to add to much support for other stuff. Duplicating every NSIS api call to provide proper feedback is just too much work. The outer instance never gets past .onInit so there are no DetailPrints i can just "steal" from the listview either and there is no way to hook into the nsis calls as far as i know
As for changes to the run-as dialog, those are way down on the list, you are only supposed to see that dialog if you are non admin with uac off. And I'm not sure if using my dialog is smart on 2k/xp, I don't know how much it changes if the machine has a custom GINA and stuff like that. Maybe I could implement some sort of show function callback and you could do whatever you want to my dialog
This thing was really just to support starting a process on the finish page, not sure how smart it is to add to much support for other stuff. Duplicating every NSIS api call to provide proper feedback is just too much work. The outer instance never gets past .onInit so there are no DetailPrints i can just "steal" from the listview either and there is no way to hook into the nsis calls as far as i know
Please make your RunAs dialog at least customizable (language strings). Is this an privileges problem? I guess the RunAs dialog is an outer process thing.
Regarding security issue (passing values from outer to inner): I think about two ways:
a) the inner process has admin privileges. We could use this to let the inner process read those values out of the process context / environment /... of the outer one.
Very simple solution: create a temp file and pass the file to the inner process as CMD. So both processes could use this file. Problem: The privileges of the inner process could be insufficient. The file could be encrypted by EFS and the admin user would not have the key. So file is not good...
b) is the inner process technically a child process of the outer one? Perhaps there is something in windows which allows limiting the communication to father-child.
Regarding security issue (passing values from outer to inner): I think about two ways:
a) the inner process has admin privileges. We could use this to let the inner process read those values out of the process context / environment /... of the outer one.
Very simple solution: create a temp file and pass the file to the inner process as CMD. So both processes could use this file. Problem: The privileges of the inner process could be insufficient. The file could be encrypted by EFS and the admin user would not have the key. So file is not good...
b) is the inner process technically a child process of the outer one? Perhaps there is something in windows which allows limiting the communication to father-child.
Perhaps Memory Mapped Files could help:
I know you started UAC only for the Finish-Exec problem. And the current solution is quite nice. The "Passing parameters back" is not as important (for me). Anyway the plugin is great, thanks for your effort.
The biggest problem is not how to pass data back, its what to pass. Even if I added UAC:😁etailPrint that works the other way, what strings would you pass back?
Originally posted by AndersI stumbled on a new Vista API function that allows an admin process to register a type of message so that user-level process could send it messages of that type. Unfortunately, I can't remember the name of it now (my work computer probably has it in the browser history).
Yeah, I have already thought about adding stack support. The problem is, you can't send a message the other way without reducing the security of the admin instance
Also, in XP and 2000, can a user-level process send messages to an admin-level process? I was under the impression they could.
I don't know if this is any help for you, just chiming in with a thought.
I don't need UAC:😁etailPrint. What I want is doing some processing for current user (not just Exec on finish):
Reading HKCU and writing HKCU, reading files from the user's profile/writing files (SetShellVarContext).
Doing actions (write) is possible using your UAC::ExecuteCodeSegment. But I cannot read values. I want to read a value (outer process), process it in the main installer (inner process), show it in the GUI, allow user options etc. and then do the action using UAC::ExecuteCodeSegment.
Reading those values using the inner process is no option because the files / keys could have privilege problems (or EFS encryption). So the original (outer) user account has to be used here.
At first I just want to pass some bool (yes/no), but in general it would be nice to at least allow int numbers and when possible strings.
Reading HKCU and writing HKCU, reading files from the user's profile/writing files (SetShellVarContext).
Doing actions (write) is possible using your UAC::ExecuteCodeSegment. But I cannot read values. I want to read a value (outer process), process it in the main installer (inner process), show it in the GUI, allow user options etc. and then do the action using UAC::ExecuteCodeSegment.
Reading those values using the inner process is no option because the files / keys could have privilege problems (or EFS encryption). So the original (outer) user account has to be used here.
At first I just want to pass some bool (yes/no), but in general it would be nice to at least allow int numbers and when possible strings.