privilegeset_diff: return things in a struct

This commit is contained in:
Ed Kellett 2021-02-14 00:28:22 +00:00
parent 8b8320596c
commit 9962f62577
4 changed files with 49 additions and 55 deletions

View file

@ -61,6 +61,12 @@ struct PrivilegeSet {
int refs;
};
struct privset_diff {
const struct PrivilegeSet *unchanged;
const struct PrivilegeSet *added;
const struct PrivilegeSet *removed;
};
bool privilegeset_in_set(const struct PrivilegeSet *set, const char *priv);
const char **privilegeset_privs(const struct PrivilegeSet *set);
struct PrivilegeSet *privilegeset_set_new(const char *name, const char *privs, PrivilegeFlags flags);
@ -72,6 +78,6 @@ void privilegeset_prepare_rehash(void);
void privilegeset_cleanup_rehash(void);
void privilegeset_report(struct Client *source_p);
const struct PrivilegeSet **privilegeset_diff(const struct PrivilegeSet *, const struct PrivilegeSet *);
struct privset_diff privilegeset_diff(const struct PrivilegeSet *, const struct PrivilegeSet *);
#endif

View file

@ -319,7 +319,7 @@ privilegeset_unref(struct PrivilegeSet *set)
}
}
const struct PrivilegeSet **
struct privset_diff
privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new)
{
static const char *no_privs[] = { NULL };
@ -327,16 +327,15 @@ privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new
static struct PrivilegeSet *set_unchanged = NULL,
*set_added = NULL,
*set_removed = NULL;
static const struct PrivilegeSet *result_sets[3];
static size_t n_privs = 0;
size_t new_size = n_privs ? n_privs : 32;
size_t i = 0, j = 0;
if (result_sets[0] == NULL)
if (set_unchanged == NULL)
{
result_sets[0] = set_unchanged = privilegeset_new_orphan("<unchanged>");
result_sets[1] = set_added = privilegeset_new_orphan("<added>");
result_sets[2] = set_removed = privilegeset_new_orphan("<removed>");
set_unchanged = privilegeset_new_orphan("<unchanged>");
set_added = privilegeset_new_orphan("<added>");
set_removed = privilegeset_new_orphan("<removed>");
}
if (old == NULL)
@ -390,7 +389,11 @@ privilegeset_diff(const struct PrivilegeSet *old, const struct PrivilegeSet *new
set_added->size = res_added - set_added->privs;
set_removed->size = res_removed - set_removed->privs;
return result_sets;
return (struct privset_diff){
.unchanged = set_unchanged,
.added = set_added,
.removed = set_removed,
};
}
void

View file

@ -975,19 +975,15 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf)
void
report_priv_change(struct Client *client, struct PrivilegeSet *old, struct PrivilegeSet *new)
{
const struct PrivilegeSet *added, *removed, *unchanged;
const struct PrivilegeSet **result = privilegeset_diff(old, new);
unchanged = result[0];
added = result[1];
removed = result[2];
struct privset_diff diff = privilegeset_diff(old, new);
hook_data_priv_change hdata = {
.client = client,
.new = new,
.old = old,
.unchanged = unchanged,
.added = added,
.removed = removed,
.unchanged = diff.unchanged,
.added = diff.added,
.removed = diff.removed,
};
call_hook(h_priv_change, &hdata);
}

View file

@ -84,23 +84,19 @@ static void test_privset_diff(void)
{
struct PrivilegeSet *old = privilegeset_set_new("old", "foo bar", 0);
struct PrivilegeSet *new = privilegeset_set_new("new", "foo qux", 0);
const struct PrivilegeSet *added, *removed, *unchanged;
const struct PrivilegeSet **result = privilegeset_diff(old, new);
unchanged = result[0];
added = result[1];
removed = result[2];
struct privset_diff diff = privilegeset_diff(old, new);
is_bool(true, privilegeset_in_set(unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(added, "foo"), MSG);
is_bool(false, privilegeset_in_set(removed, "foo"), MSG);
is_bool(true, privilegeset_in_set(diff.unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.removed, "foo"), MSG);
is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(added, "bar"), MSG);
is_bool(true, privilegeset_in_set(removed, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG);
is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG);
is_bool(false, privilegeset_in_set(unchanged, "qux"), MSG);
is_bool(true, privilegeset_in_set(added, "qux"), MSG);
is_bool(false, privilegeset_in_set(removed, "qux"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "qux"), MSG);
is_bool(true, privilegeset_in_set(diff.added, "qux"), MSG);
is_bool(false, privilegeset_in_set(diff.removed, "qux"), MSG);
cleanup();
}
@ -108,44 +104,37 @@ static void test_privset_diff(void)
static void test_privset_diff_rehash(void)
{
struct PrivilegeSet *set = privilegeset_set_new("test", "foo bar", 0);
const struct PrivilegeSet *added, *removed, *unchanged;
const struct PrivilegeSet **result;
struct privset_diff diff;
privilegeset_ref(set);
privilegeset_prepare_rehash();
/* should have changed from foo, bar to nothing, i.e. -foo -bar */
result = privilegeset_diff(set->shadow, set);
unchanged = result[0];
added = result[1];
removed = result[2];
diff = privilegeset_diff(set->shadow, set);
is_bool(false, privilegeset_in_set(unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(added, "foo"), MSG);
is_bool(true, privilegeset_in_set(removed, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG);
is_bool(true, privilegeset_in_set(diff.removed, "foo"), MSG);
is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(added, "bar"), MSG);
is_bool(true, privilegeset_in_set(removed, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG);
is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG);
privilegeset_set_new("test", "foo qux", 0);
result = privilegeset_diff(set->shadow, set);
unchanged = result[0];
added = result[1];
removed = result[2];
diff = privilegeset_diff(set->shadow, set);
/* should have changed from foo, bar to foo, qux, i.e. =foo -bar +qux */
is_bool(true, privilegeset_in_set(unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(added, "foo"), MSG);
is_bool(false, privilegeset_in_set(removed, "foo"), MSG);
is_bool(true, privilegeset_in_set(diff.unchanged, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "foo"), MSG);
is_bool(false, privilegeset_in_set(diff.removed, "foo"), MSG);
is_bool(false, privilegeset_in_set(unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(added, "bar"), MSG);
is_bool(true, privilegeset_in_set(removed, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "bar"), MSG);
is_bool(false, privilegeset_in_set(diff.added, "bar"), MSG);
is_bool(true, privilegeset_in_set(diff.removed, "bar"), MSG);
is_bool(false, privilegeset_in_set(unchanged, "qux"), MSG);
is_bool(true, privilegeset_in_set(added, "qux"), MSG);
is_bool(false, privilegeset_in_set(removed, "qux"), MSG);
is_bool(false, privilegeset_in_set(diff.unchanged, "qux"), MSG);
is_bool(true, privilegeset_in_set(diff.added, "qux"), MSG);
is_bool(false, privilegeset_in_set(diff.removed, "qux"), MSG);
privilegeset_cleanup_rehash();