struct samba_path_matching_entry {
const char *name;
bool is_wild;
+ regex_t re;
};
struct samba_path_matching_result {
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,
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,
"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",
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);
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;
+}
.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,