1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

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@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Stefan Metzmacher 2021-06-11 19:03:42 +00:00
parent 845a59919e
commit bc39450d80
6 changed files with 245 additions and 0 deletions

View File

@ -24,6 +24,7 @@
struct samba_path_matching_entry {
const char *name;
bool is_wild;
regex_t re;
};
struct samba_path_matching_result {
@ -211,6 +212,114 @@ NTSTATUS samba_path_matching_mswild_create(TALLOC_CTX *mem_ctx,
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,
const char *namecomponent,
struct samba_path_matching_result *result)
{
if (e->re.re_nsub == 1) {
regmatch_t matches[2] = { };
int ret;
ret = regexec(&e->re, namecomponent, 2, matches, 0);
if (ret == 0) {
*result = (struct samba_path_matching_result) {
.match = true,
.replace_start = matches[1].rm_so,
.replace_end = matches[1].rm_eo,
};
return NT_STATUS_OK;
}
}
*result = (struct samba_path_matching_result) {
.match = false,
.replace_start = -1,
.replace_end = -1,
};
return NT_STATUS_OK;
}
NTSTATUS samba_path_matching_regex_sub1_create(TALLOC_CTX *mem_ctx,
const char *namelist_in,
struct samba_path_matching **ppm)
{
NTSTATUS status;
TALLOC_CTX *frame = talloc_stackframe();
struct samba_path_matching *pm = NULL;
ssize_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];
int ret;
ret = regcomp(&e->re, e->name, 0);
if (ret != 0) {
fstring buf = { 0,};
regerror(ret, &e->re, buf, sizeof(buf));
DBG_ERR("idx[%zu] regcomp: /%s/ - %d - %s\n",
i, e->name, ret, buf);
status = NT_STATUS_INVALID_PARAMETER;
i--;
goto cleanup;
}
if (e->re.re_nsub != 1) {
DBG_ERR("idx[%zu] regcomp: /%s/ - re_nsub[%zu] != 1\n",
i, e->name, e->re.re_nsub);
status = NT_STATUS_INVALID_PARAMETER;
goto cleanup;
}
}
talloc_set_destructor(pm, samba_path_matching_regex_sub1_destructor);
pm->case_sensitive = true;
pm->matching_fn = samba_path_create_regex_sub1_fn;
*ppm = talloc_move(mem_ctx, &pm);
TALLOC_FREE(frame);
return NT_STATUS_OK;
cleanup:
for (; i >= 0; i--) {
struct samba_path_matching_entry *e = &pm->entries[i];
regfree(&e->re);
}
TALLOC_FREE(frame);
return status;
};
NTSTATUS samba_path_matching_check_last_component(struct samba_path_matching *pm,
const char *name,
ssize_t *p_match_idx,

View File

@ -27,6 +27,10 @@ NTSTATUS samba_path_matching_mswild_create(TALLOC_CTX *mem_ctx,
const char *namelist_in,
struct samba_path_matching **ppm);
NTSTATUS samba_path_matching_regex_sub1_create(TALLOC_CTX *mem_ctx,
const char *namelist_in,
struct samba_path_matching **ppm);
NTSTATUS samba_path_matching_check_last_component(struct samba_path_matching *pm,
const char *name,
ssize_t *p_match_idx,

View File

@ -282,6 +282,7 @@ local_tests = [
"LOCAL-MEMCACHE",
"LOCAL-STREAM-NAME",
"LOCAL-STR-MATCH-MSWILD",
"LOCAL-STR-MATCH-REGEX-SUB1",
"LOCAL-string_to_sid",
"LOCAL-sid_to_string",
"LOCAL-binary_to_sid",

View File

@ -102,6 +102,7 @@ bool run_async_echo(int dummy);
bool run_smb_any_connect(int dummy);
bool run_addrchange(int dummy);
bool run_str_match_mswild(int dummy);
bool run_str_match_regex_sub1(int dummy);
bool run_notify_online(int dummy);
bool run_nttrans_create(int dummy);
bool run_nttrans_fsctl(int dummy);

View File

@ -148,3 +148,129 @@ bool run_str_match_mswild(int dummy)
return ret;
}
bool run_str_match_regex_sub1(int dummy)
{
const char *invalidlist1 = "/Re7599Ex[0-9].*\\.txt/";
const char *invalidlist2 = "/Re7599Ex\\([0-9]\\).*\\.\\(txt\\)/";
const char *invalidlist3 = "/Re7599Ex\\([0-9]).*\\.txt/";
const char *invalidlist4 = "/Re7599Ex[0-9.*\\.txt/";
const char *namelist = "/Re7599Ex\\([0-9]\\).*\\.txt/test\\(.*\\).txt/^test\\([0-9]*\\).dat/";
struct samba_path_matching *pm = NULL;
const struct str_match_regex_sub1 {
const char *name;
ssize_t match_idx;
ssize_t sub_start;
ssize_t sub_end;
} names[] = {{
.name = "/dir/Re7599Ex567.txt",
.match_idx = 0,
.sub_start = 13,
.sub_end = 14,
},{
.name = "/dir/rE7599eX567.txt",
.match_idx = -1,
.sub_start = -1,
.sub_end = -1,
},{
.name = "/dir/Re7599Ex.txt",
.match_idx = -1,
.sub_start = -1,
.sub_end = -1,
},{
.name = "/dir/testabc123.txt",
.match_idx = 1,
.sub_start = 9,
.sub_end = 15,
},{
.name = "/dir/testabc123.tXt",
.match_idx = -1,
.sub_start = -1,
.sub_end = -1,
},{
.name = "/dir/test123.dat",
.match_idx = 2,
.sub_start = 9,
.sub_end = 12,
},{
.name = "/dir/tEst123.dat",
.match_idx = -1,
.sub_start = -1,
.sub_end = -1,
}};
NTSTATUS status;
size_t i;
bool ret = true;
d_fprintf(stderr, "invalidlist1: %s\n", invalidlist1);
status = samba_path_matching_regex_sub1_create(talloc_tos(),
invalidlist1,
&pm);
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER));
d_fprintf(stderr, "invalidlist2: %s\n", invalidlist2);
status = samba_path_matching_regex_sub1_create(talloc_tos(),
invalidlist2,
&pm);
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER));
d_fprintf(stderr, "invalidlist3: %s\n", invalidlist3);
status = samba_path_matching_regex_sub1_create(talloc_tos(),
invalidlist3,
&pm);
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER));
d_fprintf(stderr, "invalidlist4: %s\n", invalidlist4);
status = samba_path_matching_regex_sub1_create(talloc_tos(),
invalidlist4,
&pm);
SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER));
d_fprintf(stderr, "namelist: %s\n", namelist);
status = samba_path_matching_regex_sub1_create(talloc_tos(),
namelist,
&pm);
SMB_ASSERT(NT_STATUS_IS_OK(status));
for (i = 0; i < ARRAY_SIZE(names); i++) {
const struct str_match_regex_sub1 *n = &names[i];
ssize_t match_idx = -1;
ssize_t replace_start = -1;
ssize_t replace_end = -1;
bool ok = true;
status = samba_path_matching_check_last_component(pm,
n->name,
&match_idx,
&replace_start,
&replace_end);
SMB_ASSERT(NT_STATUS_IS_OK(status));
if (match_idx == -1) {
SMB_ASSERT(replace_start == -1);
SMB_ASSERT(replace_end == -1);
}
if (n->match_idx != match_idx) {
ok = false;
}
if (n->sub_start != replace_start) {
ok = false;
}
if (n->sub_end != replace_end) {
ok = false;
}
d_fprintf(stderr, "name[%s] "
"T[IDX=%zd;START=%zd;END=%zd] "
"M[[IDX=%zd;START=%zd;END=%zd] "
"%s\n",
n->name,
n->match_idx,
n->sub_start,
n->sub_end,
match_idx,
replace_start,
replace_end,
ok ? "OK" : "FAIL");
ret &= ok;
}
return ret;
}

View File

@ -15349,6 +15349,10 @@ static struct {
.name = "LOCAL-STR-MATCH-MSWILD",
.fn = run_str_match_mswild,
},
{
.name = "LOCAL-STR-MATCH-REGEX-SUB1",
.fn = run_str_match_regex_sub1,
},
{
.name = "WBCLIENT-MULTI-PING",
.fn = run_wbclient_multi_ping,