[Samba] smbclient mask command seems not to work the same way with recurse ON for mget and mput

LPC DPG lpcdpg at gmail.com
Mon Aug 24 22:49:04 UTC 2020

Dear Jeremy.

Really appreciate you took your time to answer. I had already reviewed
source4/client/client.c looking for mput (cmd_mput) command, but unluckily
saying that my C programming skills are poor woud be really overrating them.

I'm sorry to disagree for two reasons

1-. It works for mget,  true that the source code is completely different.

2-. If taking a look into smbclient man latest release:

mask <mask>

This command allows the user to set up a mask which will be used during
recursive operation of the mget and mput commands.

The masks specified to the mget and mput commands act as filters for
directories rather than files when recursion is toggled ON.

The mask specified with the mask command is necessary to filter files
within those directories\&. For example, if the mask specified in an mget
command is "source*" and the mask specified with the mask command is "*.c"
and recursion is toggled ON, the mget command will retrieve all files
matching "*.c" in all directories below and including all directories
matching "source*" in the current working directory.

Note that the value for mask defaults to blank (equivalent to "*") and
remains so until the mask command is used to change it\&. It retains the
most recently specified value indefinitely. To avoid unexpected results it
would be wise to change the value of mask back to "*" after using the mget
or mput commands.
I am no native English speaker, but as far as my understanding of your
language goes, it confirms that both * are necessary when recurse is on.
This is my interpretation.
a) recurse OFF; mask *.lsx; mput *.xls -> will transfer all (MMultiple) the
files ending with .xls, but only in the current directory. The mask *.lsx
is ignored, as recurse is off.
b)  a- recurse ON; mask *.lsx; mput *.xls -> should only transfer
directories existing in the current directory whose name end with .xls,
very unlikely, probably none; should they exist, it would transfer files
whose name end with .lsx.
c) a- recurse ON; mask *.lsx; mput * -> should transfer any file ending
with .lsx (mask *.lsx) in any (*) directory contained in the current
d) a- recurse ON; mask *.lsx; mput -> the very same es c).

So, my interpretation is to be wrong for sure, but I think it is what the
man states. In this case, there should be a documentation bug. Otherwise, I
really can't explain no one (but Ruslan, nearly 16 years ago) has ever
happened to run such filter. What's more, after testing with versions
4.2.10, 4.2.14, 4.4.16, 4.6.16 and 4.9.1 in two differente Fedora based
distributions, and having taken a look (with my referred limitations) to
client.c, I'd say mput has never been able to work with mask, unlike mget.

Still trying to compile Samba 4.12.6 in OEL 6.8, though it's a bit tricky
as I must manually compile GMP, Nettle, P11, LibFFI, GNUTLS, etc.
dependencies with versions much newer versions than the ones installable
from RPM, but I am beginning to assume I will find the very same behaviour.

Again, a ton of thanks for your time to review this issue. Best regards.

El lun., 24 ago. 2020 a las 22:33, Jeremy Allison (<jra at samba.org>)

> On Mon, Aug 24, 2020 at 09:15:48PM +0200, LPC DPG via samba wrote:
> > Dear fellows.
> >
> > Another piece of information. The issue reprduces on RHEL 7.7, Samba
> 4.9.1
> >
> > [root at vnhprerhds01 ~]# cat /etc/redhat-release
> > Red Hat Enterprise Linux Server release 7.7 (Maipo)
> > [root at vnhprerhds01 ~]# smbclient -V
> > Version 4.9.1
> >
> > [root at vnhprerhds01 ~]# smbclient -W "${d}" -U "${u}" "${s}" "${p}"
> > Try "help" to get a list of possible commands.
> > smb: \> !mkdir -p /tmp/borrame/a
> > smb: \> !mkdir -p /tmp/borrame/b
> > smb: \> !touch /tmp/borrame/a/AM.xls
> > smb: \> !touch /tmp/borrame/a/AT.xls
> > smb: \> !touch /tmp/borrame/b/BT.xls
> > smb: \> lcd /tmp/borrame
> > smb: \> cd borrar
> > smb: \borrar\> recurse
> > smb: \borrar\> prompt
> > smb: \borrar\> mask *M.xls
> > smb: \borrar\> mput *
> > putting file a/AT.xls as \borrar\a\AT.xls (0,0 kb/s) (average 0,0 kb/s)
> > putting file a/AM.xls as \borrar\a\AM.xls (0,0 kb/s) (average 0,0 kb/s)
> > putting file b/BT.xls as \borrar\b\BT.xls (0,0 kb/s) (average 0,0 kb/s)
> All the 'mask' command does is set a global string that
> is returned by the smbclient internal function: client_get_fileselection().
> Here is the code that decides if smbclient should do anything
> with a given filename:
> /*******************************************************************
>  Decide if a file should be operated on.
> ********************************************************************/
> static bool do_this_one(struct file_info *finfo)
> {
>         if (!finfo->name) {
>                 return false;
>         }
>         if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
>                 return true;
>         }
>         if (*client_get_fileselection() &&
>             !mask_match(finfo->name,client_get_fileselection(),false)) {
>                 DEBUG(3,("mask_match %s failed\n", finfo->name));
>                 return false;
>         }
> .....
> Note, all it's doing is a mask_match() call against the
> returned name and the string set via the 'mask' parameter.
> Note that when you're doing 'recurse' and the operation
> you set you're providing a second mask parameter '*'
> in this case.
> Looks like the function do_list_helper() only looks
> at the mask set via the 'mask' command if it's not
> recursing.
> Looks like this might be a bug that no one ever ran
> into before. Normally, people expect the mask given
> to the mXXXX functions to take priority. I'm guessing
> almost no one uses the 'mask' command.

More information about the samba mailing list