Cygwin: readdir: drop support for NT4/Win2K shares and Samba < 3.0.22

These systems are at least 18 years old and so buggy that they are
hopefully not used anymore.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2024-03-20 17:45:41 +01:00
parent 8bd6ba8f16
commit b9ed33dec0
2 changed files with 5 additions and 57 deletions

View File

@ -2463,66 +2463,16 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
d_cache (dir), DIR_BUF_SIZE, d_cache (dir), DIR_BUF_SIZE,
FileIdBothDirectoryInformation, FileIdBothDirectoryInformation,
FALSE, NULL, dir->__d_position == 0); FALSE, NULL, dir->__d_position == 0);
/* FileIdBothDirectoryInformation isn't supported for remote drives /* FileIdBothDirectoryInformation isn't supported on some
on NT4 and 2K systems. There are also hacked versions of remote drives, but we don't know every system out there.
Samba 3.0.x out there (Debian-based it seems), which return Check various status codes indicating this. */
STATUS_NOT_SUPPORTED rather than handling this info class. if (!NT_SUCCESS (status)
We just fall back to using a standard directory query in
this case and note this case using the dirent_get_d_ino flag. */
if (!NT_SUCCESS (status) && status != STATUS_NO_MORE_FILES
&& (status == STATUS_INVALID_LEVEL && (status == STATUS_INVALID_LEVEL
|| status == STATUS_NOT_SUPPORTED || status == STATUS_NOT_SUPPORTED
|| status == STATUS_INVALID_PARAMETER || status == STATUS_INVALID_PARAMETER
|| status == STATUS_INVALID_NETWORK_RESPONSE || status == STATUS_INVALID_NETWORK_RESPONSE
|| status == STATUS_INVALID_INFO_CLASS)) || status == STATUS_INVALID_INFO_CLASS))
dir->__flags &= ~dirent_get_d_ino; dir->__flags &= ~dirent_get_d_ino;
/* Something weird happens on Samba up to version 3.0.21c, which is
fixed in 3.0.22. FileIdBothDirectoryInformation seems to work
nicely, but only up to the 128th entry in the directory. After
reaching this entry, the next call to NtQueryDirectoryFile
(FileIdBothDirectoryInformation) returns STATUS_INVALID_LEVEL.
Why should we care, we can just switch to
FileBothDirectoryInformation, isn't it? Nope! The next call to
NtQueryDirectoryFile(FileBothDirectoryInformation) actually
returns STATUS_NO_MORE_FILES, regardless how many files are left
unread in the directory. This does not happen when using
FileBothDirectoryInformation right from the start, but since
we can't decide whether the server we're talking with has this
bug or not, we end up serving Samba shares always in the slow
mode using FileBothDirectoryInformation. So, what we do here is
to implement the solution suggested by Andrew Tridgell, we just
reread all entries up to dir->d_position using
FileBothDirectoryInformation.
However, We do *not* mark this server as broken and fall back to
using FileBothDirectoryInformation further on. This would slow
down every access to such a server, even for directories under
128 entries. Also, bigger dirs only suffer from one additional
call per full directory scan, which shouldn't be too big a hit.
This can easily be changed if necessary. */
if (status == STATUS_INVALID_LEVEL && dir->__d_position)
{
d_cachepos (dir) = 0;
for (int cnt = 0; cnt < dir->__d_position; ++cnt)
{
if (d_cachepos (dir) == 0)
{
status = NtQueryDirectoryFile (get_handle (), NULL, NULL,
NULL, &io, d_cache (dir),
DIR_BUF_SIZE,
FileBothDirectoryInformation,
FALSE, NULL, cnt == 0);
if (!NT_SUCCESS (status))
goto go_ahead;
}
buf = (PFILE_ID_BOTH_DIR_INFORMATION) (d_cache (dir)
+ d_cachepos (dir));
if (buf->NextEntryOffset == 0)
d_cachepos (dir) = 0;
else
d_cachepos (dir) += buf->NextEntryOffset;
}
goto go_ahead;
}
} }
/* NFS must use FileNamesInformation! Any other information class /* NFS must use FileNamesInformation! Any other information class
skips all symlinks. */ skips all symlinks. */
@ -2535,8 +2485,6 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
FALSE, NULL, dir->__d_position == 0); FALSE, NULL, dir->__d_position == 0);
} }
go_ahead:
if (status == STATUS_NO_MORE_FILES) if (status == STATUS_NO_MORE_FILES)
/*nothing*/; /*nothing*/;
else if (!NT_SUCCESS (status)) else if (!NT_SUCCESS (status))

View File

@ -20,7 +20,7 @@ What changed:
- ps -f now prints the commandline rather than the full path to the - ps -f now prints the commandline rather than the full path to the
executable. executable.
- Drop support for NT4 and Samba < 3.0. - Drop support for NT4 and Samba < 3.0.22.
- Now that SMBv1 is ultimately deprecated and not installed by default - Now that SMBv1 is ultimately deprecated and not installed by default
on latest Windows versions, enumerating network servers in // and shares on latest Windows versions, enumerating network servers in // and shares