lkml.org 
[lkml]   [2000]   [Jul]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: SO_PASSCRED broken in 2.4 ? - mystery tackled
On Sun, 02 Jul 2000, kuznet@ms2.inr.ac.ru wrote:

> Hello!
>
> > However, the following ``fix'' can be applied:
> > ------------------------------
> > ...
> > antsd = socket(AF_UNIX, SOCK_STREAM, 0);
> > ...
> > addr.sun_family = AF_UNSPEC; /* used to be AF_UNIX */
> > ...
> > ------------------------------
>
> I am sorry, but after this connect will return EINVAL.

Yes, I'm sorry too ;)
That was a damn stupid mistake on my part.

>
> It would be better if you showed all the related pieces
> of your program, doing operations between socket...sendmsg
> and socket...recvmsg on server side.

The entire source is available from http://ostenfeld.dtu.dk/~jakob/jobd/

It's a job distribution system for Beowulfs, the server needs the AF_UNIX
credentials to authenticate the local user.

The idea is, that a server has bound to a local UNIX socket, and will await
client connections. A server will listen for connections, accept() them, read
credentials, read data, and process the request.

I hope you can make out the idea from the code snippets below. This mail
is getting big for a list mail.

Server does: (this is C++, LOCALSOCK is a string(), thus the .c_str())
----------------------------
localsock = socket(AF_UNIX, SOCK_STREAM, 0);
if(localsock == -1) {
log_info("Sorry, cannot create local socket");
return;
}

unlink(LOCALSOCK.c_str());
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, LOCALSOCK.c_str());
int rc = bind(localsock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr));
if(rc) {
log_info("Binding on local socket \"" + LOCALSOCK + "\" failed.");
close(localsock);
localsock = -1;
return;
}
chmod(LOCALSOCK.c_str(), 0666);

listen(localsock, 5);
----------------------------

Success so far.


Client does: (plain ANSI C)
----------------------------
/* Connect and get a host suggestion */
antsd = socket(AF_UNIX, SOCK_STREAM, 0);
if(antsd == -1)
fail("Cannot create AF_UNIX socket");

addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, ANTSD_SOCKET);

opt_val = 1;
rc = setsockopt(antsd, SOL_SOCKET, SO_PASSCRED, &opt_val, sizeof(opt_val));
if(rc)
fail("Couldn't set SO_PASSCRED on antsd socket");

rc = connect(antsd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un));
if(rc)
fail("Cannot connect to local antsd socket - antsd not running on localhost ?");
----------------------------

Client also succeedes.


Then server does: (after a select())
----------------------------
int sock = accept(localsock, 0, 0);
if(sock == -1) {
log_info("Accepting connection from local socket failed");
return;
}

connections.insert(sock);
log_info("Accepted new connection on local socket");

struct linger lng = {0, 0};
int rc = setsockopt(sock, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng));
if(rc)
log_info("Cannot unset SO_LINGER on socket");

unsigned bint = 1;
rc = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &bint, sizeof(bint));
if(rc)
log_info("Cannot set SO_PASSCRED on socket");

listen(localsock, 5);
----------------------------

All works.


Now Client sends data to the server. Just a plain send().
----------------------------
/* Send request */
rc = send(antsd, type, strlen(type), 0);
if(rc != strlen(type))
fail("Cannot send to local antsd socket");
----------------------------

Success again.


And finally server fails the recvmsg() in:
----------------------------
const unsigned cmsg_bufsize = sizeof(struct ucred); // we only need sizeof(struct ucred) ourselves
struct msghdr msg;
struct cmsghdr * cmsgh;
char ancbuf[CMSG_SPACE(cmsg_bufsize)];

memset(&msg, 0, sizeof(msg));
memset(&ancbuf, 0, CMSG_SPACE(cmsg_bufsize));
msg.msg_control = ancbuf;
msg.msg_controllen = cmsg_bufsize;

int rc = recvmsg(*ci, &msg, 0);
if(rc < 0) {
log_info(std::string("Couldn't read ancillary data from jsh connection: ") + strerror(errno));
expired.insert(*ci);
continue;
}
----------------------------

I get this error from the server:
Couldn't read ancillary data from jsh connection: Operation not supported


If this is an error in my code, I sincerely apologize for clobbering up lkml
with this. I repeat though, that this code worked in 2.2 (currently runs in
production on four systems at work). I've had one success report from someone
else too, who installed and ran the code on a larger cluster.

Thanks a lot,
--
................................................................
: jakob@ostenfeld.dtu.dk : And I see the elder races, :
:.........................: putrid forms of man :
: Jakob Østergaard : See him rise and claim the earth, :
: OZ9ABN : his downfall is at hand. :
:.........................:............{Konkhra}...............:

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:57    [W:0.061 / U:0.076 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site