After fixing issue 30 (user lookup) attach in dotu mode no longer works - patch proposed
Closed this issue · 7 comments
GoogleCodeExporter commented
What steps will reproduce the problem?
1. Compile and start a 9p server listening on e. g. socket /tmp/xxx
2. mount -t 9p /tmp/xxx /mnt/ -o trans=unix,version=9p2000.u,uname=<any valid
user name>
What is the expected output? What do you see instead?
Mount does not succeed:
mount: wrong fs type, bad option, bad superblock on /tmp/xxx,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so
Mount does succeed with protocol version 9p2000 (without .u)
What version of the product are you using? On what operating system?
Current repo of go9p, Linux 3.13.0-36-generic #63-Ubuntu SMP Wed Sep 3 21:30:07
UTC 2014 x86_64 x86_64 x86_64 GNU/Linux, go version go1.3.1 linux/amd64
Please provide any additional information below.
After fixing the issue 30 (p/osusers.go) [1], the following code in
p/srv/fcall.go stopped working (line 118, attach function):
if tc.Unamenum != p.NOUID || conn.Dotu {
user = srv.Upool.Uid2User(int(tc.Unamenum))
} else if tc.Uname != "" {
user = srv.Upool.Uname2User(tc.Uname)
}
and there also is identical code in the auth function.
When mounting a 9p server, Linux sends Tattach with valid username, but numeric
user ID is -1. The code above calls Uid2User with such username when dotu mode
is active, however the lookup will certainly fail. In non-dotu mode the "else
if" branch is followed, so user lookup is successful.
The proposed patch replaces this code with
if tc.Unamenum != p.NOUID || (conn.Dotu && tc.Unamenum != p.NOUID) {
user = srv.Upool.Uid2User(int(tc.Unamenum))
} else if tc.Uname != "" || (conn.Dotu && tc.Uname != "") {
user = srv.Upool.Uname2User(tc.Uname)
}
that is, if numeric UID is -1, lookup by name only will be attempted.
Thanks.
[1]
https://code.google.com/p/go9p/source/detail?r=30ef0eabe4137d115fcb3d9b9d84bc2e7
6a40c25
Original issue reported on code.google.com by golubov...@gmail.com
on 27 Sep 2014 at 1:56
Attachments:
GoogleCodeExporter commented
When .u is used, the numerical uid takes precedence over the uname. I don't
think it makes sense to use the uname parameter in that case.
Original comment by lion...@gmail.com
on 5 Dec 2014 at 6:04
GoogleCodeExporter commented
My primary use case is to make the 9p server listen on a domain socket, and
kernel-mount that socket.
So (the server has my patch, "golubovsky" is an existing user):
$ go-src/bin/ninepserver -addr=/tmp/socket -d=1 -proto=unix -root=.
Mount the socket using 9p2000.u
# mount -t 9p /tmp/socket /mnt/ -o trans=unix,version=9p2000.u,uname=golubovsky
2014/12/05 23:35:43 connected
2014/12/05 23:35:43 >>> @ Tversion tag 65535 msize 8192 version '9P2000.u'
2014/12/05 23:35:43 <<< @ Rversion tag 65535 msize 8192 version '9P2000.u'
2014/12/05 23:35:43 >>> @ Tattach tag 1 fid 0 afid 4294967295 uname
'golubovsky' nuname 4294967295 aname ''
2014/12/05 23:35:43 <<< @ Rattach tag 1 aqid (4835cc 1a44734e 'd')
2014/12/05 23:35:43 >>> @ Tstat tag 1 fid 0
2014/12/05 23:35:43 <<< @ Rstat tag 1 st ('.' 'golubovsky' 'none' 'none' q
(4835cc 1a44734e 'd') m d777 at 1417779905 mt 1417779901 l 4096 t 0 d 0 ext )
# mount -t 9p /tmp/socket /mnt/ -o trans=unix,version=9p2000.u,uname=nosuchuser
mount: wrong fs type, bad option, bad superblock on /tmp/socket,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so
2014/12/05 23:36:23 connected
2014/12/05 23:36:23 >>> @ Tversion tag 65535 msize 8192 version '9P2000.u'
2014/12/05 23:36:23 <<< @ Rversion tag 65535 msize 8192 version '9P2000.u'
2014/12/05 23:36:23 >>> @ Tattach tag 1 fid 0 afid 4294967295 uname
'nosuchuser' nuname 4294967295 aname ''
2014/12/05 23:36:23 <<< @ Rerror tag 1 ename 'unknown user: 22' ecode 22
2014/12/05 23:36:23 disconnected
and mount fails.
Note that nuname = -1 in both cases simply because Linux kernel does not pass
UID to the 9p userspace program.
# mount -t 9p /tmp/socket /mnt/ -o trans=unix,version=9p2000,uname=golubovsky
2014/12/05 23:39:02 connected
2014/12/05 23:39:02 >>> @ Tversion tag 65535 msize 8192 version '9P2000'
2014/12/05 23:39:02 <<< @ Rversion tag 65535 msize 8192 version '9P2000'
2014/12/05 23:39:02 >>> @ Tattach tag 1 fid 0 afid 4294967295 uname
'golubovsky' nuname 4294967295 aname ''
2014/12/05 23:39:02 <<< @ Rattach tag 1 aqid (4835cc 1a44734e 'd')
2014/12/05 23:39:02 >>> @ Tstat tag 1 fid 0
2014/12/05 23:39:02 <<< @ Rstat tag 1 st ('.' 'golubovsky' 'golubovsky' 'none'
q (4835cc 1a44734e 'd') m d777 at 1417779905 mt 1417779901 l 4096 t 0 d 0 ext )
# mount -t 9p /tmp/socket /mnt/ -o trans=unix,version=9p2000,uname=nosuchuser
mount: Unknown error 526
2014/12/05 23:39:49 connected
2014/12/05 23:39:49 >>> @ Tversion tag 65535 msize 8192 version '9P2000'
2014/12/05 23:39:49 <<< @ Rversion tag 65535 msize 8192 version '9P2000'
2014/12/05 23:39:49 >>> @ Tattach tag 1 fid 0 afid 4294967295 uname
'nosuchuser' nuname 4294967295 aname ''
2014/12/05 23:39:49 <<< @ Rerror tag 1 ename 'unknown user: 22' ecode 0
2014/12/05 23:39:49 disconnected
mount fails again, but with different message.
This is Linux
# uname -a
Linux hpcompaq 3.13.0-40-generic #69-Ubuntu SMP Thu Nov 13 17:53:56 UTC 2014
x86_64 x86_64 x86_64 GNU/Linux
So, in both cases, at least with my patch, character user name is in use when
numeric lookup does not succeed. Without my patch 9p2000 would work but .u
would not. The reason why I don't want to use 9p2000 is that it also ignores
files' owner numeric IDs returning -1 for both user and group.
This is more like an issue with the logic of the kernel (which does not want to
deal with numeric UIDs). This makes sense though because if 9p connection is
made to a remote system, local numeric UIDs would not have any meaning on the
remote end. Character UIDs can be translated into numeric UIDs between the two
computers.
So my proposal is basically to add a fallback character username recognition to
9p2000.u if numeric UID fails to be recognized. If Linux kernel always passes
-1 for nuname, 9p2000.u would never work properly for kernel mounts.
Original comment by golubov...@gmail.com
on 6 Dec 2014 at 4:59
GoogleCodeExporter commented
I haven't checked the current kernel code, but at some point in the past, the
kernel used to pass numeric uid to the user-space 9p server, you just need to
make sure that your server supports the "nobody" (~0) uid too. Your server will
get multiple Tattach messages, each for any uid that accesses files on the
server.
Original comment by lion...@gmail.com
on 6 Dec 2014 at 5:31
GoogleCodeExporter commented
So then 4294967295 in these messages is "inverted 32bit 0" however UID for
nobody at least on this Ubuntu instance is 65534. Maybe mount options
dfltuid/dfltgid will help, I'll check that. Would it make sense for Uid2User to
resolve to "nobody" for any numeric UID that cannot be mapped to username on
the current system?
Original comment by golubov...@gmail.com
on 6 Dec 2014 at 2:54
GoogleCodeExporter commented
The kernel doesn't have a way to know anything about what numerical value the
"nobody" user has. For that reason the 9p filesystem uses ~0 to make sure
anybody can attach to the server. In that sense, ~0 means more like "anybody",
than "nobody".
You can create your own implementations of the Users and Groups interfaces that
do anything you would like. I'd rather keep osUsers and osGroups the way they
are, because I am not sure if the changes won't break something else.
Original comment by lion...@gmail.com
on 6 Dec 2014 at 3:10
GoogleCodeExporter commented
OK, thanks. Perhaps I understand it better now. I cannot change the status of
the issue myself, but I think you can close it.
Original comment by golubov...@gmail.com
on 7 Dec 2014 at 2:07
GoogleCodeExporter commented
Original comment by lion...@gmail.com
on 7 Dec 2014 at 8:18
- Changed state: WontFix