Bug 15506 - Windows clients can't create symbolic links on a Samba server
Summary: Windows clients can't create symbolic links on a Samba server
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: 4.17.8
Hardware: All Linux
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-10-26 21:49 UTC by Jean-François Larvoire
Modified: 2023-11-04 18:32 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-François Larvoire 2023-10-26 21:49:05 UTC
I have a WIN32 console application which (among other things) creates symbolic links using the WIN32 API CreateSymbolicLink().
It works fine on local Windows drives, and on network drives on remote Windows servers.
But on network drives on Raspberry Pi servers running Samba, CreateSymbolicLink() always fails with the WIN32 error 4390 ERROR_NOT_A_REPARSE_POINT "The file or directory is not a reparse point.".
One of the Raspberry Pis is running Raspbian 9.13 "stretch" with Samba Version 4.5.16-Debian.
The other is running Raspbian 12 "bookworm" with Samba Version 4.17.8-Raspbian.

This seems to be a bug in the implementation of the SMB protocol in Samba, regarding the creation of symbolic links.
(As the client works on Windows SMB drives, but not on Samba SMB drives.)

The Samba bugzilla has 11 bugs related to symbolic links, but none related to Windows clients using the WIN32 API CreateSymbolicLink().
I searched on the Internet, but found no mention of this issue.
But I did find a report which looks suspiciously similar: https://freefilesync.org/forum/viewtopic.php?t=490.
Even though that report does not explicitely mention Samba, it is very likely that their cloud server is running it!

To easily reproduce the problem, I've written a small test program which calls CreateSymbolicLink() with the given arguments, and displays the result.
That program is available here: http://jf.larvoire.free.fr/progs/TestLink.exe
Steps to reproduce the problem on any Windows 7 to 11 client:
- Open a cmd shell with administrator rights.
- Connect to a network drive on a Samba server. Ex: S:
- Change the current drive to S:
- List files there, and select one to be the target of the link. Ex: myfile.txt
- Run: TestLink.exe -d mynewlink myfile.txt
Comment 1 Volker Lendecke 2023-10-27 07:34:39 UTC
Shameless self-promotion: https://storagedeveloper.org/events/agenda/session/476
Comment 2 Jean-François Larvoire 2023-10-27 13:37:09 UTC
A very interresting talk indeed... But my problem is the exact opposite situation:
You're trying to improve the connection from Unix clients to Windows servers, by using reparse points to represent Unix file types not available in NTFS on the Windows servers.
I'm trying to connect a Windows client to Unix servers, expecting that the Windows client sees not just files and directories, but also symbolic links on the Ext4 partition. And currently they do not.

Thanks to your talk, I now understand why the error I get mentions reparse points. The Windows client API obviously attempts to create an IO_REPARSE_TAG_SYMLINK reparse point on the server, and the Samba server responds that it cannot do that.
But since the Linux server does support native symbolic links, I would have expected that the Samba server would create a normal Linux symbolic link instead, and pretend it's a Windows IO_REPARSE_TAG_SYMLINK reparse point. This way, both the client and server would be able to handle those symbolic links locally. (At least for relative links.)
Comment 3 Volker Lendecke 2023-10-27 15:28:07 UTC
https://www.youtube.com/watch?v=4JrY-DntoyU will tell you that what you are asking for will be a hard sell in Samba-land. Once we can create the Windows-style symlinks as reparse points, it should be possible to add a sneaky custom extension to do what you want. The first upstream version will create 0-byte files with a reparse point attribute when a Windows client wants to create a symlink. Windows will in fact see this as a symlink, it's just that we are reluctant to actually create symlinks server-side by default.
Comment 4 Jean-François Larvoire 2023-10-31 14:32:05 UTC
Whether symbolic links are a good idea or not is irrelevant here.
I've hit an incompatibility between Unix servers with Samba, and Windows servers. As far as I know, a primary goal of Samba is to allow maximal compatibility between Unix and Windows systems, both ways. So here this incompatibility needs to be fixed.

I don't really care if actual Unix symbolic links are used to emulate Windows symbolic links. For my application this does not matter. But, intuitively, this seems to be the best way to maximize compatibility between the two sides of the networking world. Having that would allow to have Windows and Linux applications seamlessly handling data sets with {files, directories, AND symlinks} both locally and remotely, without having to care if the remote side is Windows or Unix.
But I'm well aware this may not be the simplest way to implement the fix needed!
Comment 5 Jean-François Larvoire 2023-11-04 18:32:50 UTC
An interesting observation today:
I connected my Windows client to the same Linux server share using sshfs.
And sshfs manages symbolic links exactly as I suggested! :-)

Example with the client connected via Samba as drive P:, and via sshfs as drive Q:

> C:\JFL\Docs>net use
> Les nouvelles connexions ne seront pas mémorisées.
> 
> 
> État         Local     Distant                   Réseau
> 
> -------------------------------------------------------------------------------
> OK           P:        \\pi\public               Microsoft Windows Network
>              Q:        \\sshfs.r\pi@pi\srv\public
>                                                 WinFsp.Np
> La commande s’est terminée correctement.
> 
> C:\JFL\Docs>

Then I attempt to create a symbolic link on both drives, using Windows' own mklink.exe:

> P:\Temp>mklink t.lnk t.txt
> Accès refusé.
> 
> P:\Temp>Q:
> 
> Q:\Temp>mklink t.lnk t.txt
> Lien symbolique créé pour t.lnk <<===>> t.txt
> 
> Q:\Temp>dir t.*
>  Le volume dans le lecteur Q n’a pas de nom.
>  Le numéro de série du volume est DD5D-AA08
> 
>  Répertoire de Q:\Temp
> 
> 2023-11-04  19:02    <SYMLINK>      t.lnk [t.txt]
> 2020-07-03  15:01                41 t.txt
>                2 fichier(s)               46 octets
>                0 Rép(s)  725,936,631,808 octets libres
> 
> Q:\Temp>P:
> 
> P:\Temp>dir t.*
>  Le volume dans le lecteur P s’appelle public
>  Le numéro de série du volume est 873A-2E91
> 
>  Répertoire de P:\Temp
> 
> 2020-07-03  15:01                41 t.lnk
> 2020-07-03  15:01                41 t.txt
>                2 fichier(s)               82 octets
>                0 Rép(s)  674,795,839,488 octets libres
> 
> P:\Temp>

Finally, on the Linux side, I see that it's a Linux link that's been created by sshfs:

> larvoire@pi:/srv/public/Temp $ ll t.*
> lrwxrwxrwx 1 pi     pi       5 nov.   4 19:02 t.lnk -> t.txt*
> -rwxrwxrwx 1 nobody nogroup 41 juil.  3  2020 t.txt*
> larvoire@pi:/srv/public/Temp $