Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Access rights on named pipes

1,370 views
Skip to first unread message

Richard Norman

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to

I am developing a system which must allow clients to
attach to named pipes in a host. The host creates the
named pipe using a NULL DACL, exactly as described in all
the references (knowledge base Q 102798, Security Attributes
on Objects, or Marshall Brain, Win32 System Service).

I still do not get "universal" access to the pipe. Even the sample
programs from Brain's book don't give full access. Connection
seems to depend both on the client user rights on the host
sytem as well as the rights for whoever ran the host program.
Is there some written description that untangles exactly who
can access a named pipe. Must the client have a logon for the
host system? Must the host computer provide access to "Everyone"?
What about clients running Win95? What will change when clients
start using Win98 or NT5?

I would appreciate any pointers to places to look for help.

Jose Garcia

unread,
Jun 7, 1998, 3:00:00 AM6/7/98
to Richard Norman

Hi Richard,

Make a call to ImpersonateNamedPipeClient() right after your
call to ConnectNamedPipe() using the pipe handle as the
parameter in the ImpersonateNamedPipeClient() call. The server
process will 'impersonate' the security attributes of the
client process which should allow access to the pipe.


From Borland's help ....

"The ImpersonateNamedPipeClient function allows the server end
of a named pipe to impersonate the client end. When this
function is called, the named-pipe file system changes the
thread of the calling process to start impersonating the
security context of the last message read from the pipe. Only
the server end of the pipe can call this function. The server
can call the RevertToSelf function when the impersonation is
complete."

Good luck,
Jose
Remove the XXXs in my address to reply.

Richard Norman

unread,
Jun 8, 1998, 3:00:00 AM6/8/98
to

I would love to, but the problem is that ConnectNamedPipe fails
with "access denied". ImpersonateNamePipeClient is useful for
reducing the access rights of the host down to the level of the
client, but my problem is that the client doesn't even have
enough rights to connect!

In article <6lf6g7$n...@bgtnsc02.worldnet.att.net>, ga...@worldnet.att.net
says...

Jose Garcia

unread,
Jun 8, 1998, 3:00:00 AM6/8/98
to Richard Norman

OK Richand,

What are the open mode and specific mode parameters in your
call to CreateNamedPipe? What are the values in your
SECURITY_ATTRIBUTES structure?

Why don't you send a snipit of the code showing your calls
to InitializeSecurityDescriptor(), SetSecurityDescriptorDacl(),
CreateNamedPipe() ... etc and maybe we can figure it out from
there.

Jose

Brian Poe

unread,
Jun 8, 1998, 3:00:00 AM6/8/98
to

I could not get named pipes working across the network unless the server has the
client's username in its user log. Have not tried it when a password is
required though....

brian


Richard Norman wrote:
>
> I would love to, but the problem is that ConnectNamedPipe fails
> with "access denied". ImpersonateNamePipeClient is useful for
> reducing the access rights of the host down to the level of the
> client, but my problem is that the client doesn't even have
> enough rights to connect!
>

Richard Norman

unread,
Jun 9, 1998, 3:00:00 AM6/9/98
to

I have been going crazy setting up different users and rights, logging
in and out on a network with three machines: one NT Service Pack3,
one NT Service Pack 1, and one 95. I get crazy and, to me, inconsistent
results on pipe access.

Clearly creating a pipe with the default DACL on the host allows only
clients with the same login name to access it.

Creating a pipe with a NULL DACL sometimes allows other clients, but
also sometimes denies clients. I believe the client must have a valid
login on the host but it looks like there may be more to it than that.
For example, when I use FormatMessage to decode the error code from
the client CreateFile call, I get variously:

Access denied:
Logon failure: unknown user name or bad password
Logon failure: the user has not been granted the
requested logon type at this computer
and even:
The user must change his password before he logs
on for the first time.

For the last one, after I changed the account to not require the
password change, I got a logon failure, even the accounts seemed
to be identical on the two machines. When running with the same
user level logon on the two NT machines, I get different results
depending on which is host, which is client! It might be something
to do with other security settings on the machines: they have
different service packs and drive sharing is also different.

I also found funnyness in ImpersonateNamedPipe, from a client
on the same machine as the host. If the client specificies the
host computer by name, all is well. If the client specifies the
pipe name as "\\.\pipe\pipename", using the dot in place of the
actual name, the pipe connection is made but impersonation fails.

So I am still left with my questions:
How do people set up client/server applications? Do you
really have to create a logon on the host for every possible
user on the system?

Is there any good reference that sorts all this out?

In article <357C414F...@flash.net>, bp...@flash.net says...

Jose Garcia

unread,
Jun 9, 1998, 3:00:00 AM6/9/98
to

Richard,
I don't know if this relates directly to your problem but ...

The following sections of code are from applications that have
been in production now for two years. The LANs consists of one NT
server machine and none to several NT workstation machines using
Ethernet cards. There is one server process (where the first snipit
of code came from) and several client processes (the last snipit)
which may be running on the same box or on the LAN workstations.

The client processes run automated equipment and are contolled by
and communicate with the server process via namedpipes. The logons
on all the production server machines have the same group SID as
all the logons belong to the Admin group but the client apps have
been successfully tested on workstation machines with group SIDs
without admin privileges.

I hope this can be of some help to you.
Jose

// Server app where namedpipe is created
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;

link_number_is = link_number;
memset(servername_is, '\0', sizeof(servername_is));
strcpy(servername_is, servername);
dwWritten = 0;
strcpy(pipeName, name);
strcpy(linkName, name);
pipeMode = code;
linkStatus = 0;
if (code == 1)
{
sprintf(buffer, "\\\\.\\pipe\\%s", name);
pipeHandle = CreateNamedPipe( buffer,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
300,
300,
1000,
&sa);

if (pipeHandle == INVALID_HANDLE_VALUE)
{
// you know what to do
}
...
...
...
// further down in the code when the client process tries to connect
{
ConnectNamedPipe(pipeHandle, &lpOverlapped);
ImpersonateNamedPipeClient(pipeHandle);
linkStatus = 2;
}

// Client app where the client process connects
if (!strncmp(computerName, servername_is, 9))
sprintf(buffer, "\\\\.\\pipe\\%s", name);
else
sprintf(buffer, "\\\\%s\\pipe\\%s", servername_is, name);

pipeHandle = CreateFile(buffer,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);

Richard Norman

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to

In article <6lkikb$6...@bgtnsc03.worldnet.att.net>, ga...@worldnet.att.net
says...

>
>Richard,
>I don't know if this relates directly to your problem but ...
>
>The following sections of code are from applications that have
>been in production now for two years. The LANs consists of one NT
>server machine and none to several NT workstation machines using
>Ethernet cards. There is one server process (where the first snipit
>of code came from) and several client processes (the last snipit)
>which may be running on the same box or on the LAN workstations.
>
>The client processes run automated equipment and are contolled by
>and communicate with the server process via namedpipes. The logons
>on all the production server machines have the same group SID as
>all the logons belong to the Admin group but the client apps have
>been successfully tested on workstation machines with group SIDs
>without admin privileges.
>
>I hope this can be of some help to you.
>Jose
>

Many thanks for your response. I have snipped your source
to save message space. But here is where I stand.

My code for SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR is
identical to yours. The only difference I can see is my test
program is one way and non-overlapped. My real program uses
duplex pipes, but still non-overlapped.

When host and users are both power users on the host machine, things
seem to work correctly. When one is only a regular user, then things
seem to go wrong. My test program makes no file access -- it only
displays on a console.

My solution for now is to simply require that all clients have
super user logon accounts on the host machine. But I have never
seen such a limitation mentioned in all the books on named pipe
IPC I have read!

Here are details of differences in the host:
You use


> pipeHandle = CreateNamedPipe( buffer,
> PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
> PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
> 1, 300, 300, 1000, &sa);

> // snips and stylistic modifications to original
> ConnectNamedPipe(pipeHandle, &lpOverlapped);
> ImpersonateNamedPipeClient(pipeHandle);
>

My test program uses
hPipe=CreateNamedPipe("\\\\.\\pipe\\testpipe",
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
1, 0, 0, 150, &sa);
if (!ConnectNamedPipe(hPipe, (LPOVERLAPPED) NULL)) {
// ....
}
if (!ImpersonateNamedPipeClient(hPipe)) {
// ....
}
My real program uses
m_hRxPipe=CreateNamedPipe(m_csRxPipeName,
PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 0, 0, 150,
&m_RxSA);

There are corresponding differences in the client end:
You use


> pipeHandle = CreateFile(buffer,
> GENERIC_READ | GENERIC_WRITE,
> FILE_SHARE_READ | FILE_SHARE_WRITE,
> NULL,
> OPEN_EXISTING,
> FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
> NULL);

I use
hPipe=CreateFile(pipeName,
GENERIC_WRITE, FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);



Jose Garcia

unread,
Jun 10, 1998, 3:00:00 AM6/10/98
to Richard Norman

Richard,

Pacify me. Have you tried using CreateNamedPipe() and CreateFile() in
your apps using the parameters I used?

What works for one doesn't necessarily have to work for another, I
know, but I would like to know these parameters definitely don't
work in your situation.

I don't understand why, in your CreateFile() call, you only give
GENERIC_WRITE access type (you don't want your client to read from
the pipe ???) ... and then only FILE_SHARE_READ for the share
mode (which should mean that any subsequent open operations on the
pipe will fail if WRITE access is requested).

Also, if you do use the parameters in my calls, you will have to
initialize an OVERLAPPED structure, as you probably already know,
to include in any ReadFile() and WriteFile() calls.

>My solution for now is to simply require that all clients have
>super user logon accounts on the host machine.

It sounds as if you have a workaround at least.

Jose

Sorry about the "Richard uses" and "Jose uses" but I thought it might
be difficult for someone else to follow this if they hadn't read the
previous messages.

> Jose uses


> > pipeHandle = CreateNamedPipe( buffer,
> > PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
> > PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
> > 1, 300, 300, 1000, &sa);

> Richard's test program uses


> hPipe=CreateNamedPipe("\\\\.\\pipe\\testpipe",
> PIPE_ACCESS_INBOUND,
> PIPE_TYPE_MESSAGE | PIPE_WAIT,
> 1, 0, 0, 150, &sa);

> Richard's real program uses


> m_hRxPipe=CreateNamedPipe(m_csRxPipeName,
> PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
> PIPE_TYPE_MESSAGE | PIPE_WAIT,
> PIPE_UNLIMITED_INSTANCES, 0, 0, 150,
> &m_RxSA);

> There are corresponding differences in the client end:

> Jose uses


> > pipeHandle = CreateFile(buffer,
> > GENERIC_READ | GENERIC_WRITE,
> > FILE_SHARE_READ | FILE_SHARE_WRITE,
> > NULL,
> > OPEN_EXISTING,
> > FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
> > NULL);
>

> Richard uses

Richard Norman

unread,
Jun 11, 1998, 3:00:00 AM6/11/98
to

Thank you for all the responses I got for my problem,
especially to Jose Garcia for your kind attention.

My problem was having clients on other machines, WinNT
or Win95, getting access to a WinNT host through named
pipes. In creating the named pipe, I gave it a NULL
DACL which should grant access to everyone. In fact I
was finding that, first, only users with valid accounts
on the host machine could access the pipe and, second,
only some types of accounts (specifically, power users
or administrators) could access it.

The problem was not in the pipe code at all. It is true
that users cannot access a pipe unless you have a login
with appropriate rights on the host machine. The fact
was that on one of my test machines, one that was connected
to the outside world, I had set security rights for "access
this computer from the network" to "administrators and
power users", on another, it included all users. That
explains all my anomolies and problems.

Silly me! Of course, named pipe users have to access the
host through the network! But the screen to set up this
right is quite separate from the screen to create users and
grant them access, so it never occured to me to look there.

0 new messages