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