Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple dsearch improvements #87

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Remove unused S_IFMT_* funcs; flip nodots to allowdots; deprecate "fi…
…lter=dir implies allowdots"
  • Loading branch information
kurahaupo committed May 4, 2023
commit 38e83d2dccf1fc432125b3be0245ffb56f93e8a5
34 changes: 21 additions & 13 deletions src/src/lookups/dsearch.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ dsearch_find(
{
struct stat statbuf;
int save_errno;
unsigned filter_by_type = 0;
int exclude_dotdotdot = 0;
ifmt_set_t filter_by_type = 0;
int allowdots = 0;
enum {
RET_KEY, /* return the key */
RET_DIR, /* return the dir without the key */
Expand Down Expand Up @@ -166,7 +166,7 @@ if (opts)
else if (Ustrcmp(ele, "dir") == 0)
ret_mode = RET_DIR;
#if 0
/* XXX ret=key is excluded from opts by special-case code in by search_find() */
/* NOTE ret=key is excluded from opts by special-case code in by search_find() */
else if (Ustrcmp(ele, "key") == 0)
ret_mode = RET_KEY;
#endif
Expand All @@ -179,11 +179,19 @@ if (opts)
else if (Ustrncmp(ele, "filter=", 7) == 0)
{
ele += 7;
int i = S_IFMTix_from_name(ele);
if (i>=0)
filter_by_type |= BIT(i);
else if (Ustrcmp(ele, "subdir") == 0) filter_by_type |= BIT(S_IFMT_to_index(S_IFDIR)), exclude_dotdotdot = 1; /* dir but not "." or ".." */
else if (Ustrcmp(ele, "nodots") == 0) exclude_dotdotdot = 1; /* any but "." or ".." */
ifmt_set_t m = S_IFMTset_from_name(ele);
if (m)
{
filter_by_type |= m;
/* XXX issue immediate deprecation warning */
#ifndef NO_DIR_IMPLIES_ALLOWDOTS
/* allow "." or ".." when "dir" rather than "subdir" */
if (m == S_IFMT_to_set(S_IFDIR) && ele[0] == 'd')
allowdots = 1;
#endif
}
else if (Ustrcmp(ele, "allowdots") == 0)
allowdots = 1; /* allow "." or ".." */
else
{
*errmsg = string_sprintf("unknown parameter for dsearch lookup: %s", ele-=7);
Expand All @@ -206,15 +214,15 @@ if (ignore_key)
else if (keystring == NULL || keystring[0] == 0) /* in case lstat treats "/dir/" the same as "/dir/." */
return FAIL;

DEBUG(D_lookup) debug_printf_indent(" dsearch_find: %s%sfilterbits=%#x ret=%s key=%s\n",
DEBUG(D_lookup) debug_printf_indent(" dsearch_find: %s%sfilter_set=%04jx ret=%s key=%s\n",
follow_symlink ? "follow, " : "",
exclude_dotdotdot ? "filter=nodots, " : "",
filter_by_type,
allowdots ? "filter=allowdots, " : "",
(uintmax_t) filter_by_type,
ret_mode == RET_FULL ? "full" : ret_mode == RET_DIR ? "dir" : "key",
keystring);

/* exclude "." and ".." when {filter=subdir} included */
if (exclude_dotdotdot
if (! allowdots
&& keystring[0] == '.'
&& (keystring[1] == 0
|| keystring[1] == '.' && keystring[2] == 0))
Expand All @@ -235,7 +243,7 @@ else
if (stat_result >= 0)
{
if (!filter_by_type
|| filter_by_type & BIT(S_IFMT_to_index(statbuf.st_mode)))
|| filter_by_type & S_IFMT_to_set(statbuf.st_mode))
{
switch (ret_mode)
{
Expand Down
25 changes: 5 additions & 20 deletions src/src/lookups/lf_check_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static const struct {
/* sorted in descending order of likelihood */
{ CUS "file", S_IFMT_to_index(S_IFREG) },
{ CUS "dir", S_IFMT_to_index(S_IFDIR) },
{ CUS "subdir", S_IFMT_to_index(S_IFDIR) },
#ifdef S_IFLNK
{ CUS "symlink", S_IFMT_to_index(S_IFLNK) },
{ CUS "link", S_IFMT_to_index(S_IFLNK) },
Expand All @@ -100,13 +101,13 @@ static const struct {
};
static const size_t num_ni_map = nelem(ni_map);

int
S_IFMTix_from_name(const uschar *name)
ifmt_set_t
S_IFMTset_from_name(const uschar *name)
{
for (int i=0 ; i < num_ni_map ; ++i)
if (Ustrcmp(ni_map[i].name, name) == 0)
return ni_map[i].index;
return -1;
return 1UL << ni_map[i].index;
return 0;
}

const uschar *
Expand All @@ -117,22 +118,6 @@ if (index < 0 || index >= num_S_IF_names)
return S_IF_longnames[index];
}

const uschar *
S_IFMTix_to_name(int index)
{
if (index < 0 || index >= num_S_IF_names)
return NULL; /* invalid file type */
return S_IF_names[index];
}

const uschar *
S_IFMTix_to_ucname(int index)
{
if (index < 0 || index >= num_S_IF_names)
return NULL; /* invalid file type */
return S_IF_ucnames[index];
}

/*************************************************
* Check a file's credentials *
*************************************************/
Expand Down
18 changes: 10 additions & 8 deletions src/src/lookups/lf_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extern int lf_sqlperform(const uschar *, const uschar *, const uschar *,
printf("%s is a %s\n", filename, t);
else
printf("%s is unknown\n", filename);
if ( allowed_filetype_mask & BIT(S_IFMT_to_index(s.st_mode)) )
if ( allowed_filetype_mask & S_IFMT_to_set(s.st_mode) )
printf("\tALLOWED\n");
else
printf("\tFORBIDDEN\n");
Expand Down Expand Up @@ -58,15 +58,17 @@ extern int lf_sqlperform(const uschar *, const uschar *, const uschar *,
#define S_IFMT_to_index(S) ( (S_IFMT & (S)) / S_IFMT_scale )
#define S_IFMT_from_index(I) ( S_IFMT & (I) * S_IFMT_scale )

typedef unsigned long ifmt_set_t;

extern const uschar *S_IFMTix_to_name(int index); /* NULL on error */
#define S_IFMT_to_set(S) (1UL << S_IFMT_to_index(S))

extern ifmt_set_t S_IFMTset_from_name(const uschar *name); /* zero on error */
extern const uschar *S_IFMTix_to_long_name(int index); /* NULL on error */
extern const uschar *S_IFMTix_to_ucname(int index); /* NULL on error */
extern int S_IFMTix_from_name(const uschar *name); /* negative on error */

static inline const uschar *S_IFMT_to_name(int index) { int i = S_IFMT_to_index(index); return i<0 ? NULL : S_IFMTix_to_name(i); } /* NULL on error */
static inline const uschar *S_IFMT_to_long_name(int index) { int i = S_IFMT_to_index(index); return i<0 ? NULL : S_IFMTix_to_long_name(i); } /* NULL on error */
static inline const uschar *S_IFMT_to_ucname(int index) { int i = S_IFMT_to_index(index); return i<0 ? NULL : S_IFMTix_to_ucname(i); } /* NULL on error */
static inline int S_IFMT_from_name(const uschar *name) { int i = S_IFMTix_from_name(name); return i<0 ? -1 : S_IFMT_from_index(i); } /* negative on error */
static inline const uschar *
S_IFMT_to_long_name(int ifmt) { /* NULL on error */
int i = S_IFMT_to_index(ifmt);
return i<0 ? NULL : S_IFMTix_to_long_name(i);
}

/* End of lf_functions.h */