PDA

View Full Version : Launch setup itself with other credentials



tonisa
03-26-2013, 11:10 AM
Hi,
is there a possibility to make a setup.exe launch itself with other credentials? In wise-script I implemented a script where a setup could launch itself via CreateProcessWithLogonW-API-Call. This could for PCs where user is a standarduser and has no rights to execute setups. So an administrator was able to define User, Password, Domain via registrysettings (or an .ini) and the setup finding this information launched itself as another user.
best regards
Toni

linder
03-26-2013, 11:54 AM
Toni,

You have to follow the new rules now. In modern operating systems (Vista+) it's called "over-the-shoulder" elevation. What you are trying to achive should not be done any longer (because UAC is there now).

Today, you have to do a "per-machine" (requireAdministrator) install instead of "per-user" (asInvoker) installs. But if you really would like to do a "per-user" install, you have to set the "UAC Execution Level" (General Information -> Generator Settings) to "asInvoker". Please note that you do not have any access to protected Windows resources in this case (no write access to the Program Files or Windows folder tree, HKEY_LOCAL_MACHINE registry key, etc.).

You can even launch an install "wrapper" non-elevated and let the user decide whether he would like to do a per-user or per-machine install.

The following is a very brief description of how to make an application "UAC-aware" and Win8-compliant:

-- Standard Application:

1. Embed an UAC manifest into your main application (.EXE). A manifest basically tells Windows how aware the program is about the recent Windows versions (and disables "Virtualization" and unwanted legacy Installer Detection Technology). You should include a manifest for Windows 8 because it's fully backward compatible with all previous Windows versions.

2. Request "asInvoker" execution level privileges through the manifest for your application.

3. Code-sign all your application files (e.g. .EXE, .DLL). Use a certificate signed by a CA, e.g. Comodo, VeriSign, etc.

4. Your application should not depend on any administrative APIs.

5. Do not write per-user information or user-writable information to the Program Files folder tree.

6. Do not write to any other protected Windows area (e.g. the OS drive root folder, the "Windows" folder tree, etc.).

7. Do not write to the HKEY_LOCAL_MACHINE or any other protected registry key.


-- Standard Installation:

1. Use an UAC-aware installation system. By default, installations run elevated.

2. Install applications per-machine (all users) and store per-user data in different locations.

3. Do not install Quick Launch shortcuts.

4. Never write to per-user locations from the elevated running installer. That means, never write to the HKEY_CURRENT_USER registry key or to per-user file locations.

5. Launch applications non-elevated at the end of the installation process.

6. Code-sign the installer. Use a certificate signed by a CA, e.g. Comodo, VeriSign, etc.

Note: if you have to install "per-user" data, install it to a common location and as a "first run" action of your main application, copy the data from the common location into a per-user location.

Respect the recommended (default) locations for applications and data files, but provide users with an option to select another installation location for both. A true "Mixed User Application" should work elevated and non-elevated.

That's it :-) If you follow the above steps then there will not be any PCA mitigation in Windows 8.

Does this help?

Friedrich

tonisa
03-27-2013, 09:50 AM
Hi Friedrich,
thanks for this detailed information. It helps to understand the logic how applications and setups should behave. I think, my applications act just in this way.
My primary "problem" is the following: My program is installed localy as it should (program files...), data is stored on a sql database on a server and there is a common folder on a network share with "non-db-data" and other usefull files (.ini, memorytables, ..). Generally there is a domain with activedirectory (AD) and users are defined as domainusers, so they are not admins in AD and are not part of the local admin-group. This means, for every update the have to insert the credentials of a user allowed to install applications on the local PC. But most users should not be allowed to install software to avoid all known problems about it (viruses, net-traffic, ..). Now if one user with rights updates my application, all other users on the network must install the same version, otherwise they could have problems with missing database-fields or other definitions removed from the upgrade. To avoid an admin has to run the upgrade on every PC, entering in the application it checks if the "server-version" stored in a .ini of the network-share is newer (higher) as the version of the local .exe and if so, the update-exe stored on the shared folder is invoked. So far no problem, because also the application-exe could launch the update-exe through a "CreateProcessWithLogin". But a problem could be it a user for some reason has to launch the upgrade-exe manually and he is not an admin. In wise-setup I had a script reading the credentials (crypted) from an .ini and if found, it launches itself through CreateProcessWithLogin. But if Setupbuilder does not provide such functionality I will create a small console-application doing the same.
best regards
Toni

linder
03-27-2013, 10:23 AM
Toni,

The problem is that Wise could also not help you with the CreateProcessWithLogin in the modern Windows world <g>. The old Wise 9 is a "legacy" application and is not UAC-aware at all. But UAC is here, so we have to follow the new rules :)

On UAC-aware operating systems (Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012) even an Admin does not automatically have elevated rights. But as I understand it, you have to write to protected Windows areas (e.g. the "Program Files" folder tree). Tasks that require administrator privileges will trigger an UAC prompt.

Let us assume, you have a "JoeUser" Standard User account on Windows 7. Installation applications always run elevated -- an elevated process is usually one that has been launched by someone with a Full Administrator Token and runs with High Integrity Level Privileges (administrator execution level privileges). If "JoeUser" starts the installation, UAC determines that the Current User does not have a token of sufficiently high Integrity Level and the Credentials Prompt asks the user to provide a username and password of someone who has sufficient rights. Windows will then create the necessary token for that user and uses it to elevate the process so you can now continue with the installation. Please note that you are on a completely different profile after the elevation. You have switched from the "JoeUser" profile to the "Administrator" profile!

You can't write to any protected Windows area (e.g. Program Files) from a non-elevated running application. Similar to a "Limited User" account on XP.

But I would be very interested to here if your small console-application can handle this. Perhaps we can then integrate a similar thing into SetupBuilder. In theory, it's possible with some kind of "bootstrapper" (.exe starts "asInvoker" manifested bootstrapper via the CreateProcessWithLogin API and this bootstrapper then executes the real "requireAdministrator" install via ShellExecuteEx).

It would be great if you could keep me posted on this.

Friedrich

tonisa
03-28-2013, 01:53 AM
Hi,
so far I was not aware that a CreateProcessWithLogon fails (error 740) when invoked on a UAC-enabled PC (account) and user doesn't have admin-rights. I will continue my research and let you know if I'll find some work around.
Here http://www.robotronic.de/runasspcEn.html I found a little tool that seems to work. Till now I've not tested it.
Toni

linder
03-28-2013, 03:24 AM
Hi Toni,

CreateProcess will always fail if a non-elevated application under Vista/2008/Win7/2012/Win8 attempts to launch another application whose manifest requires elevation. GetLastError will return 740 (ERROR_ELEVATION_REQUIRED) in this case.

Friedrich

tonisa
03-29-2013, 06:30 AM
Hi Friedrich,
I tested the tool found on robotronic.de and it does what it promises. I would be fine if SetupBuilder would provide something similar.
Toni