SFTP: ignore permissions when opening a file (needed for sshfs interoperability).
This commit is contained in:
parent
a67e745b26
commit
195b4afa8f
|
@ -191,7 +191,7 @@ def _lsLine(name, attrs):
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
def _no_write(parent_readonly, child, metadata):
|
def _no_write(parent_readonly, child, metadata=None):
|
||||||
"""Whether child should be listed as having read-only permissions in parent."""
|
"""Whether child should be listed as having read-only permissions in parent."""
|
||||||
|
|
||||||
if child.is_unknown():
|
if child.is_unknown():
|
||||||
|
@ -201,7 +201,7 @@ def _no_write(parent_readonly, child, metadata):
|
||||||
elif parent_readonly or IDirectoryNode.providedBy(child):
|
elif parent_readonly or IDirectoryNode.providedBy(child):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return metadata.get('no-write', False)
|
return metadata is not None and metadata.get('no-write', False)
|
||||||
|
|
||||||
|
|
||||||
def _populate_attrs(childnode, metadata, size=None):
|
def _populate_attrs(childnode, metadata, size=None):
|
||||||
|
@ -1326,10 +1326,6 @@ class SFTPUserHandler(ConchUser, PrefixingLogMixin):
|
||||||
if (flags & FXF_WRITE) and root.is_readonly():
|
if (flags & FXF_WRITE) and root.is_readonly():
|
||||||
raise SFTPError(FX_PERMISSION_DENIED,
|
raise SFTPError(FX_PERMISSION_DENIED,
|
||||||
"cannot write to a non-writeable filecap without a parent directory")
|
"cannot write to a non-writeable filecap without a parent directory")
|
||||||
if (flags & FXF_WRITE) and root.is_mutable() and desired_metadata.get('no-write', False):
|
|
||||||
raise SFTPError(FX_PERMISSION_DENIED,
|
|
||||||
"cannot write to a mutable filecap without a parent directory, when the "
|
|
||||||
"specified permissions would require the link from the parent to be made read-only")
|
|
||||||
if flags & FXF_EXCL:
|
if flags & FXF_EXCL:
|
||||||
raise SFTPError(FX_FAILURE,
|
raise SFTPError(FX_FAILURE,
|
||||||
"cannot create a file exclusively when it already exists")
|
"cannot create a file exclusively when it already exists")
|
||||||
|
@ -1346,7 +1342,7 @@ class SFTPUserHandler(ConchUser, PrefixingLogMixin):
|
||||||
# reported as r--r--r--, which is appropriate because an immutable file can't be
|
# reported as r--r--r--, which is appropriate because an immutable file can't be
|
||||||
# written via this path.
|
# written via this path.
|
||||||
|
|
||||||
metadata['no-write'] = _no_write(True, root, metadata)
|
metadata['no-write'] = _no_write(True, root)
|
||||||
return self._make_file(file, userpath, flags, filenode=root, metadata=metadata)
|
return self._make_file(file, userpath, flags, filenode=root, metadata=metadata)
|
||||||
else:
|
else:
|
||||||
# case 2
|
# case 2
|
||||||
|
@ -1398,7 +1394,10 @@ class SFTPUserHandler(ConchUser, PrefixingLogMixin):
|
||||||
if noisy: self.log("_got_child( (%r, %r) )" % (filenode, current_metadata), level=NOISY)
|
if noisy: self.log("_got_child( (%r, %r) )" % (filenode, current_metadata), level=NOISY)
|
||||||
|
|
||||||
metadata = update_metadata(current_metadata, desired_metadata, time())
|
metadata = update_metadata(current_metadata, desired_metadata, time())
|
||||||
metadata['no-write'] = _no_write(parent_readonly, filenode, metadata)
|
|
||||||
|
# Ignore the permissions of the desired_metadata in an open call. The permissions
|
||||||
|
# can only be set by setAttrs.
|
||||||
|
metadata['no-write'] = _no_write(parent_readonly, filenode, current_metadata)
|
||||||
|
|
||||||
if filenode.is_unknown():
|
if filenode.is_unknown():
|
||||||
raise SFTPError(FX_PERMISSION_DENIED,
|
raise SFTPError(FX_PERMISSION_DENIED,
|
||||||
|
|
|
@ -573,12 +573,6 @@ class Handler(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, unittest.TestCas
|
||||||
self.shouldFailWithSFTPError(sftp.FX_PERMISSION_DENIED, "openFile readonly uri WRITE denied",
|
self.shouldFailWithSFTPError(sftp.FX_PERMISSION_DENIED, "openFile readonly uri WRITE denied",
|
||||||
self.handler.openFile, "uri/"+self.readonly_uri, sftp.FXF_WRITE, {}))
|
self.handler.openFile, "uri/"+self.readonly_uri, sftp.FXF_WRITE, {}))
|
||||||
|
|
||||||
# cannot write to a mutable file by uri when no-write permissions are specified
|
|
||||||
d.addCallback(lambda ign:
|
|
||||||
self.shouldFailWithSFTPError(sftp.FX_PERMISSION_DENIED, "openFile mutable uri permissions:0444 WRITE denied",
|
|
||||||
self.handler.openFile, "uri/"+self.mutable_uri, sftp.FXF_WRITE,
|
|
||||||
{'permissions': 0444}))
|
|
||||||
|
|
||||||
# cannot create a file with the EXCL flag if it already exists
|
# cannot create a file with the EXCL flag if it already exists
|
||||||
d.addCallback(lambda ign:
|
d.addCallback(lambda ign:
|
||||||
self.shouldFailWithSFTPError(sftp.FX_FAILURE, "openFile small WRITE|CREAT|EXCL failure",
|
self.shouldFailWithSFTPError(sftp.FX_FAILURE, "openFile small WRITE|CREAT|EXCL failure",
|
||||||
|
@ -696,6 +690,16 @@ class Handler(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, unittest.TestCas
|
||||||
d.addCallback(lambda node: download_to_data(node))
|
d.addCallback(lambda node: download_to_data(node))
|
||||||
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "01234"))
|
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "01234"))
|
||||||
|
|
||||||
|
# test WRITE | TRUNC with permissions: 0
|
||||||
|
d.addCallback(lambda ign:
|
||||||
|
self.handler.openFile("newfile", sftp.FXF_WRITE | sftp.FXF_TRUNC, {'permissions': 0}))
|
||||||
|
d.addCallback(_write_trunc)
|
||||||
|
d.addCallback(lambda ign: self.root.get(u"newfile"))
|
||||||
|
d.addCallback(lambda node: download_to_data(node))
|
||||||
|
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "01234"))
|
||||||
|
d.addCallback(lambda ign: self.root.get_metadata_for(u"newfile"))
|
||||||
|
d.addCallback(lambda metadata: self.failIf(metadata.get('no-write', False), metadata))
|
||||||
|
|
||||||
# test EXCL flag
|
# test EXCL flag
|
||||||
d.addCallback(lambda ign:
|
d.addCallback(lambda ign:
|
||||||
self.handler.openFile("excl", sftp.FXF_WRITE | sftp.FXF_CREAT |
|
self.handler.openFile("excl", sftp.FXF_WRITE | sftp.FXF_CREAT |
|
||||||
|
@ -824,6 +828,14 @@ class Handler(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, unittest.TestCas
|
||||||
d.addCallback(_check_same_file)
|
d.addCallback(_check_same_file)
|
||||||
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "mutable new! contents"))
|
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "mutable new! contents"))
|
||||||
|
|
||||||
|
# ... and with permissions, which should be ignored
|
||||||
|
d.addCallback(lambda ign:
|
||||||
|
self.handler.openFile("mutable", sftp.FXF_WRITE, {'permissions': 0}))
|
||||||
|
d.addCallback(_write_mutable)
|
||||||
|
d.addCallback(lambda ign: self.root.get(u"mutable"))
|
||||||
|
d.addCallback(_check_same_file)
|
||||||
|
d.addCallback(lambda data: self.failUnlessReallyEqual(data, "mutable new! contents"))
|
||||||
|
|
||||||
# test READ | WRITE without CREAT or TRUNC
|
# test READ | WRITE without CREAT or TRUNC
|
||||||
d.addCallback(lambda ign:
|
d.addCallback(lambda ign:
|
||||||
self.handler.openFile("small", sftp.FXF_READ | sftp.FXF_WRITE, {}))
|
self.handler.openFile("small", sftp.FXF_READ | sftp.FXF_WRITE, {}))
|
||||||
|
|
Loading…
Reference in New Issue