Solved

Remote OpenSCManager

Posted on 2001-07-01
23
1,982 Views
Last Modified: 2013-12-03
Hi

I try to install/start/stop a service on a remote computer.
So first I have to open the service manager using OpenSCManager with the needed rights.
But then I get a access denied error. I guess I have to enter a username and password somewhere, but how ?
I don't see a way to pass a username and password to the function, what to do ?
0
Comment
Question by:sorentop
  • 12
  • 11
23 Comments
 

Author Comment

by:sorentop
ID: 6242685
BTW I'm logged on as administrator
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242739
You'll have to make sure that the admin password is the same on both machines or that they're connected to a domain with you being logged on as the Domain Admin.
0
 

Author Comment

by:sorentop
ID: 6242776
But what if this is not the case.
From the control panel, you can do it via computer management and then connect to the computer.
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242825
Hmm, just found some sample code at http://www.codeguru.com/system/NTSrv.shtml - the idea seems to be to 'RegConnectRegistry()' before using 'OpenSCManager()':

      if(m_strWkstaName.CompareNoCase(GetLocalMachineName()) == 0)
            lRet = RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hMachineKey);
      else
      {
            CString strUNCName = _T("\\\\") + m_strWkstaName;
            RedrawWindow();
            CString strText;
            strText.Format(_T("Connecting to registry database of computer %s..."), m_strWkstaName);
            m_stStatus.SetWindowText(strText);

            lRet = RegConnectRegistry(strUNCName, HKEY_LOCAL_MACHINE, &hMachineKey);
      }

      if(lRet == NO_ERROR)
      {
            lRet = RegOpenKey(hMachineKey, "SYSTEM\\CurrentControlSet\\Services", &hRegServicesKey);

            if(lRet == NO_ERROR)
            {
                  DWORD dwSubKeys = 0, dwMaxSubKeyNameLen = 0;
                  lRet = RegQueryInfoKey(hRegServicesKey, NULL, NULL, NULL, &dwSubKeys, &dwMaxSubKeyNameLen,
                        NULL, NULL, NULL, NULL, NULL, NULL);

                  SC_HANDLE hSCManager = OpenSCManager(m_strWkstaName, NULL, GENERIC_READ);

                  if(hSCManager != NULL)
                  {
                        DWORD dwIndex = 0;
                        char pszServiceName[128];
                        char pszDisplayName[128];
                        char pszStartup[128];
                        char pszStatus[128];
                        DWORD dwServiceNameLen = 128;
                        DWORD dwDisplayNameLen = 128;

                        m_stStatus.ShowWindow(SW_HIDE);
                        m_progRegistry.ShowWindow(SW_SHOW);
                        m_progRegistry.SetRange32(1, (int)dwSubKeys);
                        m_progRegistry.SetPos((int)dwIndex);

                        do
                        {
                              //      RegQueryInfoKey
                              dwServiceNameLen = dwMaxSubKeyNameLen;
                              lRet = RegEnumKey(hRegServicesKey, dwIndex, pszServiceName, dwServiceNameLen);

                              if(lRet == ERROR_NO_MORE_ITEMS)
                                    break;

                              if(lRet != NO_ERROR)
                              {
                                    dwIndex++;
                                    continue;
                              }

                              BOOL bClose = FALSE;

                              dwDisplayNameLen = 64; // reset length
                              if(GetServiceDisplayName(hSCManager, pszServiceName, pszDisplayName, &dwDisplayNameLen))
                              {
                                    QUERY_SERVICE_CONFIG qsc;
                                    SERVICE_STATUS ss;

                                    DWORD dwBytesNeeded = 0;

                                    // pass a false size to QueryServiceConfig (for 5 strings)
                                    DWORD dwFalseSize = sizeof(QUERY_SERVICE_CONFIG) + 5 * (1 + _MAX_PATH);

                                    SC_HANDLE hService = OpenService(hSCManager, pszServiceName, SERVICE_ALL_ACCESS);

                                    BOOL bQuery = QueryServiceConfig(hService, &qsc, dwFalseSize, &dwBytesNeeded);

                                    if(bQuery)
                                          strcpy(pszStartup, GetStartupString(qsc.dwStartType));
                                    else
                                    {
                                          ShowLastError(TRUE);

                                          if(QueryServiceConfig(hService, &qsc, dwBytesNeeded, &dwBytesNeeded))
                                                strcpy(pszStartup, GetStartupString(qsc.dwStartType));
                                          else
                                                strcpy(pszStartup, ShowLastError(TRUE));
                                    }

                                    if(!(qsc.dwServiceType & m_dwType))
                                          goto _next;
                                    
                                    bClose = CloseServiceHandle(hService);
                                    hService = 0;

                                    hService = OpenService(hSCManager, pszServiceName, GENERIC_READ);
                                    if(hService)
                                    {
                                          if(QueryServiceStatus(hService, &ss))
                                                strcpy(pszStatus, GetStatusString(ss.dwCurrentState));
                                          else
                                                strcpy(pszStatus, ShowLastError(FALSE));
                                    }
                                    else
                                          continue;
                                    
                                    CloseServiceHandle(hService);
//                                    hService = 0;
                                    
                                    if(((m_dwStatus == SERVICE_ACTIVE) && (ss.dwCurrentState == SERVICE_STOPPED))      ||
                                       ((m_dwStatus == SERVICE_INACTIVE) && (ss.dwCurrentState != SERVICE_STOPPED)))
                                          goto _next;

                                    InsertInList(pszServiceName, pszDisplayName, pszStatus, pszStartup,
                                          ss.dwCurrentState, qsc.dwStartType);
                              }
                              else
                              {
                                    if(fLog)
                                    {
                                          CString strErr;
                                          strErr.Format(_T("%s#%s"),
                                                pszServiceName, ShowLastError(FALSE));

                                          fprintf(fLog, "%s\n", strErr);
                                          nErrCnt++;
                                    }
                              }
_next:
                              dwIndex++;
                              m_progRegistry.SetPos((int)dwIndex);

                        } while(TRUE);
                  }
                  else
                        ShowLastError();

                  CloseServiceHandle(hSCManager);
            }
            else
                  ShowLastError();

            RegCloseKey(hRegServicesKey);
      }
      else
            ShowLastError(lRet, TRUE);

      RegCloseKey(hMachineKey);


0
 

Author Comment

by:sorentop
ID: 6242887
well when I try RegConnectRegistry I get a access denied so that doesn't help me... I guess
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242903
>>well when I try RegConnectRegistry I get a access denied
>>so that doesn't help me

Well, THAT's certainly username/password related. One way out would be e.g. establishing a NULL session to the machine you want to start the service at - see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample98/html/vcsmpnullsess.asp :

"NullSess Sample: Using Null Session for Access Problems
[...]

This sample illustrates how to use a Null session to overcome access problems during network related query operations."
0
 

Author Comment

by:sorentop
ID: 6242907
According to Win32 sdk:
the OpenSCManager function fails if the calling process does not have administrator privileges.
Is it possible to set administrator privileges for my program ?
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242913
>>Is it possible to set administrator privileges for my
>>program ?

Err, you wrote: "BTW I'm logged on as administrator"

Well, all SCM related functions that do more than e.g. service enumeration need amin privileges. The only way (if you're not already logged on as an administrator) would be using 'LogonUser()'/'ImersonateLoggedOnUser()'...
0
 

Author Comment

by:sorentop
ID: 6242920
Yes i'm logged in as administrator, so the program automatic has administrator privileges. stupid question I guess
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242924
BTW: Could you just try to set the Admim PWD on your machine to the same that's used on the machine you want to start the service on? I'm pretty sure that this should remedy the problem...
0
 

Author Comment

by:sorentop
ID: 6242942
Yes you are right that fixes the problem. But the password's must be different, so I will just change it back :)

I don't know if I'm getting stupid, but I can't find the sample, I click on your url and the page says I should
"Click to open or copy the files for the NullSess sample"
but there is only a link to: Building SDK Samples
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 86

Expert Comment

by:jkr
ID: 6242952
Well, if you have VC++, you'll find the sample via the accompanying MSDN distribution.

Just one thing that might remedy your problem also:

    HANDLE          hToken  =   NULL;

    if  (   LogonUser   (   "Administrator",
                            ".\\<machine>,
                            "<password>",
                            LOGON32_LOGON_INTERACTIVE,
                            LOGON32_PROVIDER_DEFAULT,
                            &hToken
                        )
        )   ImpersonateLoggedOnUser (   hToken);

    // do the service related operations

    RevertToSelf ();
0
 
LVL 86

Expert Comment

by:jkr
ID: 6242954
Ooops,

".\\<machine>,

should of course read

".\\<machine>,"

(the '.\\' is mandantory)
0
 

Author Comment

by:sorentop
ID: 6243006
hmm I'm sorry but the LogonUser fails
0
 
LVL 86

Expert Comment

by:jkr
ID: 6243014
You'll have to grant the 'SE_TCB_NAME' to the admin account of your machine (and logoff) - this is required for 'LogonUser()', and not automatically granted.
0
 

Author Comment

by:sorentop
ID: 6243045
Just to make sure.
Should I have to log off and then on again, after getting the admin right, before I can use the LogonUser ?
0
 
LVL 86

Expert Comment

by:jkr
ID: 6243089
Well, use the user manager (or the W2k equivalent) to grant the SE_TCB_NAME ("Act as Part of the Operating System") to the Admin account (you must be admin to do this). Then, log off and log back on to activate the new set of credentials.
0
 

Author Comment

by:sorentop
ID: 6243109
OK, but I'm sorry I can't accept that as a sollution to the problem.
I'm sorry to turn down all your work.
0
 
LVL 86

Accepted Solution

by:
jkr earned 200 total points
ID: 6243115
>>OK, but I'm sorry I can't accept that as a sollution to
>>the problem.

Err, why? You'll hardly find a different one...
0
 

Author Comment

by:sorentop
ID: 6243122
Yes I know, but it is possible using the computer management, so it must be possible somehow.
0
 
LVL 86

Expert Comment

by:jkr
ID: 6243136
>>but it is possible using the computer management

Without corresponding passwords, this is hardly possible. Does this work under the same admin account with the same (different) password?
0
 

Author Comment

by:sorentop
ID: 6243137
well I will just give you the points and re-ask the question.
If you find a solution somehow, please write it here :)
0
 

Author Comment

by:sorentop
ID: 6243142
Yes it does
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

759 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

17 Experts available now in Live!

Get 1:1 Help Now