Solved

Cannot start [service name] service from computer '.'. Access Denied

Posted on 2011-02-14
13
829 Views
Last Modified: 2012-05-11
Hello All,
 I have a Windows Service(of Account- LocalSystem) which has to be started from a VB.NET Windows Application whose UAC level is set to "asInvoker". If i start the Service manually it works. If i launch the Windows Application through - launch option from Finish Dialog of Setup Installation Process(Run As Administrator)  also starts the Service.. But by programmatically, using mySPCObject.Start()  - throws an Error "Cannot start [service name] service from computer '.'. Access Denied."

Looks like Sufficient privilege is not there for that user..? If so how do i set the access rights programmatically to start the service ?

Any help appreciated...


0
Comment
Question by:depaa
  • 6
  • 3
  • 2
  • +2
13 Comments
 
LVL 9

Expert Comment

by:Deathrace
ID: 34887514
You have to run the same code with admin previleges by using Impersonation concept.

try this
http://www.dotnetspider.com/resources/38277-Impersonation-prgrammatically.aspx
0
 
LVL 9

Expert Comment

by:Deathrace
ID: 34887517
the above post help you to understand impersonation , use the same concept for you code
0
 
LVL 2

Expert Comment

by:JRWoehler
ID: 34887534
This code is C#, but you should be able to find a good VB.NET converter out there somewhere.   It also looks like I left some unnecessary references at the top.  I don't think the System.Web stuff is necessary.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Principal;
using System.Runtime.InteropServices;

/// <summary>
/// Summary description for Impersonator
/// </summary>
public class Impersonator : IDisposable
{
    private WindowsImpersonationContext impersonationContext;

    #region Dll Import Declarations

    public const int LOGON32_LOGON_INTERACTIVE = 2;
    public const int LOGON32_PROVIDER_DEFAULT = 0;

    [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);

    #endregion

    public Impersonator(string userId, string password, string domain)
	{
        if (!impersonateValidUser(userId, domain, password)) {
            //throw new Exception("User impersonation failed for user: '" + userId + "'.");
            uint errorCode = WinSystem.GetLastError();
            throw new ApplicationException("User impersonation failed for user: '" + userId + "'.  " +
                                           WinSystem.GetMessage((int)errorCode));
        }
	}

    #region IDisposable Members

    void IDisposable.Dispose() {
        undoImpersonation();
    }

    #endregion

    private 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;
    }
    private void undoImpersonation() {
        impersonationContext.Undo();
    }

}

Open in new window


Once you get this converted and compiling, use the following to impersonate the user with appropriate authorizations:
using (new Impersonator(userId, pw, domain)) {
   // start the service here...
}

Open in new window

0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 34891034
Impersonation won't work with UAC enabled because you will just pickup the *user end of the split token.

1) Create a seperate executable manifested with requireAdministrator and add your service code inside this process.
2) Create elevated COM object for your main application (alot of work but the best option)
3) Create another service that runs under LocalSystem that manages all your work services this should be installed during setup. You can send commands to the service and have the service itself do the work.
0
 

Author Comment

by:depaa
ID: 36805005
thanks for all your replies.. I am busy with some other work, will get back soon
0
 

Author Comment

by:depaa
ID: 37324021
Hello All,

Excuse me for my ignorance, if any. I have tried impersonator. Did not work. What eql1044 had asked s really a bit too much work to make things slow.

What I did not mention clearly in my earlier question/comment is that - this code has to work with a product and will have to work when installed on users machine - first of all - the user may use any OS - XP / Vista / Win7 / Windows 2003 Server or Windows 2008 Server - with any version, any bit - 32 / 64 - but, my product should work fine.

The user is free to enable firewall, UAC, anti-virus - s/he should be totally free to anything s/he likes.

Given this new situation - please advise.

Regards
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 37328012
0
 

Author Comment

by:depaa
ID: 37339155
Hi

I have done all these.

Once again - I want to clarify that - the "Service" is to be started from a VB.NET windows application which was installed (Setup.exe) as "Admin" but, when it runs - it runs as "User"

The installer (setup.exe ) is supposed to Install the service on the user machine.

The VB.Net application is supposed to start the Windows service. Since this VB.Net application starts as "user" - it is not able to start the service which needs to be started as "admin"

Any help will be highly appreciated.

Thanks
Depaa
www.goace.com 
0
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 37362688
>Since this VB.Net application starts as "user" - it is not able to start the service which needs to be started as "admin"

And the solution for this is to request admin elevation before starting the service which is what was suggested.
0
 

Author Comment

by:depaa
ID: 37366385
I understand your frustration with my understanding..

But, if the application which start as "User" by common windows user, asks for an elevation as "Admin" - every time the user start this application - they have to call the administrator - which is not practical.

The service is a License watchdog without the knowledge of the user.

Is it possible to install the service ( install time - the administrator installs - so elevation is not an issue) in such a way that whenever it is invoked by the application which is started as "User", the service should be started as "Admin" ? That is the main question..
0
 
LVL 83

Accepted Solution

by:
CodeCruiser earned 125 total points
ID: 37366410
What account is the service installed under? I think its installed to run under System or Network account which does not have much permissions. Install it to run under an admin account and then there should be no problem starting it.
0
 

Author Comment

by:depaa
ID: 37367319
I will try this on 9th or10th Jan and will get back to you.
Thanks
0
 

Author Closing Comment

by:depaa
ID: 37439003
Thanks
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question