Repository navigation
Description
Bug reports
I tried to set permission on a file on a SFTP server. I use normally use FileZilla to interact with the server, but I needed a fast way to change a lot of files, file permission. So I thought I would write a python script.
I noticed 2 things, if I only have read access to the file, I could not change the permission, giving me a ssh2.exceptions.SFTPProtocolError, I can using the same login, change the permission in FileZilla.
The second and more important issue, was that I could not change the permission at all using the code described below:
Steps to reproduce:
def chmod(sftp, path, permissions):
stat = sftp.stat(path)
print("original permission", oct(stat.permissions))
stat.permissions = permissions | 0x8000 #I tried without the '|' as well, and I tried with only LIBSSH2_SFTP_S_IRWXU
print("seting permissions to ", oct(stat.permissions))
try:
if sftp.setstat(path, stat) == 0:
stat = sftp.stat(path)
print("managed to set permissions to ", oct(stat.permissions))
else:
print("failed to set permissions")
except Exception:
raiseThe out put is this when trying to change the permission of a file from '666' to '755'
original permission 0o100666
seting permissions to 0o100755
managed to set permissions to 0o100666
successExpected behaviour:
I expect that I can change permission on files with only read-access, as long as the authenticated user, has privileges todo so
I expected that the new file permission would be '755' after calling setstat with changed permissions
Actual behaviour:
When I only read access has been set on a file it throws a ssh2.exceptions.SFTPProtocolError
When trying to setstat it does not change, even though the setstat() returned a 0
Additional info:
I am uncertain of which libssh2 I am running, as I just pip installed ssh2-python and it was up and running, but if I were to hazard a guess, I'd say 1.9.0
Activity
pkittenis commentedon Oct 13, 2020
Thanks for the interest.
stat.permissionsshould be a mask ofLIBSSH2_SFTP_S_*flags. Example from tests:33024 == 100400 in octal (read only).
SFTPProtocolErrormeans invalid attributes were given to setstat. If the flags were not used, this is probably why.Will need to see code that reproduces the read only file case to help further.
Togtja commentedon Oct 13, 2020
To be clearer: I only get the

SFTPProtocolErrorerror with the read only example:This throws this error:
current permission is 0o100444 setting permission to be 0o700 Traceback (most recent call last): File "c:\Users\labuser\Documents\test_folder\python_ssl.py", line 41, in <module> chmod(sftp, "test.txt", None) File "c:\Users\labuser\Documents\test_folder\python_ssl.py", line 15, in chmod if sftp.setstat(path, stat) == 0: File "ssh2\sftp.pyx", line 385, in ssh2.sftp.SFTP.setstat File "ssh2\utils.pyx", line 184, in ssh2.utils.handle_error_codes ssh2.exceptions.SFTPProtocolErrorIf I make the file with write access (using FileZilla in my case, but I could go ssh and do chmod 666 test.txt as well):

running the same code again, I get this output:
Here I use
LIBSSH2_SFTP_S_IRWXUas permission, which I did say I tried in the OG postpkittenis commentedon Oct 18, 2020
Can you show output of:
In shell:
In python:
Please show complete python code, including login code.
Togtja commentedon Oct 19, 2020
The setup for the
sftpvariable looks like this:The output from the ls command (login in with same user, pwd as the code)
pkittenis commentedon Oct 20, 2020
What is the owner of the file and what is the login user?
?is not a valid user name. The python code is not complete and does not show login user.The login user needs to have owner or group status in order to change permissions. Exception is raised otherwise.
Togtja commentedon Oct 20, 2020
The owner of the file should be
togtja, but thels -lhcommand shows-rw-rw-rw- ? 0 0 0B Oct 13 14:41 test.txtThe code is complete, I just hide the personal information such as the host, user and password, but for the sake of argument I can make example variable:
Entire code:
output:
I can create a file using
ssh2-pythonso I will try to do that, and comment the outputpkittenis commentedon Oct 21, 2020
According to the shell, it is not. Does
chmod 644 test.txtwork when logged in astogtja? If not, it will not work with ssh2-python either.There is a test that creates a file locally and changes permissions with ssh2-python.
Will need to show some code to reproduce an issue to be able to help further.
Togtja commentedon Oct 22, 2020
Hmm it seems that the sftp server only accepts permissions of "444" and "666", so it's not an issue with (ssh2-python/linssh2).
might be because the SFTP server is running on Windows, so that might be the reason for my issues. (But I have no choice)
However, I am still not able to change the permission from a read-only, to write only:
The file test.txt has 666 permission:
The first chmod outputs:
However it fails on the second one
If I do the same in the console:
Here I expect it to behave the same. And I am able to do it using CURL (with libssh2 1.9.0)
pkittenis commentedon Oct 22, 2020
To be able to help with this please show:
Complete code that reproduces the issue.
Will also need to show login user, user owning file and python code using appropriate masks from
LIBSSH2_SFTP_S_*. Ignoring these masks and using hardcoded octal numbers will not work. Particularly across operating systems..Please also show result of
ls -lh test.txt- can usesftp.listdirif not have shell access - after changing permissions withsftp.setstat.Togtja commentedon Oct 23, 2020
Alot of this is similar from before, such as login user, the same login user should be the owner of the file, but all files on the file server, including those not made by my login user, are all owned by
?, I think it might have to do with it being a Windows server, but not certain. Also minor improvment so I can transalte octal toLIBSSH2_SFTP_S_*Before and after doing:
chmod(sftp, "test.txt", 0o444)BEFORE:
AFTER:
For your sake I also did it with pure
sftp.setstat():Before and after doing:
BEFORE:
AFTER:
If trying to go back to 666, with a file with only read access
this happens:
For both these example, the same code to create the
sftpis the same as I have shown beforeWhy there is a bunch of
*******, I do not knowpkittenis commentedon Oct 23, 2020
Thanks for the code to reproduce.
So it looks like
setstatrequires thatLIBSSH2_SFTP_ATTR_PERMISSIONSmask is set toattrs.flagswhen setting permissions otherwise the permissions may not be set correctly.I assume this is also the case when setting size, time et al - #103 will probably also be resolved by setting correct attribute.
Eg:
This fails. Setting flag before setstat sets permissions correctly.
Having to use attribute flags is not documented anywhere from what I can see and some permission flags work without
LIBSSH2_SFTP_ATTR_PERMISSIONS- current integration tests do not use them and work for the read only flags that they test.SFTP attribute flags are not implemented in the current release - will have to wait for next release to use them.
Added SFTP attribute flags. Updated sftp tests - resolves #119
[-]setstat fails silently and cannot setstat when only having read permissions on file[/-][+]Missing SFTP file attribute constants[/+]pkittenis commentedon Oct 25, 2020
0.23.0contains theLIBSSH2_SFTP_ATTR_*flags. To change permissions correctly setattrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONSper example above.Thanks for raising. A complete example for setstat would be good to have if anyone wants to make a PR. There does not seem to be much libssh2 documentation on SFTP attributes.
Sftp attrs (ParallelSSH#124)