[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Thu Jul 1 13:49:02 UTC 2021
The branch, master has been updated
via 11a3a8d9b9c WHATSNEW: document new preopen:* options
via 83563b37213 vfs_preopen: add useful debug messages which can be configured on adjustable log levels
via ade3b16490e vfs_preopen: introduce support for "preopen:posix-basic-regex = yes"
via 67159410175 docs-xml:vfs_preopen.8: improve the documentation of the current detection algorithm
via 430cbfc7918 vfs_preopen: make use of any hints from samba_path_matching_check_last_component()
via e51a2e6e4ee vfs_preopen: cap the queue length to the maximum number that fits into the digits space
via 1197c87c916 vfs_preopen: introduce helper variables in preopen_parse_fname()
via 0900ab40d6d vfs_preopen: completely reset the queue if the name structure changes
via d34c291d98e vfs_preopen: only reset the queue state if preopen_parse_fname() found matching digits
via 68832c91bd7 vfs_preopen: make use of new samba_path_matching_* infrastructure
via a843e74b85f vfs_preopen: only try to preopen if we can construct an absolute path
via c6aaa36497f vfs_preopen: introduce "preopen" debug class
via ebe5203c576 docs-xml: document dynamic debug classes from modules
via e2e3b032cd9 lib/util: improve debug message about unknown classes
via bc39450d80b s3:lib: add samba_path_matching_regex_sub1_create()
via 845a59919e5 s3:lib: add a new samba_path_matching* infrastructure
via 0a459c6b2df s3:torture: add STR-MATCH-MSWILD test for is_in_path()
from accaa2f1f67 vfs_default: use copy_file_range()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 11a3a8d9b9c6d008a06a39f4669bb3b50cbe2464
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Jul 1 14:07:34 2021 +0200
WHATSNEW: document new preopen:* options
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Thu Jul 1 13:48:32 UTC 2021 on sn-devel-184
commit 83563b37213cdb58776e034c0bbd22ba55d51022
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 18 14:00:25 2021 +0000
vfs_preopen: add useful debug messages which can be configured on adjustable log levels
The following are the default values:
preopen:nomatch_log_level = 5
preopen:match_log_level = 5
preopen:nodigits_log_level = 1
preopen:founddigits_log_level = 3
preopen:reset_log_level = 5
preopen:push_log_level = 3
preopen:queue_log_level = 10
This gives admins a way to debug/audit the preopen usage.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit ade3b16490e9afdf909a761828a38d80d6596fd1
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 19:07:03 2021 +0000
vfs_preopen: introduce support for "preopen:posix-basic-regex = yes"
This will allow the usage of patterns as
'POSIX Basic Regular Expression'
vfs objects = preopen
preopen:posix-basic-regex = yes
preopen:names = /Re7599Ex\([0-9]\).*\.txt/test\([0-9]*\)\.dat/
The key is that exactly one 'subexpression' starting with '\(' and
ending with '\)' is specified in order to select the position where
the digits are searched.
E.g. given a file name 'Re7599Ex01234.txt' will actually preopen:
Re7599Ex01234.txt
Re7599Ex11234.txt
Re7599Ex21234.txt
Re7599Ex31234.txt
Re7599Ex41234.txt
As '\([0-9]\)' will only match the first digit after 'Re7599Ex'.
It also means it's now possible to have digits in the fixed part of the
filename, which was the actual motivation for this patchset.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 67159410175a9ceccc7beda01601b9dc6656be04
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 28 11:54:29 2021 +0200
docs-xml:vfs_preopen.8: improve the documentation of the current detection algorithm
We should be more verbose that the first digits in a name are taken by
default, if at least 3 digits were found.
There might be cases were the last group of digits describe the
increasing frame number, while the fixed name already contains
3 digits. This is currently not supported.
It's also possible to provide more than one pattern.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 430cbfc7918939fde22d8da2327451b6801173bd
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 21:08:19 2021 +0000
vfs_preopen: make use of any hints from samba_path_matching_check_last_component()
samba_path_matching_check_last_component() may return the start and end
offset of a submatch (for us the bytes where the digits are expected).
We use that in order to allow preopen_parse_fname() to just
look at these bytes and ignore any trailing digits after the submatch.
For the current use of samba_path_matching_mswild_create(),
there's no difference as we'll always get replace_start=-1 and
replace_end=-1. But the next commit will make optional use of
samba_path_matching_regex_sub1_create(), which will change the situation
and allow to return hints we got from regexec().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit e51a2e6e4ee5409a61b2adb069561fcf40da3818
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 18 18:29:31 2021 +0000
vfs_preopen: cap the queue length to the maximum number that fits into the digits space
If we have a single digit we only replace up to '9', which also fits
into a single digit.
We operate on numbers from 0 to 9999999999999999999 independent of the
architecture.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 1197c87c916bc947d8143a57e59e9b36aaba309c
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 21:08:19 2021 +0000
vfs_preopen: introduce helper variables in preopen_parse_fname()
Calculating the start_idx and num_digits at the first possible place
will make the following commits much easier.
At the end we just want to assign the return values without any logic.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 0900ab40d6de6b6d878b6a48cb3df464d536d91b
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 18 13:31:58 2021 +0000
vfs_preopen: completely reset the queue if the name structure changes
There's no point in trying to check if the current number is part
of the existing queue. This makes the logic at least more unstandable
to me.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit d34c291d98e6b0e061406e4d0760ce7db8e69a3f
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 20:03:49 2021 +0000
vfs_preopen: only reset the queue state if preopen_parse_fname() found matching digits
Otherwise there's no point in stopping the existing queue to continue
via pending preopen_helper_readable() invocations.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 68832c91bd718b577c3a25139ab8bee883c36767
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Jun 9 15:08:38 2021 +0200
vfs_preopen: make use of new samba_path_matching_* infrastructure
There should not be any logic change in this commit,
for now we'll keep the same ms wildcard matching we had before.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit a843e74b85f50ca6285b7670f7bafb3199bb6008
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 20:05:14 2021 +0000
vfs_preopen: only try to preopen if we can construct an absolute path
So we make sure the dirfsp contains an absolute path to begin with
and smb_fname is a relative name within the directory.
Note: dirfsp->fsp_name->base_name[0] is only '/' because currently all callers pass
conn->cwd_fsp as dirfsp ... though there's already one caller that calls
fd_openat() with a real dirfsp, that is in vfs_fruit though on the
resource fork stream so doesn't really effect us currently.
If more callers are changed in future the situation may change,
but I guess then this is not the only place with potential problems.
We most likely need a generic helper function that returns the absolute
path of a dirfsp and use it here.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit c6aaa36497f6dc6d4a8488d6ff8f43a6591eda59
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Jun 8 10:56:22 2021 +0200
vfs_preopen: introduce "preopen" debug class
It might be useful to change the level/location
of debug messages specific to this module.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit ebe5203c576576f96e7deffde34364e68d6c4805
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jun 28 11:44:27 2021 +0200
docs-xml: document dynamic debug classes from modules
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit e2e3b032cd94500dd409a44c01abd2357da31c29
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 18 12:18:00 2021 +0000
lib/util: improve debug message about unknown classes
debug classes registered by vfs modules are not available immediately.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit bc39450d80b2f319501747d8b285d0d70ca6505b
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 11 19:03:42 2021 +0000
s3:lib: add samba_path_matching_regex_sub1_create()
This will allow the usage 'POSIX Basic Regular Expression'
instead of 'ms wildcard' strings.
We allow exactly one 'subexpression' starting with '\(' and
ending with '\)' in order to find a replacement (byte) region
in the matching string.
This will be used in the vfs_preopen module in the following
commits.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 845a59919e528d083b1ab025844c41155ac93e43
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Jun 9 14:44:39 2021 +0200
s3:lib: add a new samba_path_matching* infrastructure
This aims to replace the current is_in_path() code in the long run.
For now it implements samba_path_matching_mswild_create()
in order to replace is_in_path() in the long run.
But there will be other "backends" using regexec() too.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 0a459c6b2df45895c7a89a65ce736a1402a88dcc
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Jun 18 21:54:27 2021 +0000
s3:torture: add STR-MATCH-MSWILD test for is_in_path()
I want to assert at least some of the behavior as the
next commits will add a new abstraction that should
at least partly behave the same.
Note: case_[in]sensitive_idx is the index to the patterns
in the namelist, set to -1 on non-match, otherwise to
a value >= 0.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
-----------------------------------------------------------------------
Summary of changes:
WHATSNEW.txt | 20 +-
docs-xml/manpages/vfs_preopen.8.xml | 166 ++++++++-
docs-xml/smbdotconf/logging/loglevel.xml | 17 +
lib/util/debug.c | 3 +-
source3/lib/util_matching.c | 391 +++++++++++++++++++++
.../secace.h => source3/lib/util_matching.h | 31 +-
source3/modules/vfs_preopen.c | 351 ++++++++++++++++--
source3/selftest/tests.py | 2 +
source3/torture/proto.h | 2 +
source3/torture/test_matching.c | 276 +++++++++++++++
source3/torture/torture.c | 8 +
source3/wscript_build | 2 +
12 files changed, 1215 insertions(+), 54 deletions(-)
create mode 100644 source3/lib/util_matching.c
copy libcli/security/secace.h => source3/lib/util_matching.h (50%)
create mode 100644 source3/torture/test_matching.c
Changeset truncated at 500 lines:
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index d8effc5ce09..82bd5eaefc6 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -135,12 +135,20 @@ which have been out of support since 2018.
smb.conf changes
================
- Parameter Name Description Default
- -------------- ----------- -------
- client use kerberos New desired
- client protection New default
- winbind use krb5 enterprise principals Changed Yes
- winbind scan trusted domains Changed No
+ Parameter Name Description Default
+ -------------- ----------- -------
+ client use kerberos New desired
+ client protection New default
+ preopen:posix-basic-regex New No
+ preopen:nomatch_log_level New 5
+ preopen:match_log_level New 5
+ preopen:nodigits_log_level New 1
+ preopen:founddigits_log_level New 3
+ preopen:reset_log_level New 5
+ preopen:push_log_level New 3
+ preopen:queue_log_level New 10
+ winbind use krb5 enterprise principals Changed Yes
+ winbind scan trusted domains Changed No
KNOWN ISSUES
diff --git a/docs-xml/manpages/vfs_preopen.8.xml b/docs-xml/manpages/vfs_preopen.8.xml
index f9f3d60a02a..e826d72ffef 100644
--- a/docs-xml/manpages/vfs_preopen.8.xml
+++ b/docs-xml/manpages/vfs_preopen.8.xml
@@ -49,15 +49,42 @@
<variablelist>
<varlistentry>
- <term>preopen:names = /pattern/</term>
+ <term>preopen:posix-basic-regex = BOOL (default: no)</term>
<listitem>
<para>
- preopen:names specifies the file name pattern which should
+ <command>preopen:posix-basic-regex = yes</command> changes
+ the meaning of the <command>preopen:names</command> option.
+ Further details are described there.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:names = /pattern1/pattern2/</term>
+ <listitem>
+ <para>
+ preopen:names specifies the file name pattern(s) which should
trigger the preopen helpers to do their work. We assume that
the files are numbered incrementally. So if your file names
are numbered FRAME00000.frm FRAME00001.frm and so on you would
- list them as <command>preopen:names=/FRAME*.frm/</command>
+ list them as <command>preopen:names=/FRAME*.frm/</command>.
+ The default algorithm uses the first (at least 3) digits it finds
+ in order to calculate the name of the next frames.
</para>
+
+ <para><command>preopen:posix-basic-regex = yes</command> changes
+ the meaning of the <command>preopen:names</command> option.
+ It means 'POSIX Basic Regular Expression' strings are used
+ as patterns. The key is each pattern requires exactly one
+ 'subexpression' starting with '\(' and ending with '\)' in
+ order to specify the position of the digits representing
+ the incrementing frame numbers. Given a file names like
+ Movie7599Frame0v1234.txt, Movie7599Frame1v1234.txt, Movie7599Frame2v1234.txt
+ up to Movie7599Frame9v1234.txt you can use <command>preopen:names = /.*Frame\([0-9]\).*\.txt/</command>
+ in order to match just a single digits, this might not be a real world example,
+ but it shows the flexiblity that is possible here.
+ </para>
+
</listitem>
</varlistentry>
@@ -90,6 +117,139 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>preopen:nomatch_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug or audit the usage of the preopen logic
+ you can use this option to specify at what log level details
+ about filenames not matching any pattern from '<command>preopen:names</command>'
+ are logged.
+ </para>
+ <para>
+ Defaults to the log level 5.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:match_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug or audit the usage of the preopen logic
+ you can use this option to specify at what log level details
+ about filenames actually matching a pattern from '<command>preopen:names</command>'
+ are logged.
+ </para>
+ <para>
+ See also '<command>preopen:founddigits_log_level</command>' and '<command>preopen:push_log_level</command>'.
+ </para>
+ <para>
+ Defaults to the log level 5.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:nodigits_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug or audit problems with the preopen configuration
+ you can use this option to specify at what log level details
+ about filenames actually matching a pattern from '<command>preopen:names</command>',
+ but at the same time don't contain the expected digits, are logged.
+ This is typically something the administrator wants to notice and
+ adjust the configuration in order to define more precisely where to
+ find the digits in the filename.
+ </para>
+ <para>
+ Defaults to the log level 1.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:founddigits_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug or audit the usage of the preopen logic
+ you can use this option to specify at what log level details
+ about filenames actually matching a pattern from '<command>preopen:names</command>',
+ and at the same time having valid expected digits, are logged. This means enough information is available
+ in order to queue preopens.
+ </para>
+ <para>
+ Defaults to the log level 3.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:reset_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ If a matching filename belongs to a different pattern from '<command>preopen:names</command>',
+ a different parent directory or differs in a significant way from the last filename
+ that was found before, the module needs to reset it's internal queue state.
+ This means that no more preopens will be pushed to helper processes belonging to the
+ former queue state. In order to debug or audit such queue resets you can use this option to specify at what
+ log level details are logged.
+ </para>
+ <para>
+ Defaults to the log level 5.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:push_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug or audit the usage of the preopen logic
+ you can use this option to specify at what log level details
+ about filenames actually pushed to preopen helper processes are logged.
+ This means they will actually be preopened soon.
+ </para>
+ <para>
+ Defaults to the log level 3.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>preopen:queue_log_level = LOGLEVEL</term>
+ <listitem>
+ <para>
+ In order to debug details about internal queue processing
+ you can use this option to specify at what log level the details are logged.
+ </para>
+ <para>
+ Defaults to the log level 10.
+ See also <citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ in the '<smbconfoption name="log level"/>' section
+ for special handling of the 'preopen' debug class.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/docs-xml/smbdotconf/logging/loglevel.xml b/docs-xml/smbdotconf/logging/loglevel.xml
index 4c6bb5e7e73..434c5d06832 100644
--- a/docs-xml/smbdotconf/logging/loglevel.xml
+++ b/docs-xml/smbdotconf/logging/loglevel.xml
@@ -59,6 +59,23 @@
<listitem><para><parameter moreinfo="none">dsdb_group_json_audit</parameter></para></listitem>
</itemizedlist>
+ <para>Various modules register dynamic debug classes at first usage:</para>
+ <itemizedlist>
+ <listitem><para><parameter moreinfo="none">catia</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">dfs_samba4</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">extd_audit</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">fileid</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">fruit</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">full_audit</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">media_harmony</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">preopen</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">recycle</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">shadow_copy</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">shadow_copy</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">unityed_media</parameter></para></listitem>
+ <listitem><para><parameter moreinfo="none">virusfilter</parameter></para></listitem>
+ </itemizedlist>
+
<para>To configure the logging for specific classes to go into a different
file then <smbconfoption name="log file"/>, you can append
<emphasis>@PATH</emphasis> to the class, eg <parameter>log level = 1
diff --git a/lib/util/debug.c b/lib/util/debug.c
index 05a76efc5a4..cd52fe4be77 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -795,8 +795,7 @@ static int debug_lookup_classname(const char *classname)
if (ndx != -1)
return ndx;
- DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
- classname));
+ DBG_WARNING("Unknown classname[%s] -> adding it...\n", classname);
return debug_add_class(classname);
}
diff --git a/source3/lib/util_matching.c b/source3/lib/util_matching.c
new file mode 100644
index 00000000000..4a321f2ca44
--- /dev/null
+++ b/source3/lib/util_matching.c
@@ -0,0 +1,391 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Stefan Metzmacher 2021
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/util_matching.h"
+#include "lib/util/string_wrappers.h"
+
+struct samba_path_matching_entry {
+ const char *name;
+ bool is_wild;
+ regex_t re;
+};
+
+struct samba_path_matching_result {
+ ssize_t replace_start;
+ ssize_t replace_end;
+ bool match;
+};
+
+struct samba_path_matching {
+ bool case_sensitive;
+ NTSTATUS (*matching_fn)(const struct samba_path_matching *pm,
+ const struct samba_path_matching_entry *e,
+ const char *namecomponent,
+ struct samba_path_matching_result *result);
+ size_t num_entries;
+ struct samba_path_matching_entry *entries;
+};
+
+static NTSTATUS samba_path_matching_split(TALLOC_CTX *mem_ctx,
+ const char *namelist_in,
+ struct samba_path_matching **ppm)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *name_end = NULL;
+ char *namelist = NULL;
+ char *namelist_end = NULL;
+ char *nameptr = NULL;
+ struct samba_path_matching *pm = NULL;
+ size_t num_entries = 0;
+ struct samba_path_matching_entry *entries = NULL;
+
+ *ppm = NULL;
+
+ pm = talloc_zero(mem_ctx, struct samba_path_matching);
+ if (pm == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ talloc_reparent(mem_ctx, frame, pm);
+
+ namelist = talloc_strdup(frame, namelist_in);
+ if (namelist == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ nameptr = namelist;
+
+ namelist_end = &namelist[strlen(namelist)];
+
+ /*
+ * We need to make two passes over the string. The
+ * first to count the number of elements, the second
+ * to split it.
+ *
+ * The 1st time entries is NULL.
+ * the 2nd time entries is allocated.
+ */
+again:
+ while (nameptr <= namelist_end) {
+ /* anything left? */
+ if (*nameptr == '\0') {
+ break;
+ }
+
+ if (*nameptr == '/') {
+ /* cope with multiple (useless) /s) */
+ nameptr++;
+ continue;
+ }
+
+ /* find the next '/' or consume remaining */
+ name_end = strchr_m(nameptr, '/');
+ if (entries != NULL) {
+ if (name_end != NULL) {
+ *name_end = '\0';
+ }
+ entries[num_entries].name = talloc_strdup(entries,
+ nameptr);
+ if (entries[num_entries].name == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ num_entries++;
+ if (name_end != NULL) {
+ /* next segment please */
+ nameptr = name_end + 1;
+ continue;
+ }
+
+ /* no entries remaining */
+ break;
+ }
+
+ if (num_entries == 0) {
+ /*
+ * No entries in the first round => we're done
+ */
+ goto done;
+ }
+
+ if (entries != NULL) {
+ /*
+ * We finished the 2nd round => we're done
+ */
+ goto done;
+ }
+
+ /*
+ * Now allocate the array and loop again
+ * in order to split the names.
+ */
+ entries = talloc_zero_array(pm,
+ struct samba_path_matching_entry,
+ num_entries);
+ if (entries == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+ num_entries = 0;
+ nameptr = namelist;
+ goto again;
+
+done:
+ pm->num_entries = num_entries;
+ pm->entries = entries;
+ *ppm = talloc_move(mem_ctx, &pm);
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+};
+
+static NTSTATUS samba_path_create_mswild_fn(const struct samba_path_matching *pm,
+ const struct samba_path_matching_entry *e,
+ const char *namecomponent,
+ struct samba_path_matching_result *result)
+{
+ bool match = false;
+
+ if (e->is_wild) {
+ match = mask_match(namecomponent, e->name, pm->case_sensitive);
+ } else if (pm->case_sensitive) {
+ match = (strcmp(namecomponent, e->name) == 0);
+ } else {
+ match = (strcasecmp_m(namecomponent, e->name) == 0);
+ }
+
+ *result = (struct samba_path_matching_result) {
+ .match = match,
+ .replace_start = -1,
+ .replace_end = -1,
+ };
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS samba_path_matching_mswild_create(TALLOC_CTX *mem_ctx,
+ bool case_sensitive,
+ const char *namelist_in,
+ struct samba_path_matching **ppm)
+{
+ NTSTATUS status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct samba_path_matching *pm = NULL;
+ size_t i;
+
+ *ppm = NULL;
+
+ status = samba_path_matching_split(mem_ctx, namelist_in, &pm);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return status;
+ }
+ talloc_reparent(mem_ctx, frame, pm);
+
+ for (i = 0; i < pm->num_entries; i++) {
+ struct samba_path_matching_entry *e = &pm->entries[i];
+
+ e->is_wild = ms_has_wild(e->name);
+ }
+
+ pm->case_sensitive = case_sensitive;
+ pm->matching_fn = samba_path_create_mswild_fn;
+ *ppm = talloc_move(mem_ctx, &pm);
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+};
+
+static int samba_path_matching_regex_sub1_destructor(struct samba_path_matching *pm)
+{
+ ssize_t i;
+
+ for (i = 0; i < pm->num_entries; i++) {
+ struct samba_path_matching_entry *e = &pm->entries[i];
+
+ regfree(&e->re);
+ }
+
+ pm->num_entries = 0;
+
+ return 0;
+}
+
+static NTSTATUS samba_path_create_regex_sub1_fn(const struct samba_path_matching *pm,
+ const struct samba_path_matching_entry *e,
--
Samba Shared Repository
More information about the samba-cvs
mailing list