Q re POSIX->NT->POSIX error mapping

Green, Paul Paul.Green at stratus.com
Tue Jan 19 14:28:10 MST 2010

Gentle Samba experts,

A client of ours is complaining that the sftp rename request stopped
working after they performed some software upgrades.  They upgraded some
Linux systems to a newer release and they switched from SMBFS to CIFS
and the behavior of sftp rename changed.  The issue seems to be a change
in the way that errors are mapped between Samba and SMBFS versus Samba
and CIFS.  I think I understand what is going on, but I would appreciate
comments from folks with more knowledge and experience in these areas.

Here is the situation:

S1. Client logs into a RHEL 5 Linux server.

S2. Client invokes the sftp command (OpenSSH 4.2p1-1).  (Hmm.  They must
be a little downrev, because the current RHEL RPM for OpenSSH is up to

S3. Client accesses files on what appears to be a locally-mounted Linux
disk, but in fact it is a CIFS-mounted file system which, in turn, is a
Samba share located on a machine running Samba 3.2.4 on a Stratus VOS

S4. Client attempts to rename a file using the sftp rename request.  The
request fails with a "Permission denied." error:

	sftp>  rename y1 y2
	Couldn't rename file "/home/paulg/m16/y1" to
"/home/paulg/m16/y2": Permission denied.

Naturally, the client actually has the appropriate permission to rename
the file.  Here are the reasons for the failure:


O1. The openssh-4.2p1/sftp-server.c code has two methods to perform the
rename of a file. It first tries to use the POSIX link and unlink
functions to implement a non-racy rename. If the link function returns
EOPNOTSUPP, it falls back to using stat and rename, which is racy.

O2. The VOS operating system doesn't implement hard links. The VOS POSIX
link function always returns ENOSYS.  I fully admit that this is
completely non-standard; the POSIX standard doesn't admit that
implementations are free to do this. But Samba has code to deal with it,
and many other missing functions, in source/lib/system.c.  Typically, an
attempt by Samba to call a missing POSIX function results in a failed
call with errno set to ENOSYS.  But even if our link function had set
errno to EOPNOTSUPP, I believe that this case still would have failed; 

O3. The samba-3.2.4/source/smbd/trans2.c code (hardlink_internals) gets
the ENOSYS from link() and maps the errno to an NT error using
map_nt_error_from_unix (in source/lib/errmap_unix.c;
source3/lib/errmap_unix.c in newer versions). But the mapping function
doesn't know about ENOSYS and returns the default error of
NT_STATUS_ACCESS_DENIED (but see O6, below). Bingo.

O4. Samba4 would have returned NT_STATUS_UNSUCCESSFUL in this case.
(source4/libcli/util/errormap.c). I don't think CIFS would have mapped
this error to EOPNOTSUPP, either. See O5.

O5. CIFS will map ERRinvlevel, ERReasnotsupported,or ERRsymlink to
EOPNOTSUPP.  See http://lxr.linux.no/linux+v2.6.32/fs/cifs/netmisc.c
(look for the ERRDOS array around line 46).  We have run an experiment
where we change Samba to map ENOSYS to NT_STATUS_EAS_NOT_SUPPORTED, and
the sftp rename request now works.

O6. As of 2009-07-14, Samba maps ENOSYS to NT_STATUS_NOT_SUPPORTED. See
722c8845d0dadd9ab525 by Metze.  As far as I can tell, this NT error
won't produce the EOPNOTSUPP error on the POSIX end of things, and so
this case will still fail.


I'm probably going to fix this issue via a local patch to our copy of
Samba (per the attached uni-diff).  I am reluctant to propose this as an
official change because (1) we are probably one of the few
implementations that doesn't implement hard links and (2) the error
mapping code looks to me to be a difficult area to test and get right in
all cases. Who knows what else might break. But you now know what I
know, and I'll accept any suggestions or advice anyone cares to offer.
I'm also going to go take 2 aspirin, because my head hurts.


Paul Green, Senior Technical Consultant, Stratus Technologies.
Voice: +1 978-461-7557; FAX: +1 978-461-3610; Mobile: +1 (978) 235-2451;
AIM: PaulGreen

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: samba_enosys.patch.txt
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20100119/8e6043d4/attachment.txt>

More information about the samba-technical mailing list