external auth mech over unix socket

Serge Hallyn serge.hallyn at ubuntu.com
Fri Dec 6 12:55:23 PST 2013


Hi,

I'm playing with a dbus daemon over a simple unix socket, which should
server the whole system.  In non-user-namespace use, it works fine,
client authenticates and makes its requests, server responds, no
problem.

I'd like it to answer requests from another user namespace as well.
That means that the client might think it is (read, in its namespace it
*is*) uid 0, but the daemon sees that it is actually uid 160000.  Since
the server listens over unix socket and the daemon can use so_peercred
to get the real uid and pid of the client, this should be fine.
However, the dbus auth protocol includes the client sending its uid
(which is 0) in the AUTH EXTERNAL message;  then the server trying to
authenticate based on that.  Since the client requests uid 0, the server
checks _dbus_credentials_are_superset() against the socket which is
owned by 160000, then returns error.

>From here, the auth negotiation proceeds until anonymous seems to
succeed, but then the client immediately closes its socket rather
than proceeding.

The daemon source is branch usernstest of github.com/hallyn/cgmanager,
while test is just

dbus-send --address=unix:path=/tmp/cgmanager --type=method_call /org/linuxcontainers/cgmanager org.linuxcontainers.cgmanager0_0.Poke

run as root in a userns where 0 is mapped to 160000 on the host.

The client sees:

133   sendto(3, "AUTH EXTERNAL 30\r\n", 18, MSG_NOSIGNAL, NULL, 0) = 18
133   poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
133   read(3, "REJECTED EXTERNAL DBUS_COOKIE_SH"..., 2048) = 46
133   geteuid()                         = 0
133   poll([{fd=3, events=POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
133   sendto(3, "AUTH DBUS_COOKIE_SHA1 30\r\n", 26, MSG_NOSIGNAL, NULL, 0) = 26
133   poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
133   read(3, "REJECTED EXTERNAL DBUS_COOKIE_SH"..., 2048) = 46
133   poll([{fd=3, events=POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
133   sendto(3, "AUTH ANONYMOUS 6c696264627573203"..., 45, MSG_NOSIGNAL, NULL, 0) = 45
133   poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
133   read(3, "OK 33f6659184ac461c2219eaf752a23"..., 2048) = 37
133   poll([{fd=3, events=POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
133   sendto(3, "NEGOTIATE_UNIX_FD\r\n", 19, MSG_NOSIGNAL, NULL, 0) = 19
133   poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
133   read(3, "AGREE_UNIX_FD\r\n", 2048) = 15
133   poll([{fd=3, events=POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
133   sendto(3, "BEGIN\r\n", 7, MSG_NOSIGNAL, NULL, 0) = 7
133   poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLOUT|POLLHUP}])
133   recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"", 2048}], msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 0
133   close(3)                          = 0

I dont' understand why the socket gets closed right after the ANONYMOUS
mech succeeds.  IIUC ANONYMOUS would be fine with me - all I need is
the socket credentials.  Could this be a bug in the anonymous mech
code, or (more likely) am I misusing something?

-serge


More information about the dbus mailing list