util/winutil: publicize existing functions for opening read-only connections to the Windows Service Control Manager

We're going to need to access these from code outside winutil.

Updates #10215

Signed-off-by: Aaron Klotz <aaron@tailscale.com>
pull/10679/head
Aaron Klotz 11 months ago
parent cae6edf485
commit 5812093d31

@ -60,13 +60,13 @@ type walkSvcFunc func(*mgr.Service, mgr.Config)
// walkServices opens the service named rootSvcName and walks its dependency // walkServices opens the service named rootSvcName and walks its dependency
// graph, invoking callback for each service (including the root itself). // graph, invoking callback for each service (including the root itself).
func walkServices(rootSvcName string, callback walkSvcFunc) error { func walkServices(rootSvcName string, callback walkSvcFunc) error {
scm, err := connectToLocalSCMForRead() scm, err := ConnectToLocalSCMForRead()
if err != nil { if err != nil {
return fmt.Errorf("connecting to Service Control Manager: %w", err) return fmt.Errorf("connecting to Service Control Manager: %w", err)
} }
defer scm.Disconnect() defer scm.Disconnect()
rootSvc, err := openServiceForRead(scm, rootSvcName) rootSvc, err := OpenServiceForRead(scm, rootSvcName)
if err != nil { if err != nil {
return fmt.Errorf("opening service %q: %w", rootSvcName, err) return fmt.Errorf("opening service %q: %w", rootSvcName, err)
} }
@ -102,7 +102,7 @@ func walkServices(rootSvcName string, callback walkSvcFunc) error {
continue continue
} }
depSvc, err := openServiceForRead(scm, depName) depSvc, err := OpenServiceForRead(scm, depName)
if err != nil { if err != nil {
return fmt.Errorf("opening service %q: %w", depName, err) return fmt.Errorf("opening service %q: %w", depName, err)
} }
@ -276,10 +276,10 @@ func makeLogEntry(svc *mgr.Service, status svc.Status, cfg mgr.Config) (entry sv
return entry return entry
} }
// connectToLocalSCMForRead connects to the Windows Service Control Manager with // ConnectToLocalSCMForRead connects to the Windows Service Control Manager with
// read-only access. x/sys/windows/svc/mgr/Connect requests read+write access, // read-only access. x/sys/windows/svc/mgr/Connect requests read+write access,
// which requires higher privileges than we want. // which requires Administrative access rights.
func connectToLocalSCMForRead() (*mgr.Mgr, error) { func ConnectToLocalSCMForRead() (*mgr.Mgr, error) {
h, err := windows.OpenSCManager(nil, nil, windows.GENERIC_READ) h, err := windows.OpenSCManager(nil, nil, windows.GENERIC_READ)
if err != nil { if err != nil {
return nil, err return nil, err
@ -287,10 +287,10 @@ func connectToLocalSCMForRead() (*mgr.Mgr, error) {
return &mgr.Mgr{Handle: h}, nil return &mgr.Mgr{Handle: h}, nil
} }
// openServiceForRead opens a service with read-only access. // OpenServiceForRead opens a service with read-only access.
// x/sys/windows/svc/mgr/(*Mgr).OpenService requests read+write access, // x/sys/windows/svc/mgr/(*Mgr).OpenService requests read+write access,
// which requires higher privileges than we want. // which requires Administrative access rights.
func openServiceForRead(scm *mgr.Mgr, svcName string) (*mgr.Service, error) { func OpenServiceForRead(scm *mgr.Mgr, svcName string) (*mgr.Service, error) {
svcNamePtr, err := windows.UTF16PtrFromString(svcName) svcNamePtr, err := windows.UTF16PtrFromString(svcName)
if err != nil { if err != nil {
return nil, err return nil, err

Loading…
Cancel
Save