Description of problem: Compiling and running the following will result in a corrupted filename. #include <unistd.h> int main (void) { return symlink ("a:b", "f") != 0; } The symlink has to be created on a CIFS mount. The colon then gets substituted for U+F022. Version-Release number of selected component (if applicable): samba-4.4.6-1.fc24.x86_64 Steps to Reproduce: 1. See description. Actual results: Corrupted filename. Expected results: Filename with a colon in it. Additional info: Running "ln -s <target> a:b" works.
This is not a bug in Samba. MS-CIFS specification forbids a number of characters to be present in the file names, see MS-CIFS 2.2.1.1.1. cifs.ko kernel module obeys the restriction and does not allow to use them in file names. In case 'mapchars' option was specified when mounting the share, cifs.ko module maps the characters except a backslash to the range above 0xF000, so colon becomes 0xF022. This only works with SMB servers supporting Unicode on the wire (Samba does support it), but Samba does not allow specifying the original, non-translated characters in any case, to be compatible with the MS-CIFS specification. Windows POSIX emulation does the translation as well. By default cifs.ko does not do the translation, so if you see the translated character it means 'mapchars' option was specified in the mount options on one client and then without 'mapchars' on another. Once you started mapping characters, you need to always specify 'mapchars' when mounting the share or otherwise you'll get 'corrupted' characters back. They are stored converted on the SMB server side. For example, on F24: [root@f24-master ~]# mount -t cifs //`hostname`/testshare /mnt/ -o mapchars,user=admin Password for admin@//f24-master.ipa.ad.test/testshare: ******** [root@f24-master ~]# mount|grep testshare //f24-master.ipa.ad.test/testshare on /mnt type cifs (rw,relatime,vers=1.0,cache=strict,username=admin,domain=IPAAD,uid=0,noforceuid,gid=0,noforcegid,addr=192.168.5.117,unix,posixpaths,serverino,mapchars,acl,rsize=1048576,wsize=65536,echo_interval=60,actimeo=1,user=admin) [root@f24-master ~]# touch /mnt/a:b [root@f24-master ~]# ls -la /mnt/a:b -rw-r--r--+ 1 admin admins 0 Oct 12 13:01 /mnt/a:b [root@f24-master ~]# ls -la /mnt/ total 0 drwxrwxr-x+ 2 root root 0 Oct 12 13:01 . dr-xr-xr-x. 17 root root 259 May 31 11:09 .. -rw-r--r--+ 1 admin admins 0 Oct 12 13:01 a:b [root@f24-master ~]# ls -la /srv/myshare/ total 0 drwxrwxr-x+ 2 root root 19 Oct 12 13:01 . drwxr-xr-x. 3 root root 21 Oct 12 12:58 .. -rw-r--r--. 1 admin admins 0 Oct 12 13:01 ab [root@f24-master ~]# umount /mnt [root@f24-master ~]# mount -t cifs //`hostname`/testshare /mnt/ -o user=admin Password for admin@//f24-master.ipa.ad.test/testshare: ******** [root@f24-master ~]# ls -la /mnt/ total 0 drwxrwxr-x+ 2 root root 0 Oct 12 13:01 . dr-xr-xr-x. 17 root root 259 May 31 11:09 .. -rw-r--r--+ 1 admin admins 0 Oct 12 13:01 ab [root@f24-master ~]# So you can see that doing mount without mapchars option does not change filenames which were created when using mapchars option.
I observed the problem on Fedora 24 without using any mapchars option, and without using multiple clients or unmounting and remounting the CIFS file system. I created a simple share using the recipe at the start of <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24656#c5>, appending this to the otherwise-stock /etc/samba/smb.conf: [public] browseable = Yes guest ok = Yes path = /tmp/samba read only = No Although I normally don't run Samba, I enabled it as follows: setsebool -P samba_export_all_rw 1 service smb restart mount -t cifs //penguin.cs.ucla.edu/public /mnt/tmp -o guest cd /mnt/tmp I then compiled and ran the following program: #include <unistd.h> int main (void) { return symlink ("a:b", "f") != 0; } This created a symbolic link from "f" to "a<F022>b", where "<F022>" stands for the UTF-8 representation for U+F022, i.e., the bytes EF, 80, A2.
I can see that cifs.ko actually passing U+F022 on the wire because this is what Samba receives from the network: [2016/10/12 19:16:02.473717, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../lib/util/util.c:559(dump_data) [0000] 00 00 00 09 02 00 00 00 00 2F 00 61 00 22 F0 62 ........ ./.a.".b [0010] 00 00 00 02 00 00 00 12 00 00 00 A4 81 00 00 00 ........ ........ [0020] 00 00 00 00 02 ..... [2016/10/12 19:16:02.473743, 3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/process.c:1538(switch_message) switch message SMBtrans2 (pid 3889) conn 0x555d829c0680 [2016/10/12 19:16:02.473750, 4, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/uid.c:384(change_to_user) Skipping user change - already user [2016/10/12 19:16:02.473772, 5, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/filename.c:276(unix_convert) unix_convert called on file "ab" [2016/10/12 19:16:02.473777, 5, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/filename.c:469(unix_convert) unix_convert begin: name = ab, dirpath = , start = ab [2016/10/12 19:16:02.473788, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1160(check_reduced_name) check_reduced_name: check_reduced_name [ab] [/srv/myshare] [2016/10/12 19:16:02.473798, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1220(check_reduced_name) check_reduced_name realpath [ab] -> [/srv/myshare/ab] [2016/10/12 19:16:02.473803, 5, pid=3889, effective(903200000, 903200000), real(903200000, 0), class=vfs] ../source3/smbd/vfs.c:1307(check_reduced_name) check_reduced_name: ab reduced to /srv/myshare/ab [2016/10/12 19:16:02.473807, 3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8739(call_trans2setfilepathinfo) call_trans2setfilepathinfo(6) ab (fnum [fsp is NULL]) info_level=521 totdata=18 [2016/10/12 19:16:02.473813, 3, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8299(smbd_do_setfilepathinfo) smbd_do_setfilepathinfo: ab (fnum [fsp is NULL]) info_level=521 totdata=18 [2016/10/12 19:16:02.473818, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/trans2.c:8058(smb_posix_open) smb_posix_open: file ab, smb_posix_flags = 0, mode 0644 [2016/10/12 19:16:02.473822, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/open.c:5030(create_file_default) create_file: access_mask = 0x112 file_attributes = 0x10001a4, share_access = 0x7, create_disposition = 0x3 create_options = 0x40 oplock_request = 0x1 private_flags = 0x0 root_dir_fid = 0x0, ea_list = 0x(nil), sd = 0x(nil), fname = ab [2016/10/12 19:16:02.473828, 10, pid=3889, effective(903200000, 903200000), real(903200000, 0)] ../source3/smbd/open.c:4505(create_file_unixpath) create_file_unixpath: access_mask = 0x112 file_attributes = 0x10001a4, share_access = 0x7, create_disposition = 0x3 create_options = 0x40 oplock_request = 0x1 private_flags = 0x0 ea_list = 0x(nil), sd = 0x(nil), fname = ab So, the issue is in cifs.ko, it seems, where it tries to translate the name despite using UNIX extensions.
*********** MASS BUG UPDATE ************** We apologize for the inconvenience. There are a large number of bugs to go through and several of them have gone stale. Due to this, we are doing a mass bug update across all of the Fedora 24 kernel bugs. Fedora 25 has now been rebased to 4.10.9-100.fc24. Please test this kernel update (or newer) and let us know if you issue has been resolved or if it is still present with the newer kernel. If you have moved on to Fedora 26, and are still experiencing this issue, please change the version to Fedora 26. If you experience different issues, please open a new bug report for those.
*********** MASS BUG UPDATE ************** This bug is being closed with INSUFFICIENT_DATA as there has not been a response in 2 weeks. If you are still experiencing this issue, please reopen and attach the relevant data from the latest kernel you are running and any data that might have been requested previously.