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

Obtaining Credentials of Peer Process

2 views
Skip to first unread message

shadows

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

Under System V it's possible to obtain the effective uid and effective gid
of a peer process connected via a unix domain socket. By passing a
descriptor from one process to another, the receiving process also gets the
euid and egid of the sender.

I was wondering if anything remotely like this is possible under 4.4BSD?
I've been looking over at dejanews to no avail, though I'm pretty sure a
technique to accomplish this has been brought up before in this forum.

--
Thamer Al-Herbish <URL http://www.whitefang.com/>
[ The Raw IP Networking FAQ <URL http://www.whitefang.com/rin/ > ]

Bill Paul

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

Daring to challenge the will of the almighty Leviam00se, shadows
(sha...@whitefang.com) had the courage to say:

: Under System V it's possible to obtain the effective uid and effective gid


: of a peer process connected via a unix domain socket.

Are you sure it's a UNIX domain socket? I always thought it was a TLI
endpoint. I know there's a way to do this with t_getinfo().

: By passing a


: descriptor from one process to another, the receiving process also gets the
: euid and egid of the sender.

Hm. I could swear this only worked if you used TLI, not sockets. But
anyway...

: I was wondering if anything remotely like this is possible under 4.4BSD?


: I've been looking over at dejanews to no avail, though I'm pretty sure a
: technique to accomplish this has been brought up before in this forum.

It's not possible with stock 4.4BSD, but you can easily modify the
kernel to support this. There is a mechanism for passing file descriptors
in 4.4BSD using sendmsg()/recvmsg() but unlike SysV, the kernel does not
pass along the credentials of the sending process (and having just the
file descriptor doesn't really let you learn the identity of the sending
process with absolute certainty).

In 4.4BSD, you attach a control message to the message buffer that you
send with sendmsg(). This control message contains ancillary data; it
can be arbitrarily chosen user data, but there are also a couple of
special data types that the kernel interprets internally. One is
SCM_RIGHTS, which is used to contain file descriptor indexes: this is
how you transfer a file descriptor in 4.4BSD (the mechanism was a
little different in 4.3). It's possible to modify the kernel to handle
other kinds of control data, including process credential information.

FreeBSD-current has support for SCM_CREDS messages that do what you
want: when a process sends a message with sendmsg() and includes a
control message buffer with the SCM_CREDS flag set, the kernel fills
in the buffer with the UID, EUID, PID and group list of the sending
process. The receiving process can then check examine this information
to learn the sender's identity. If the message is received without the
SCM_CREDS flag set, it can refuse to handle the message. Currently,
this mechanism is only used in the RPC library: there is a special
AF_LOCAL transport used by keyserv and rpc.yppasswdd (in some cases).
This new transport uses sendmsg()/recvmsg() as its underlying transport
mechanism and servers using this transport can use the credential data
for authentication. (This is a big win for keyserv in particular because
it lets you do away with the awful kludge that is keyenvoy.)

According to _UNIX Network Programming, 2nd Edition, Vol. 1_, recent
versions of BSD/OS from BSDI have similar support, although with their
approach the sender doesn't necessarily have to use sendmsg(). (I
thought I was being really clever when I added the SCM_CREDS changes
to FreeBSD, until I realized that BSDI had done it first. :) The
receiving process can use setsockopt() to force the kernel to provide
cedential info without requiring the sender to take any special action.

Also, I _think_ that Linux has support for SCM_CREDS as well, though
I can't swear to this as I don't use it myself. Check your kernel
source code, if it's handy. If your version doesn't have this support,
I imagine it wouldn't be too difficult to add it.

-Bill

--
=============================================================================
-Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu
Work: wp...@ctr.columbia.edu | Center for Telecommunications Research
Home: wp...@skynet.ctr.columbia.edu | Columbia University, New York City
=============================================================================
"Mulder, toads just fell from the sky!" "I guess their parachutes didn't open."
=============================================================================

Thomas H. Ptacek

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

27 Jun 1998 10:32:19 GMT sha...@whitefang.com:

>I was wondering if anything remotely like this is possible under 4.4BSD?
>I've been looking over at dejanews to no avail, though I'm pretty sure a
>technique to accomplish this has been brought up before in this forum.

Yes, pass a message over a UNIX socket with SCM_CREDS set as ancillary
data. man recv.

--
-----------------------------------------------------------------------------
Thomas H. Ptacek SNI Labs, Network Associates, Inc.
-----------------------------------------------------------------------------
http://www.pobox.com/~tqbf "If you're so special, why aren't you dead?"

Thomas H. Ptacek

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

27 Jun 1998 17:47:29 GMT wp...@ctr.columbia.edu:

>It's not possible with stock 4.4BSD, but you can easily modify the
>kernel to support this. There is a mechanism for passing file descriptors
>in 4.4BSD using sendmsg()/recvmsg() but unlike SysV, the kernel does not

Even if your kernel doesn't support SCM_CREDS (FreeBSD does, at least in
newer releases), you can verify the creds of a client by having it send an
SCM_RIGHTS message with a file descriptor in it for a mode 0700 file;
fstat() the descripto and see what st_uid is.

You could also agree on the location of a file somewhere, and create the
file externally and set permissions so that only authorized users can open
it. Check st_dev and st_ino on the SCM_RIGHTS message.

shadows

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

Bill Paul wp...@ctr.columbia.edu wrote:
>Daring to challenge the will of the almighty Leviam00se, shadows
>(sha...@whitefang.com) had the courage to say:

>: By passing a


>: descriptor from one process to another, the receiving process also gets the
>: euid and egid of the sender.
>
>Hm. I could swear this only worked if you used TLI, not sockets. But
>anyway...

Right, my mistake (should'nt be posting at 5 am). You can pass descriptors
with an unamed stream pipe via TLI, and as you receive them you receive
additional credential information. (This is all from UNP 1st edition).

>According to _UNIX Network Programming, 2nd Edition, Vol. 1_, recent
>versions of BSD/OS from BSDI have similar support, although with their
>approach the sender doesn't necessarily have to use sendmsg(). (I
>thought I was being really clever when I added the SCM_CREDS changes
>to FreeBSD, until I realized that BSDI had done it first. :) The
>receiving process can use setsockopt() to force the kernel to provide
>cedential info without requiring the sender to take any special action.

Just wondering, any standards mention SCM_CREDS? Abviously BSD/OS and
FreeBSD did'nt both choose the same name by coincidence :)

(Kudos to Mr.Paul and Mr.Ptacek, the responses were just what I needed).

Bill Paul

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

Daring to challenge the will of the almighty Leviam00se, Thomas H. Ptacek
(tq...@joshua.enteract.com) had the courage to say:

: 27 Jun 1998 17:47:29 GMT wp...@ctr.columbia.edu:


: >It's not possible with stock 4.4BSD, but you can easily modify the
: >kernel to support this. There is a mechanism for passing file descriptors
: >in 4.4BSD using sendmsg()/recvmsg() but unlike SysV, the kernel does not

: Even if your kernel doesn't support SCM_CREDS (FreeBSD does, at least in
: newer releases),

I know that; like I said, I was the one who implemented it in FreeBSD. :)

: you can verify the creds of a client by having it send an


: SCM_RIGHTS message with a file descriptor in it for a mode 0700 file;
: fstat() the descripto and see what st_uid is.

: You could also agree on the location of a file somewhere, and create the
: file externally and set permissions so that only authorized users can open
: it. Check st_dev and st_ino on the SCM_RIGHTS message.

Before adding the SCM_CREDS changes to uipc_usrreq.c, I looked around to
see if there was an alternate method for doing what I needed, and several
people suggested things like this. To me, this seemed like a bit of a
kludge though since client and server have to make extra syscalls, and
you have to muck about in the filesystem. Also, in my case I was trying
to implement library code that was meant to be used in libc: things can
get really clumsy if you use SCM_RIGHTS since you have to be careful
about deciding where to create the file, cleaning up after you're done,
avoiding symlinks, cleaning up stale files that may have been left
behind by previous programs that crashed, etc.

I tried very hard to think of a way to learn the UID of a process on the
other end of an AF_LOCAL socket without modifying the kernel. I even
wrote an LKM that implemented a special syscall which would grovel
through the open file table in order to find the process holding on
to the other side of the connection, but even that wasn't good enough
because more than one process can reference a descriptor at any one
time. (I also experimented a bit with SysV message queues, but that didn't
quite fit my needs either.) I finally realized that the sockets interface
just didn't do what I wanted, so caved in and settled for hacking the
kernel in the least obtrusive way I could think of.

Bill Paul

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

Daring to challenge the will of the almighty Leviam00se, shadows
(sha...@whitefang.com) had the courage to say:

: Bill Paul wp...@ctr.columbia.edu wrote:
: >Daring to challenge the will of the almighty Leviam00se, shadows
: >(sha...@whitefang.com) had the courage to say:

: >: By passing a


: >: descriptor from one process to another, the receiving process also gets the
: >: euid and egid of the sender.
: >
: >Hm. I could swear this only worked if you used TLI, not sockets. But
: >anyway...

: Right, my mistake (should'nt be posting at 5 am). You can pass descriptors
: with an unamed stream pipe via TLI, and as you receive them you receive
: additional credential information. (This is all from UNP 1st edition).

Yeah, that's where I read it too. :)

: >According to _UNIX Network Programming, 2nd Edition, Vol. 1_, recent


: >versions of BSD/OS from BSDI have similar support, although with their
: >approach the sender doesn't necessarily have to use sendmsg(). (I
: >thought I was being really clever when I added the SCM_CREDS changes
: >to FreeBSD, until I realized that BSDI had done it first. :) The
: >receiving process can use setsockopt() to force the kernel to provide
: >cedential info without requiring the sender to take any special action.

: Just wondering, any standards mention SCM_CREDS?

Not that I know of, but then I'm not an authority.

: Abviously BSD/OS and


: FreeBSD did'nt both choose the same name by coincidence :)

Actually, I think it was a coincidence. It depends on whether or not
BSD/OS had it before FreeBSD. I _think_ that BSD/OS had it first, however
I was totally unaware of this when I made the changes to FreeBSD since
I never had access to any BSD/OS systems. I also remember I asked for
suggestions about what to do on some of the FreeBSD mailing lists and
nobody mentioned BSD/OS either. Since SCM_RIGHTS already existed, I
settled on SCM_CREDS for my own little hack. The cmsgcred structure
is a bit different between the two systems: the BSD/OS version includes
the username of the sending process in addition to its UID and EUID.
It didn't occur to me to include the username when I set up my version
of the struct since I was mindful of the fact that all of the credential
data had to fit inside an mbuf, and with FreeBSD it's possible for someone
to recompile the system to use usernames longer than 8 bytes.

It was only recently that I started seeing signs that Linux might have
adopted SCM_CREDS too; I have no idea where they got their inspiration
from though.

0 new messages