[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference decwet::nt-developers

Title:MS Windows NT Developers
Notice:See note 1222 for MS bug reporting info
Moderator:TARKIN::LINEIBER
Created:Mon Nov 11 1991
Last Modified:Tue Jun 03 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3247
Total number of notes:15633

3220.0. "Child Process invoking Command Interpreter with Subcommand, from a Service" by PTHRED::SHARRIS () Wed Apr 09 1997 12:24

We have an application that runs as a service on WNT.  When requested to
do so, this application has the ability to create a subprocess (child) with
the environment and startup values for the requesting user, and execute
the requested command.   Because we want to be able to execute shell
commands, we always launch the command like this:

	cmd /c user-command

This works fine for all shell-specific commands (like SET, DIR, etc).
But it doesn't work for cases like this:

	cmd /c hostname

Even tho this certainly does work interactively.

It isn't just a failure with ANY exe; a very simple exe that only does
"printfs" works fine.   But any non-trivial exe seems to fail.  

What happens is that the exe never gets activated by the CMD interpreter. (We
can see that visually with the Task Manager, and also by writing our own
copycat hostname program with some printfs at the top - we never get the
printfs.)  The CMD interpreter returns error 128 as an exit status to the
parent process ("No child process to wait for") and ERROR_NO_DATA to the
communication input pipe. 

The confusing issues are that:

	1) everything works if the parent process runs as an exe instead of
           as a service.  So we believe that there are not any path issues or 
           env. variable issues involved...

        2) everything works even *if* the parent process is a service, if
           it's NT 3.51.  The problem started appearing on NT V4.0.
           And it appears for both ALPHA and INTEL processors on V4.0.

        3) everything works even if it's a service and even if it's NT 4.0,
           if we don't precede the "hostname" command or "user-command" 
           with "cmd /c". So again there's evidence that the environment
           is properly setup for the command to work.  Except when cmd /c
           launches it (from a subprocess of an application running as
           a service).

           Unfortunately, since we want users to be able to do "SET" or
           "CD" commands, we need to have the command interpreter 
           involved. 

It seems that something about image activation or image initialization doesn't
work when the command interpreter is launched in this way. But without hooks
into either CMD or intialization code, we've been unable to determine what is
going on.   Or maybe there's a security issue here somewhere... 

We have tried inserting ntsd.exe into the mix, so that we could try to debug
the startup, as in:

	 cmd /c ntsd.exe program.exe

But in this case, it's just ntsd.exe that doesn't get activated.  It seems to
have the same problems as hostname and various other exes.  It never shows up
as a process in the NT task manager list.  Possibly also because ntsd tries to
create a window and it doesn't have access to the console. 

Also, this one is interesting:

	cmd /c set && hostname

Executes the set directive and passes back all the environment variables,
but then it gets the 128 error and never manages to load the hostname.exe.

Another thought was to do "cmd /c foo.bat"  where the batch file does
something like:

	sleep 15  (simple program)
        hostname 

During the sleep, we tried to attach to CMD.EXE with the debugger, but it only
shows one message about not being able to load the Kernel32 symbols, and then
it immediately shows "UNLOAD" messages, including an unload for APP01.EXE. 
(what is this?? any idea?)  And then it terminates with the error code 128.  We
never saw any "LOAD" messages for the hostname program. 

At first, we thought it was something related to wsock32.lib, since hostname
requires this.  But experiments with other executables shows that this isn't
really the culprit.  I do know that all the cases that fail are using this set
of DLLS, but that may just be coincidence, based on the test executables we
have: 

	rpcrt4.dll
	advapi32.dll
        gdi32.dll
        user32.dll
        ntdll.dll
        kernel32.dll

Does anybody have any other ideas about what might cause this problem?  Or ways
to try and debug it????  Or unique qualities of a service on NT 4.0? Any
information about how CMD /c works?  Presumably it also creates a subprocess
that inherits the existing environment.   So what we really have is a
subprocess of a subprocess of an image running from a service...? 

Oh yes.  The service is created with SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,  SERVICE_ERROR_NORMAL.

And, we are creating this child process with 0 for the dxCreationFlags which
gives it NormalPriorityClass.  At various times we thought this was a problem
with allocating the console, but setting CREATE_NEW_CONSOLE had no effect. 
Creating it as a DETACHED_PROCESS also did not make any difference.  Also, if
"hostname" requires a console, then case #3 above shouldn't really work, but it
does. 

The parent process also calls DuplicateHandle with PROCESS_ALL_ACCESS.

Thanks,
Sue
T.RTitleUserPersonal
Name
DateLines
3220.1check access to desktopDECWET::LEESWill, NTSG DECwest, SeattleWed Apr 09 1997 17:0920
Some quick thoughts.  Have you tried varying the account that the service runs 
under?  This can be set using the services applet.  By default a service runs 
under the LocalSystem account.  This can sometimes be an issue when the service
accesses services over the network from this account.  In general the 
environment that a service runs under is different from the general interactive 
environment. 

Also, from the services applet you set an option having to do with the service
have access to the desktop.  Perhaps that needs to be set in order for cmd to
work.

You might check the SDK or VC++ samples for ideas on executing commands.

Finally, this kind of thing, executing arbitrary commands from a service, has 
been done other times to my recollection.   This is what telnet and rexec
servers for nt do.  You might check the tools repositories or others may comment
on programs that do this kind of thing.  The kind of problems that you are 
running into are the usual stumbling block for this type of application: how to 
execute a session with the proper security and evironment.

3220.2Yes, but...DCEIDL::SHARRISThu Apr 10 1997 10:5127
Thanks for all the suggestions.  It's true that this works if we set the
option for the service that says "access to the desktop".  But that seems
like the wrong solution, from a security standpoint, for us.    Remember
that we are allowing multiple users to launch services on a host machine and
we were trying to execute those services *within* the user's security and
environment.  So we try to setup all the environment variables, the user
profile, etc., and then we launch the application - if the user has 
access to that application.  If the user doesn't originally have access to 
the desktop should they really be allowed to randomly launch, say, Notepad, on 
somebody else's desktop?  

So we don't really want to allow general access to the desktop for any user.
But it seems to us that users should be able to execute commands like
"cmd /c hostname" within their own environment.  Particularly when "hostname"
by itself is ok.  It seems an arbitrary restriction imposed by "cmd /c".

We ran into this problem because our regression tests simply want to echo where
a service got launched. Certainly without expecting to affect somebody's
desktop. 

But for now, it seems like we may have to document this as a restriction.
I just wish it was more clear about when "cmd /c" needs access to the 
desktop.  I haven't had a chance yet to look for more documentation in
the areas you suggested...thanks -

Sue
                  
3220.3More infoPTHRED::SHARRISThu Apr 17 1997 18:1442
Ok, I'm going to document what I found out, in case it's useful to anybody.
(I would have liked to have a quicker pointer to this info!)  Also, I still
have various questions as noted below...

It turns out that this problem occurs because the default workstation for a
service can't be OPENed by accounts other than the account the service runs in
(LocalSystem).   The error can only be seen by enabling auditing ("policies"
under UserManager) and by adding a key to the registry  to "AuditBaseObjects"
(and rebooting).  Once you've done this, however, all you will see is a
security failure on an Open operation for the workstation. 

The next thing to find out is what privileges are needed in order to open the
workstation.  I was unable to find this out from the documentation, but trial
and error showed that all I needed was this privilege: 

  workstation:  WINSTA_ACCESSGLOBALATOMS     

I read a little bit about global atoms but there's not a lot there to 
indicate why you would need this priv to open a workstation.  (Anybody
else got any info or comments?????)

So, I finally got this all to work by adding an ACE to the workstation ACL
for each user that we impersonate with a CreateProcess.

By the way, I did use the suggestion of looking at a TELNET and how it works in
order to find out what to do.  I looked at the telnet daemon from InterAccess. 
 They appear to also add ACEs for their users. 

But an interesting side effect seems to be that the workstation and desktop for
the telnet daemon is shared by our service - perhaps by any service that
doesn't explicitly open a different workstation and desktop.  So the fact that
telnet adds access for their users also inadvertently enables those processes
to work with our service launch and vice versa! This seems wrong to me.  (Not
to mention how *confusing* it was before I sorted out what was happening.) 

I would prefer to be able to create a separate workstation and desktop just for
use by our service.  But in my early testing of this (before I discovered
auditing and the privileges problem), it appeared that the service didn't have
privs to create a desktop.  This, in spite of what the documentation says to
the contrary.  Anybody else have any comments or information about this?   I
may not even need to create a desktop since so far it appears I don't need
to add any ACEs for the desktop...