[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