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

Stilez stilezy at gmail.com
Thu Mar 1 13:03:39 UTC 2018

(Add to above email in this thread:
Symlink params aren't independent of other params, although conceptually 
they could (and perhaps should?) be. Symlink handling entangles with Unix 
extensions, with possible behaviour changes. The proposal avoids this and 
gives "clean" and easily understood symlink behaviours that don't interact 
with Unix extensions or any other params. So behaviour is consistent, 
easier to be certain of implications, independent of other settings, and 
distinct from whether or not Unix extensions are set.

On 1 March 2018 10:48:02 am Stilez Stilezy <stilezy at gmail.com> wrote:

> 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