At least these two places in ADS over xattr vfs make assume that extended attribute value must be null-terminated: "source3/modules/vfs_streams_xattr.c" line 491 /* * Darn, xattrs need at least 1 byte */ char null = '\0'; "source3/modules/vfs_streams_xattr.c" line 1024 length = ea.value.length-1; DEBUG(10, ("streams_xattr_pread: get_ea_value returned %d bytes\n", (int)length)); However linux extended attribute man pages are clear that zero-length values are in fact allowed: setxattr() sets the value of the extended attribute identified by name and associated with the given path in the filesystem. The size argument specifies the size (in bytes) of value; a zero-length value is permitted. My use case is that I want to set extended attributes natively on the samba server and have those readable as ADS for windows clients. Currently if I set 8-byte value, clients see 7-byte value (sans last byte) and I'll probably have to work around samba's vfs module and include a dummy byte at the end.
Linux EA's are not the only EA's Samba uses. We also run on all the *BSD's and also Solaris (and older HPUX and AIX). It's very likely this restriction might come from another platform than Linux (shock, horror :-). They do exist :-). Adding an extra null byte on Linux isn't the end of the world, and I'm having a hard time thinking of this as a Samba bug.
This affects xattr reads and is a real problem there. The Samba read path forces the final byte to be NULL even if it isn't! It doesn't extend the response with an extra NULL pad. It just overwrites the final byte with NULL. Produce the following using macOS Sierra as the client and Samba 4.6 on FreeBSD/ZFS server: On the FreeBSD server on a ZFS backed share: > touch asdf > setextattr user foo bar asdf > getextattr -x user foo asdf asdf 62 61 72 the "foo" attribute is 3 bytes, not NULL padded. On the macOS client: > xattr -p foo asdf ba > xattr -x -p foo asdf 62 61 FreeBSD does have an "-n" option to setextattr, which NULL pads and produces the expected result on the client. This is not the default though and it seems reasonable for Samba to handle both cases. You could make a case for not extending attributes when writing from the client, too, especially when the attribute is binary and not a string. So, the assumption of NULL padding on read is a bug and, perhaps NULL padding should be an option on write instead of forced.
Linux, FreeBSD and Solaris have 0-byte size attributes, so vfs_streams_xattr should default to not append a 0 byte. Alas, we can't change the default, we can only add this as an optional behaviour.
Created attachment 14265 [details] WIP patch that addresses the problem
(In reply to Dima Tisnek from comment #0) Here is the patch I've sent to the Samba ML for the evaluation. If you happen to run the FreeBSD as a Samba server it is already in the ports.
Hello, Is there any chance of getting this bug fixed? I note that TrueNAS have their own fix which might be interesting: https://github.com/truenas/samba/pull/23 Personally, I used rsync -X to move Mac files to an ext4 partition, and shared that via Samba using: streams_xattr:prefix = user. streams_xattr:store_stream_type = no However, the presence of this bug means that the last byte of the attribute contents are replaced with a null termination byte, breaking them back in MacOS. I was able to fix the issue for myself by building from source but decided to see if we could get this open bug advanced all the same :). Howard