How to run a C # application with administrator privileges?

I wrote a C # application that unlocks users when they are locked out of their account (Active Directory). The application searches for users in a specific department and displays blocked users in ComboBox. Then you select this user from ComboBox and choose unlock.

If you are logged in as an administrator, it works fine. If you are not a regular user.

I want to run my application using admin admins, but as a regular user it is also as safe as possible.

I read that it might be a program for Windows, but I don’t know how to program my application for installation, run as a service, and run under administrator accounts.

+6
c # windows-services
source share
7 answers

It looks like you want to impersonate the admin user. Here's an article and a demo . You want to write in .Net 1, but you need to start. Also check out the WindowsIdentity class.

+1
source share

The purpose of this application seems wrong to me. Basically, you are trying to create a tool that allows non-administrator users to unblock accounts ... which, for good reason, is a feature inaccessible to ordinary users.

+8
source share

You do not need to use the Windows service to do something like someone else. You can use impersonation to log in as another user for the actual switch. Here is an example that I found for logging into the Windows dll "advapi32.dll".

Take the sample code at the bottom of the page. I did not want to just copy his code here.

http://csharptuning.blogspot.com/2007/06/impersonation-in-c.html

One impersonation bar, however, is that the impersonating computer must be in the same domain as the user that impersonates.

+2
source share

Here is a class that I use to perform impersonation on an ASP.NET 2.0 website running on Windows 2000.

Usage example:

if (iu.impersonateValidUser("AdminUserName", "DomainName", "AdminPassword")) { // Do Something Under Other Users Security Context iu.undoImpersonation(); } 

What is it ... Full class below.

 using System; using System.Runtime.InteropServices; using System.Security.Principal; public class ImpersonateUser { public const int LOGON32_LOGON_INTERACTIVE = 2; public const int LOGON32_PROVIDER_DEFAULT = 0; WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")] public static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern bool CloseHandle(IntPtr handle); public bool impersonateValidUser(String userName, String domain, String password) { WindowsIdentity tempWindowsIdentity; IntPtr token = IntPtr.Zero; IntPtr tokenDuplicate = IntPtr.Zero; if (RevertToSelf()) { if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0) { if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); impersonationContext = tempWindowsIdentity.Impersonate(); if (impersonationContext != null) { CloseHandle(token); CloseHandle(tokenDuplicate); return true; } } } } if (token != IntPtr.Zero) CloseHandle(token); if (tokenDuplicate != IntPtr.Zero) CloseHandle(tokenDuplicate); return false; } public void undoImpersonation() { impersonationContext.Undo(); } } 
+2
source share

You cannot use the Windows service (easily) because the Windows service cannot have a graphical interface. The only way to do this as a service is to install the service, and then make a GUI application that used IPC to pass the request to the service. However, this will open a potential loophole.

If you are running Vista, a good option would be to edit the manifest file and add requireAdministrator.


Edit:

It seems like my first suggestion might be what you want ... For this, the main process:

  • Make your application a Windows service. MSDN has a walkthrough of this process .
  • Make your service the answer to some form of IPC. You can use sockets, pipes or any other form of communication. The service will “listen” for a user unlock request, and then complete this.
  • Install the service on the machine. This will make him work as an administrator, and always will be.
  • Make a second application to work as a client. Use the same IPC technology to communicate with the server. This will send a client unlock request for this service.

Then you can start the client as a regular user (since he just needs to talk to the service, he does not do anything that requires permission).

0
source share

I have a very similar widget on my intranet site, so members of the IT department located in different time zones can handle password resetting, which also unlocks the account when domain administrators on the west coast are unavailable. These are fairly simple tasks, and with the exception of how I did this ...

  using System.DirectoryServices; // Impersonate the Admin to Reset the Password / Unlock Account // // Change variables below. ImpersonateUser iu = new ImpersonateUser(); if (iu.impersonateValidUser("AdminUserName", "DomainName", "AdminPassword")) { resetPassword("AdminUserName", "AdminPassword", UserToReset, "NewPassword"); iu.undoImpersonation(); } // Perform the Reset / Unlock // public void resetPassword(string username, string password, string acct, string newpassword) { string Path = // LDAP Connection String string Username = username; string Password = password; string Domain = "DomainName\\"; // Change to your domain name DirectoryEntry de = new DirectoryEntry(Path, Domain + Username, Password, AuthenticationTypes.Secure); DirectorySearcher ds = new DirectorySearcher(de); ds.Filter = "(&(objectClass=user)(|(sAMAccountName=" + acct + ")))"; ds.PropertiesToLoad.Add("displayName"); ds.PropertiesToLoad.Add("sAMAccountName"); ds.PropertiesToLoad.Add("DistinguishedName"); ds.PropertiesToLoad.Add("CN"); SearchResult result = ds.FindOne(); string dn = result.Properties["DistinguishedName"][0].ToString(); DirectoryEntry uEntry = new DirectoryEntry("LDAP://" + dn, username, password); uEntry.Invoke("SetPassword", new object[] { newpassword }); uEntry.Properties["LockOutTime"].Value = 0; uEntry.CommitChanges(); uEntry.Close(); } 

I strongly agree that this can lead to security problems if used improperly, each change is registered and sent by e-mail to the domain administrators (therefore, in a loop), and we automatically generate passwords. This was a huge help for our small IT department, since admins no longer need to wake up from 4:00 to reset the password.

0
source share

This code will allow you to call another executable file and run it as an administrator.

 try { path = path_to_your_executable; ProcessStartInfo myProcess = new ProcessStartInfo(path); myProcess.Domain = domain; myProcess.UserName = username; myProcess.Password = password; myProcess.UseShellExecute = false; Process.Start(myProcess); } catch (Exception myException) { // error handling } 

Not exactly what you are looking for, but it is a possible solution.

0
source share

All Articles