views:

35

answers:

2

Here's the code (in a standard TService in Delphi):

const
  ProcessExe = 'MyNetApp.exe';

function RunService: Boolean;
var
  StartInfo : TStartupInfo;
  ProcInfo : TProcessInformation;
  CreateOK : Boolean;
begin 
  CreateOK := false;
  FillChar(StartInfo,SizeOf(TStartupInfo),#0);
  FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
  StartInfo.cb := SizeOf(TStartupInfo);
  CreateOK := CreateProcess(nil, PChar(ProcessEXE),nil,nil,False,
                    CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
                    nil, PChar(InstallDir), StartInfo, ProcInfo);
  CloseHandle(ProcInfo.hProcess);
  CloseHandle(ProcInfo.hThread);
  Result := CreateOK;
end;

procedure TServicel.ServiceExecute(Sender: TService);
const
  IntervalsBetweenRuns = 4; //no of IntTimes between checks
  IntTime = 250; //ms
var
  Count: SmallInt;
begin
  Count := IntervalsBetweenRuns;  //first time run immediately
  while not Terminated do
  begin
    Inc(Count);
    if Count >= IntervalsBetweenRuns then
    begin
      Count := 0;
      //We check to see if the process is running,
      //if not we run it. That's all there is to it.
      //if ProcessEXE crashes, this service host will just rerun it
      if processExists(ProcessEXE)=0 then
        RunService;
    end;
    Sleep(IntTime);
    ServiceThread.ProcessRequests(False);
  end;
end;

MyNetApp.exe is a SOCKS5 proxy listening on port 9870. Users configure their browser to this proxy which acts as a secure-tunnel/anonymizer.

All works perfectly fine on 2000/XP/2003, but on Vista/Win7 with UAC the service runs in Session0 under LocalSystem and port 9870 doesn't show up in netstat for the logged-in user or Administrator.

Seems UAC is getting in my way.

Is there something I can do with the SECURITY_ATTRIBUTES or CreateProcess, or is there something I can do with CreateProcessAsUser or impersonation to ensure that a network socket on a service is available to logged-in users on the system (note, this app is for mass deployment, I don't have access to user credentials, and require the user elevate their privileges to install a service on Vista/Win7)

A: 

Turns out that the problem has nothing to do with the port not being visible under netstat. I ran another test with a prior build on a Win7 machine and even when netstat doesn't show the port listening either as Administrator or a regular user, then browsers can still bind to the port (why would this be?)

What's actually happening is that MyNetApp.exe is failing to run correctly (only on Win7) since when running under the NT AUTHORITY\SYSTEM account it isn't able to read files in C:\ProgramData\ (%ALLUSERPROFILE%) -- it needs files that my client is placing in subfolders under there.

When I check "Effective Permissions" for the SYSTEM user on these files I'm getting Full Control.

What's going on?

UPDATE: No that's not it either. MyNetApp.exe is being told where it's config files are by reading a string in HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MyApp\ which I set during install (to %ALLUSERPROFILE%\MyCompany\MyApp. Seems what it's getting is an empty string, which is breaking it. Why on earth would NT AUTHORITY\SYSTEM not be getting the same string as the one I set in the installer (running with elevated privileges so it can install the service)

rwired
A: 

A service should be able to read the HKLM hive. When you create the Registry handle make sure you set the Access setting to KEY_READ (ARegHandle.Access := KEY_READ;) and also when you open the key, open in it with Create as false or OpenReadOnly.

vicky
This was the problem, thanks. I wasn't paying close enough attention to the Reg permissions in my NetApp, and barking up the wrong tree as to why it was working when debugging, but not when running as NT AUTHORITY\SYSTEM
rwired