[Samba] Feedback request on a tentative proposal to enhance smb.conf symlink-related params

Stilez Stilezy stilezy at gmail.com
Thu Mar 1 10:48:02 UTC 2018


As mentioned in another thread, I notice that the params used to control
symlinks feel a bit inefficient and inelegant, and quite limited.  I think
there might be a good opportunity to simplify and also make their
management in Samba more powerful and adaptable to use-cases.  I'm guessing
this list is a good enough starting point to propose a smb.conf param
change to this area and see what reactions it gets.


*The issue:*

Currently symlink handling uses 3 parameters:

 - "follow symlinks" (are they followed at all?)
 - "wide links" (if so, can they be traversed to a location that isn't a
child of the share root dir? Effectively "read/traverse but not write"
restriction)
 - "allow insecure links" (effectively "non-write restriction" removed,
user can write wide links to arbitrary dirs. as well as follow them)

Limitations/opacity caused by the current options:

1. These three params have slightly opaque names ("wide links" doesn't say
*what* about wide links is/isn't altered by the option), and only certain
combinations make sense. Implication:  smb.conf could combine them to good
effect, simplifying the config, and also being clearer about how they
relate to each other.

2. There is no granularity about where symlinks can link to. The only
granularity within Samba is to restrict read/traversal/create to either * a
descendant of /dir/share, or * a descendant of / (=universal access).
There's no other restriction setup possible within smb.conf. An implication
is that it's impossible to include a directive that restricts symlink
use+creation to specified locations outside the share root, other than by
allowing them to have scope over the entire of /. For example, a if the
file system separates user home and "generally available files", or has a
virtual file system made up of dynamically updated symlinks, the user can't
create symlinks unless these are all under the same share root, in which
case the file system is forced to allow symlinks to dirs. that might not be
desirable. Alternatively if they aren't under a common share root the user
can't maintain symlinks as the only directive available gives permission to
create links to anywhere. It's very crude.


*Tentative ideas for discussion:*

Replace the current symlink handling directives by directives modelled on
valid/invalid hosts+users:

*valid symlink targets = follow:<mask>, <mask>, <mask> ... [create:]
<mask>, <mask>, <mask>, ...*
*invalid symlink targets = follow:<mask>, <mask>, <mask> ... [create:]
<mask>, <mask>, <mask>, ...*

<mask> is built as usual from % substitutions,
default for each share is   *valid symlink targets = follow:%P, create:%P*

The syntax in each param is a keyword (follow: | create:) which identifies
if the masks after it control *following* a symlink to the location, or
*creating* a symlink to the location. The type must be explicit (no
implicit "follow"). After each "(follow: | create:)", any masks listed are
deemed to be of that type. An empty list is valid and means "none".

   - A symlink to /dir/foo/bar will be *followed *if any of /, /dir,
   /dir/foo, or /dir/foo/bar are given as "follow" masks in a "valid symlink
   targets" (*provided that* none of these is also listed within an
   "invalid symlink targets" follow clause).
   - A symlink to /dir/foo/bar can be *created* by a user if any of /,
   /dir, /dir/foo, or /dir/foo/bar are given as "create" masks in a "valid
   symlink targets" (*provided that* none of these is also listed within an
   "invalid symlink targets" create clause).


*Examples (the share root in each case is /dir/foo/share):*


*DEFAULT (follow:%P, create:%P)*
 - user can follow a symlink anywhere within /dir/foo/share and subdirs
with path /dir/foo/share/**, and can create symlinks that point at any
target within these. Same as current "follow symlinks"

*valid symlink targets = follow:/*
 - user can follow a symlink anywhere within file system tree, but can only
create symlinks that point to targets like /dir/foo/share/** (default for
create is %P). Same as current "follow symlinks" + "wide links"

*valid symlink targets = follow:/, create:/*
 - user can follow a symlink anywhere within file system tree, and create
symlinks that point to targets anywhere in the file system tree. Same as
current "follow symlinks" + "wide links" + "insecure wide links"

*valid symlink targets = follow:/, create:/*
*invalid symlink targets = create:/etc, /bin, /boot, /dev, follow:/etc,
/dev*
  - user can create symlinks that point anywhere except a descendant of
/etc, /bin, /dev, and can follow symlinks anywhere other than to
descendants of /etc and /dev

*valid symlink targets = follow:%P, %P/../bar1, %P/../bar2, create:**%P,
%P/../bar1, %P/../bar2*
  - user can follow symlinks to targets within /dir/foo/share,
/dir/foo/bar1 and /dir/foo/bar2, but not to any other locations outside the
share root, and can create symlinks to any location in these dirs. (but not
to locations in other "wide" dirs.)

*valid symlink targets = follow:%P, %P/../bar1, %P/../bar2, create:**%P,
%P/../bar1, %P/../bar2*
*invalid symlink targets = follow:%P/../bar1/private, create:*
*%P/../bar1/private*
  - as above but cannot follow or create any symlink whose destination is
within /dir/foo/bar1/private

*valid symlink targets = follow:%P, /pub, create:**%P, /pub/devel*
*invalid symlink targets = create:/pub/devel/unlinkable*
  - the user can follow and create symlinks pointing within the share root.
They can also follow any symlink to a target within /pub (a general public
dir), and can create symlinks to *most* locations within /pub, with the
exception of links to /pub/unlinkable/***

*invalid symlink targets = create:/, follow:/*
  - user cannot create or follow any symlinks

*valid symlink targets = create: , follow:*
  - overrides the defaults of %P with empty follow+allow lists, effectively
making symlinks followable to no targets and creatable to no targets,
Equivalent to previous example.


This would simplify and enhance symlink handling, by allowing a user to
specify explicitly where symlinks can/cannot be followed to, and where they
can/cannot be created to link to. So a Samba share could allow wide symlink
creation and yet restrict where they linked, either by enumerating
acceptable locations or prohibiting invalid ones - a very powerful and
flexible tool.  It also simplifies and replicates current behaviour, and
brings symlink params in line with other "valid/invalid" params, such as
those permitting/prohibiting IPs/hosts/users.

(As an aside, I haven't assumed regex because I figure this is way powerful
enough for the majority of uses that aren't currently configurable, and
Samba needs to be fast but regex is expensive. Not much gain, lots of
potential cost.)

Feedback and suggestions/comments sought?

Thanks,

Stilez


More information about the samba mailing list