Solved

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

Posted on 2011-02-14
13
817 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
Comment Utility
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
Comment Utility
the above post help you to understand impersonation , use the same concept for you code
0
 
LVL 2

Expert Comment

by:JRWoehler
Comment Utility
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
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
Comment Utility
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
Comment Utility
thanks for all your replies.. I am busy with some other work, will get back soon
0
 

Author Comment

by:depaa
Comment Utility
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 83

Expert Comment

by:CodeCruiser
Comment Utility
0
 

Author Comment

by:depaa
Comment Utility
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
Comment Utility
>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
Comment Utility
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
Comment Utility
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
Comment Utility
I will try this on 9th or10th Jan and will get back to you.
Thanks
0
 

Author Closing Comment

by:depaa
Comment Utility
Thanks
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This video discusses moving either the default database or any database to a new volume.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

728 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now