passing access rights
Oliver Laumann
net at tub.UUCP
Fri Oct 21 02:57:23 AEST 1988
Although this article contains a question, I think the matter
is `wizardry' enough to justify a posting to comp.unix.wizards.
What I would like to do is to pass a file descriptor from one
process to another one through a connection based on UNIX
domain sockets. Although the demonstration program attached
to this article works fine under Integrated Solutions 4.3 BSD
and SunOS 4.0, the calls to `sendmsg' and `recvmsg' both
return "Bad address" under vanilla 4.3 BSD on a Microvax.
I can't find the bug; all fields of the message structures
passed to `sendmsg' and `recvmsg' are properly initialized.
Unfortunately, the manual entries for these system calls
do not indicate under what circumstances EFAULT is returned.
Note that the `msg' structures are declared as `static'.
And yes, I know, the programming style is sloppy (returning
no value from main; return values of sys-calls not checked,
etc.); my `real' programs certainly look differently.
Here comes the code; first the server which accepts a
connection on a UNIX domain socket and then opens /etc/passwd
and sends the file descriptor to the client process (note that
I don't want to send any data -- just the file descriptor).
------------------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
main () {
int s, fd;
struct sockaddr_un a;
static struct msghdr msg;
char *name = "foo";
unlink (name);
if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror ("socket"); return;
}
a.sun_family = AF_UNIX;
strcpy (a.sun_path, name);
if (bind (s, (struct sockaddr *)&a, strlen (name)+2) == -1) {
perror ("bind"); return;
}
listen (s, 1);
s = accept (s, (struct sockaddr *)0, (int *)0);
if ((fd = open ("/etc/passwd", 0)) == -1) {
perror ("passwd"); return;
}
msg.msg_accrights = (caddr_t)&fd;
msg.msg_accrightslen = sizeof (fd);
if (sendmsg (s, &msg, 0) == -1)
perror ("sendmsg");
}
------------------------------------------------------------
This is the client receiving the file descriptor:
------------------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
main () {
int s, n, fd;
struct sockaddr_un a;
static struct msghdr msg;
char *name = "foo";
char buf[512];
if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror ("socket"); return;
}
a.sun_family = AF_UNIX;
strcpy (a.sun_path, name);
if (connect (s, (struct sockaddr *)&a, strlen (name)+2) == -1) {
perror ("connect"); return;
}
msg.msg_accrights = (caddr_t)&fd;
msg.msg_accrightslen = sizeof(fd);
if ((n = recvmsg (s, &msg, 0)) == -1) {
perror ("recvmsg"); return;
}
if ((n = read (fd, buf, 512)) == -1) {
perror ("read"); return;
}
write (1, buf, n);
}
------------------------------------------------------------
Just compile the programs, start the server in the background,
then invoke the client and watch the error messages.
--
Regards,
Oliver Laumann, Technical University of Berlin, Germany.
...!pyramid!tub!net or net at TUB.BITNET
...!mcvax!unido!tub!net
More information about the Comp.unix.wizards
mailing list