this behavior of smbc_readdir() had me puzzled for a while this morning. Suppose I have a directory containing a "file.dat" and a "file.lnk" which is a symlink pointing to "file.dat". When I open the directory with "smbc_opendir()" and iterate through its content with "smbc_readdir()" I will get both the "file.dat" and "file.lnk". Now if I remove the "file.dat" but leave the - now broken - symlink, smbc_readdir() will not show me the "file.lnk" file.
This becomes a problem when a user tries to delete a directory containing such entries. If the deleting function happens to delete the symlink target before the actual symlink, "smbc_rmdir()" will return ENOTEMPTY and the directory becomes undeletable through Samba.
I can reproduce this behavior with a CentOS 7 server running Samba 4.7.1 and libsmbclient from Samba 4.8.5 used though KDE's KIO Samba plugin on a client running Arch Linux.
Steps to reproduce (run on server):
1) touch file.dat
2) ln -s file.dat file.lnk
3) rm file.dat
4) Walk through the directory on client.
Unfortunately this is by design. Clients using SMB windows access methods see symlinks as real files, and if they are broken they cannot access them.
If you want to see symlinks as symlinks, you need to access the filesystem using the POSIX extensions. At that point you can manipulate and destroy them.
You'll need to fix the broken symlinks before non-posix access can remove them.
Okay, thanks for clearing this up. It is my understanding that I currently can’t enable POSIX extensions if my client is libsmbclient-based?
Yes, I don't think we expose the cli_posix_XXX() function calls we have to libsmbclient code. We could do so, by allowing the caller to specify they want POSIX semantics but we don't currently have that code.