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:
parent
845a59919e
commit
bc39450d80
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user