diff --git a/pyftpdlib/filesystems.py b/pyftpdlib/filesystems.py index 8f930c76..39b7a3bf 100644 --- a/pyftpdlib/filesystems.py +++ b/pyftpdlib/filesystems.py @@ -2,6 +2,7 @@ # Use of this source code is governed by MIT license that can be # found in the LICENSE file. +import errno import os import stat import tempfile @@ -258,8 +259,10 @@ def chdir(self, path): """Change the current directory. If this method is overridden it is vital that `cwd` attribute gets set. """ - # note: process cwd will be reset by the caller - os.chdir(path) + is_dir = stat.S_ISDIR(os.stat(path).st_mode) + if not is_dir or not os.access(path, os.R_OK | os.X_OK): + code = errno.EACCES if is_dir else errno.ENOTDIR + raise OSError(code, os.strerror(code), path) self.cwd = self.fs2ftp(path) def mkdir(self, path): diff --git a/pyftpdlib/handlers.py b/pyftpdlib/handlers.py index bf619aaa..c8c212ca 100644 --- a/pyftpdlib/handlers.py +++ b/pyftpdlib/handlers.py @@ -2759,14 +2759,11 @@ def ftp_CWD(self, path): """Change the current working directory. On success return the new directory path, else None. """ - # Temporarily join the specified directory to see if we have - # permissions to do so, then get back to original process's - # current working directory. + # Check permissions for the specified directory and set it as cwd. # Note that if for some reason os.getcwd() gets removed after # the process is started we'll get into troubles (os.getcwd() # will fail with ENOENT) but we can't do anything about that # except logging an error. - init_cwd = os.getcwd() try: self.run_as_current_user(self.fs.chdir, path) except (OSError, FilesystemError) as err: @@ -2775,8 +2772,6 @@ def ftp_CWD(self, path): else: cwd = self.fs.cwd self.respond(f'250 "{cwd}" is the current directory.') - if os.getcwd() != init_cwd: - os.chdir(init_cwd) return path def ftp_CDUP(self, path):