Copy file with elevated privileges; prompt is fine [duplicate] - vb.net

When a user saves a file from my application, they currently can't save to restricted locations (like C:). I think this is a good restriction, but I would like to provide a UAC prompt to elevate privileges and allow a user to save in a restricted area.
I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.
What I'm wanting to do is basically what Windows itself does. When you try to copy a file to C:\ in Windows 7 (assuming you've got UAC set to its default level), you get the following prompt:
Once you click the Continue button with the UAC shield, the file is copied to C:\ with no prompt for credentials (assuming you're logged on with admin privileges).
How can I replicate this behavior in my application for admin users? They shouldn't have to impersonate any other user because they already have admin privileges. Can anyone provide details on what Windows is doing during this process? Are they spawning a new explorer.exe process with elevated privileges?

You need to do what Windows does. And spawn a new process which will run with elevated rights. There are no shortcuts here. The token that is allocated when a process starts is what determines what rights the process has. That token cannot be changed after the process has started. If you need to elevate, you need a new process.
I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.
No that's not the case. If the current user is not an admin, then the UAC dialog will prompt for new credentials of a user that does have admin rights. That's the over-the-shoulder UAC dialog. On the other hand, if the current user is an admin then they just get the consent dialog. That's the dialog that's shown on the secure desktop and just asks for you to click Continue.
The one thing that Windows components can do that you cannot is start a process elevated without showing you the consent dialog. That happens on Windows 7 only (not on Vista), and only if you have the UAC setting at the new Default setting that was added in Windows 7. That's how Explorer is able to show the dialog that you included in the question and then start an elevated process to do the copying without showing the consent UAC dialog. Only Windows components are granted that ability.
But the bottom line is that you need to start a new process that runs elevated. Using the runas verb is the canonical way to do it.

Programming Elevated Privilege/UAC
Running applications with more privileges than required is against the
principle of least privilege, and may have potential security
vulnerability. To defend this, Windows Vista introduces User Account
Control (UAC), to protect operating system by running applications
with reduced privileges (as a normal user), even the current user is
signed in as an administrator. More and more XP/2K users are also use
normal user account for daily use. Read UAC Demystified first to fully
understand UAC.
There are two common mistakes that developers tend to make:
Request the end-user to run an application with administrator privilege even
though this is not necessary, most of the time because of bad design
practices. These applications either scare away end-users, or
potentially have security vulnerability.
Do not request the end-user
to run the application elevated but try to perform operations that
require administrator privilege. These applications simply break under
Windows Vista or Windows XP/2K normal user account.
The downloadable sample code demonstrates how to programming elevated
privilege/UAC. Both WPF and Windows Forms sample applications are
provided. Run the application for the following scenarios to see the
difference:
Normal user, Windows XP/Windows Vista: the UAC shield icon
is displayed. Clicking “Save to C:\” displays “Run As” dialog, asking
user to enter administrator password to continue;
Administrator, Windows XP/Windows Vista with UAC disabled: the UAC shield icon is
hidden. Clicking “Save to C:\” completed without any dialog;
Administrator, Windows Vista with UAC enabled: the UAC shield icon is
displayed. Clicking “Save to C:\” displays dialog asking user’s
permission to continue.
Link to Download
Calling the elevated execute (testing for admin first):
private void SaveToRootFolder_Click(object sender, EventArgs e)
{
string fileName = #"C:\Test.txt";
if (App.IsAdmin)
DoSaveFile(textBox1.Text, textBox2.Text, fileName);
else
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("Text1", textBox1.Text);
parameters.Add("Text2", textBox2.Text);
parameters.Add("FileName", fileName);
string result = Program.ElevatedExecute(parameters);
if (!string.IsNullOrEmpty(result))
MessageBox.Show(result);
}
}
Elevated Executes:
internal static string ElevatedExecute(NameValueCollection parameters)
{
string tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, ConstructQueryString(parameters));
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
Uri uri = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
startInfo.FileName = uri.LocalPath;
startInfo.Arguments = "\"" + tempFile + "\"";
startInfo.Verb = "runas";
Process p = Process.Start(startInfo);
p.WaitForExit();
return File.ReadAllText(tempFile);
}
catch (Win32Exception exception)
{
return exception.Message;
}
finally
{
File.Delete(tempFile);
}
}

A limited option, useful only when Moving, Renaming, Copying, and Deleting files:
SHFileOperation
If you attempt to perform a file operation via this function, Windows will provide the elevation prompt to the user.
Note there are some drawbacks for this:
This only works for Moving, Renaming, Copying, and Deleting. Saving a new file this way would require saving to a temp directory, then Moving it to the desired location. This does not solve the problem of the Save File Dialog not allowing you to select a UAC protected location as a target.
If the target directory doesn't exist (for a Move or Copy), SHFileOperation can prompt the user if the target directory should be created. However, it will NOT ask for elevated privileges to do so, and so will fail under a UAC protected location. The workaround for this is to manually create the non-existent directories in a temporary location, then Move/Copy them to the target location. This WILL provide the UAC prompt.
You need to have contingency plans in place for if the user selects 'Skip' or 'Cancel' to the Move/Copy dialog, or if the user selects 'No' at the UAC prompt.

Related

Prompt for user input during installation

I have developed a vb.net desktop app that connects and interacts with a database. Ideally, I would like to set up the publication project to prompt for user input during installation of the app (when running the *.msi file). Then, this input could be used as constants within the application. This way, the admins can enter the connection info during install rather than managing through config files, etc.
Prompts would include Username, Password, Database name.
Is this possible or is there a better way of implementing this functionality?
Not during install but this is how I accomplish a similar task.
Add a setting to your application called IsUpgrade and set it to true.
Create a settings form to set all of the values you need.
Once the application is installed, have the admin launch it.
Check for IsUpgrade in your starting form load event.
If IsUpgrade then
FormSettings.Show()
'Save settings in FormSettings closing event
My.Settings.IsUpgrade = False
End If

OSP Control Automatic Logon Feature Fail

I have an Okuma OSP Machine Controller running Windows XP.
By default it attempts to automatically log on when the machine is turned on.
We have changed the default administrator password and now the auto-log on fails every time.
How can I turn off this feature or update the password so that it succeeds?
Machine Types Effected: Any machine with P200 or P300 control running Windows-XP
4/1/2014: Confirmed the same applies to new OSP-300 Windows 7 controls
2/1/2015: There is another (easier) way to accomplish this on Okuma controls.
This can be done using a utility in the TOOLS directory called the "Auto Logon Setting Tool". This is perfect for anyone uncomfortable with editing the registry.
Tool location:
The utility:
Just choose the user you wish to to be logged on automatically, and click the "Register auto log-on" button.
This feature is enabled from the factory to allow users to get up and running quickly while still having the machine password protected. Because it is recommended to change the default password this is most likely a very common situation.
The automatic login behavior can be changed by editing registry settings.
Click Start, type "regedit" (sans-quotes) in the run box, and press enter.
In the folder structure in the left pane, navigate to the following folder:
> HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
To turn the feature OFF, change the key value of "AutoAdminLogon" to '0'
Similarly, the default user name and password can be changed by editing the appropriate keys to restore the functionality of the auto login feature.
Reference Microsoft Support article here.

Vb.net program login using local admin account

I write a program which need user login using local admin account.
But local admin account name is different for every PC, so I cannot hard code the user name.
Below code only retrieved the user in Administrators group, but not authentication. Can help?
1. How to authentication username & password?
2. How to force user to login using local user account only.
Dim localMachine As New DirectoryEntry("WinNT://" & "localhost")
Dim admGroup As DirectoryEntry = localMachine.Children.Find("Administrators", "group")
Dim members As Object = admGroup.Invoke("members", Nothing)
For Each groupMember As Object In CType(members, IEnumerable)
Dim member As New DirectoryEntry(groupMember)
MsgBox(member.Name)
Next
The best and simplest way of ensuring that your application runs with administrative privileges is to embed a manifest that makes just such a demand.
You should never hard-code anything like this, and the presence of UAC means there is no guarantee that a user who is a member of the Administrators group has administrative privileges at the moment for your process.
The VB.NET compiler embeds a default manifest into your application automatically, but that default manifest doesn't request administrative privileges. So you need to add a custom manifest that does.
To get one, follow these steps:
Right-click on your project in the Solution Explorer.
Select "Properties" from the context menu.
Switch to the "Application" tab.
Click "View Windows Settings" to open the manifest file.
Make the following modification:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

Can I run RegAsm without being Administrator?

My coworker is trying to register some COM components (which I wrote) via RegAsm.exe and it says he needs Administrator privileges. His account has admin privileges but he is not logged in as Administrator. Is there a way to use his regular user account and succeed at this task?
I work in an environment/jurisdiction where giving local admin access to all users is simply not possible (legal/compliance/regulations will not allow).
It appears there is no equivalent of this function in .NET world: AtlSetPerUserRegistration
Try this: Using regasm, generate the registry entries with /regfile argument. By default, registry entries should use HKEY_CLASSES_ROOT (HKCR) as a root. Modify the entries (manually, or by script) to use HKEY_CURRENT_USER (HKCU).
Finally, distribute your .NET DLL with the registry script. You can still run regedit without admin rights to register your .NET DLL. Manually from the command line, using a batch file, or a (tiny) separate installation program can handle the registration.
Admin privileges are required to allow Regasm.exe to update the registry. If this is a UAC restriction then create a shortcut on the desktop for cmd.exe and check the "Run this program as an administrator" checkbox. Or change this setting on the Visual Studio Command Prompt shortcut, that's easier.
I think this question belongs elsewhere, but Windows uses least privilege so if he is a user that is both a normal user and an Administrator than he gets normal user privileges. Use runas to make this work or right click the item and "run as administrator"
Why don't you use registration free com? Its only been supported since 2003 and obviates the need for UAC / administrative access to install COM components.
With RegFree COM you can just bundle the COM dlls with the application that uses them as a private assembly - but that doesn't mean they can't be properly installed - either in the registry or in WinSxS by the final deployment install.exe/msi
Subtext wrt the actual query: no - COM registration is in the HKEY_LOCAL_MACHINE key that always requires administrative access.
I lied: Actually you can. If you create a application with no manifest at all, Windows deduces that its an XP era application that expects administrative access to run and will activate a compatibility mode that, amongst other features, redirects write access to HKLM to a writable location under HKCU. So the COM component registration "succeeds" - but is registered for the current user only.
Im not sure why the ability to register for just the current account isn't supported generally outside the compatibility framework.
Check this out: https://gist.github.com/florentbr/6be960752fc852ee99eece6b4acb8ba7
I was trying to do the same thing and was about to give up when I came upon it.
It's a cmd script that will register the SeleniumBasic.dll in the registry without having admin privileges. With a bit of work you should be able to repurpose the code to register your COM components.
Many, many thanks to Florent Breheret for SeleniumBasic and this cmd script to register it!
I am logged into an account that has Administrator privileges. But RegAsm.exe still says it needs Administrator privileges.
[From some notes I have for Windows 2008 R2. Confirm on other Windows operating systems that support UAC. The following assumes that you are permitted to make changes to the Local Security Policy. ]
In its default configuration, User Account Control (UAC) settings give the local Administrator full privileges, but restrict the privileges of other members of the Administrators group. To lift the UAC restrictions on other members of the Administrators group, do the following:
Select Start -> All Programs -> Administrative Tools -> Local Security Policy.
Select Local Policies -> Security Options.
In the right panel, double-click the third entry from the bottom which reads User Account Control: Run all administrators in Admin Approval Mode.
Click Disabled.
Click OK to close the dialog and close the Local Security Policy configuration tool.
Reboot the computer to complete this change to the UAC settings.

Starting a process as an other user in OnAfterInstall gets access denied

I'm tryning to start a .bat file as the last step in OnAfterInstall in the context of an other user. I'm doing this by using the Process.Start overload with user name, domain and password as input. It works fine if I do not check the 'Everyone' in the installation. If i have the 'Everyone' selected I get access denied, with the same user (administrator). If I run the installment using the .start method with just the proccess name it work fine.
To test this I made a Windows froms application that start the proccess the same way after I install using 'Everyone', and it works fine.
Does anyone know why I can't access the file in OnAfterInstall with 'Everyone' selected, using an other user context?
Most likely when you check everyone you are telling the install program it doesn't need elevate permissions so it doesn't ask for them. Even when you run as an admin in windows vista or 7 your process token is that of a user until the UAC elevates you. There are a set of polices you need to be able to call createprocessasuser which is what is happening underneath. Give all polices related to the above api to everyone and then see if it works.