Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ACL: add support for multiple profiles/dvr-configs/channel-tags per u…
…ser, fixes #2495
  • Loading branch information
perexg committed Jun 16, 2015
1 parent dcf5643 commit 78d9eda
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 108 deletions.
203 changes: 104 additions & 99 deletions src/access.c
Expand Up @@ -459,6 +459,8 @@ static access_t *access_alloc(void)
static void
access_update(access_t *a, access_entry_t *ae)
{
idnode_list_mapping_t *ilm;

switch (ae->ae_conn_limit_type) {
case ACCESS_CONN_LIMIT_TYPE_ALL:
if (a->aa_conn_limit < ae->ae_conn_limit)
Expand All @@ -483,22 +485,31 @@ access_update(access_t *a, access_entry_t *ae)
}
}

if(ae->ae_profile && ae->ae_profile->pro_name[0] != '\0') {
if (a->aa_profiles == NULL)
a->aa_profiles = htsmsg_create_list();
htsmsg_add_str(a->aa_profiles, NULL, idnode_uuid_as_str(&ae->ae_profile->pro_id));
LIST_FOREACH(ilm, &ae->ae_profiles, ilm_in1_link) {
profile_t *pro = (profile_t *)ilm->ilm_in2;
if(pro && pro->pro_name[0] != '\0') {
if (a->aa_profiles == NULL)
a->aa_profiles = htsmsg_create_list();
htsmsg_add_str(a->aa_profiles, NULL, idnode_uuid_as_str(&pro->pro_id));
}
}

if(ae->ae_dvr_config && ae->ae_dvr_config->dvr_config_name[0] != '\0') {
if (a->aa_dvrcfgs == NULL)
a->aa_dvrcfgs = htsmsg_create_list();
htsmsg_add_str(a->aa_dvrcfgs, NULL, idnode_uuid_as_str(&ae->ae_dvr_config->dvr_id));
LIST_FOREACH(ilm, &ae->ae_dvr_configs, ilm_in1_link) {
dvr_config_t *dvr = (dvr_config_t *)ilm->ilm_in2;
if(dvr && dvr->dvr_config_name[0] != '\0') {
if (a->aa_dvrcfgs == NULL)
a->aa_dvrcfgs = htsmsg_create_list();
htsmsg_add_str(a->aa_dvrcfgs, NULL, idnode_uuid_as_str(&dvr->dvr_id));
}
}

if(ae->ae_chtag && ae->ae_chtag->ct_name[0] != '\0') {
if (a->aa_chtags == NULL)
a->aa_chtags = htsmsg_create_list();
htsmsg_add_str(a->aa_chtags, NULL, idnode_uuid_as_str(&ae->ae_chtag->ct_id));
LIST_FOREACH(ilm, &ae->ae_chtags, ilm_in1_link) {
channel_tag_t *ct = (channel_tag_t *)ilm->ilm_in2;
if(ct && ct->ct_name[0] != '\0') {
if (a->aa_chtags == NULL)
a->aa_chtags = htsmsg_create_list();
htsmsg_add_str(a->aa_chtags, NULL, idnode_uuid_as_str(&ct->ct_id));
}
}

a->aa_rights |= ae->ae_rights;
Expand Down Expand Up @@ -948,12 +959,9 @@ access_entry_destroy(access_entry_t *ae)
TAILQ_REMOVE(&access_entries, ae, ae_link);
idnode_unlink(&ae->ae_id);

if (ae->ae_profile)
LIST_REMOVE(ae, ae_profile_link);
if (ae->ae_dvr_config)
LIST_REMOVE(ae, ae_dvr_config_link);
if (ae->ae_chtag)
LIST_REMOVE(ae, ae_channel_tag_link);
idnode_list_destroy(&ae->ae_profiles, ae);
idnode_list_destroy(&ae->ae_dvr_configs, ae);
idnode_list_destroy(&ae->ae_chtags, ae);

while((ai = TAILQ_FIRST(&ae->ae_ipmasks)) != NULL)
{
Expand All @@ -972,14 +980,7 @@ access_entry_destroy(access_entry_t *ae)
void
access_destroy_by_profile(profile_t *pro, int delconf)
{
access_entry_t *ae;

while ((ae = LIST_FIRST(&pro->pro_accesses)) != NULL) {
LIST_REMOVE(ae, ae_profile_link);
ae->ae_profile = NULL;
if (delconf)
access_entry_save(ae);
}
idnode_list_destroy(&pro->pro_accesses, pro);
}

/*
Expand All @@ -988,14 +989,7 @@ access_destroy_by_profile(profile_t *pro, int delconf)
void
access_destroy_by_dvr_config(dvr_config_t *cfg, int delconf)
{
access_entry_t *ae;

while ((ae = LIST_FIRST(&cfg->dvr_accesses)) != NULL) {
LIST_REMOVE(ae, ae_dvr_config_link);
ae->ae_dvr_config = NULL;
if (delconf)
access_entry_save(ae);
}
idnode_list_destroy(&cfg->dvr_accesses, cfg);
}

/*
Expand All @@ -1004,14 +998,7 @@ access_destroy_by_dvr_config(dvr_config_t *cfg, int delconf)
void
access_destroy_by_channel_tag(channel_tag_t *ct, int delconf)
{
access_entry_t *ae;

while ((ae = LIST_FIRST(&ct->ct_accesses)) != NULL) {
LIST_REMOVE(ae, ae_channel_tag_link);
ae->ae_chtag = NULL;
if (delconf)
access_entry_save(ae);
}
idnode_list_destroy(&ct->ct_accesses, ct);
}

/**
Expand Down Expand Up @@ -1131,96 +1118,108 @@ access_entry_class_prefix_get(void *o)
}

static int
access_entry_chtag_set(void *o, const void *v)
access_entry_chtag_set_cb ( idnode_t *in1, idnode_t *in2, void *origin )
{
access_entry_t *ae = (access_entry_t *)o;
channel_tag_t *tag = v ? channel_tag_find_by_uuid(v) : NULL;
if (tag == NULL && ae->ae_chtag) {
LIST_REMOVE(ae, ae_channel_tag_link);
ae->ae_chtag = NULL;
return 1;
} else if (ae->ae_chtag != tag) {
if (ae->ae_chtag)
LIST_REMOVE(ae, ae_channel_tag_link);
ae->ae_chtag = tag;
LIST_INSERT_HEAD(&tag->ct_accesses, ae, ae_channel_tag_link);
access_entry_t *ae = (access_entry_t *)in1;
idnode_list_mapping_t *ilm;
channel_tag_t *ct = (channel_tag_t *)in2;
ilm = idnode_list_link(in1, &ae->ae_chtags, in2, &ct->ct_accesses, origin);
if (ilm) {
ilm->ilm_in1_save = 1;
return 1;
}
return 0;
}

static int
access_entry_chtag_set(void *o, const void *v)
{
access_entry_t *ae = (access_entry_t *)o;
return idnode_list_set1(&ae->ae_id, &ae->ae_chtags,
&channel_tag_class, (htsmsg_t *)v,
access_entry_chtag_set_cb);
}

static const void *
access_entry_chtag_get(void *o)
{
static const char *ret;
access_entry_t *ae = (access_entry_t *)o;
if (ae->ae_chtag)
ret = idnode_uuid_as_str(&ae->ae_chtag->ct_id);
else
ret = "";
return &ret;
return idnode_list_get1(&((access_entry_t *)o)->ae_chtags);
}

static char *
access_entry_chtag_rend (void *o)
{
return idnode_list_get_csv1(&((access_entry_t *)o)->ae_chtags);
}

static int
access_entry_dvr_config_set(void *o, const void *v)
access_entry_dvr_config_set_cb ( idnode_t *in1, idnode_t *in2, void *origin )
{
access_entry_t *ae = (access_entry_t *)o;
dvr_config_t *cfg = v ? dvr_config_find_by_uuid(v) : NULL;
if (cfg == NULL && ae->ae_dvr_config) {
LIST_REMOVE(ae, ae_dvr_config_link);
ae->ae_dvr_config = NULL;
return 1;
} else if (ae->ae_dvr_config != cfg) {
if (ae->ae_dvr_config)
LIST_REMOVE(ae, ae_dvr_config_link);
ae->ae_dvr_config = cfg;
LIST_INSERT_HEAD(&cfg->dvr_accesses, ae, ae_dvr_config_link);
access_entry_t *ae = (access_entry_t *)in1;
idnode_list_mapping_t *ilm;
dvr_config_t *dvr = (dvr_config_t *)in2;
ilm = idnode_list_link(in1, &ae->ae_dvr_configs, in2, &dvr->dvr_accesses, origin);
if (ilm) {
ilm->ilm_in1_save = 1;
return 1;
}
return 0;
}

static int
access_entry_dvr_config_set(void *o, const void *v)
{
access_entry_t *ae = (access_entry_t *)o;
return idnode_list_set1(&ae->ae_id, &ae->ae_dvr_configs,
&dvr_config_class, (htsmsg_t *)v,
access_entry_dvr_config_set_cb);
}

static const void *
access_entry_dvr_config_get(void *o)
{
static const char *ret;
access_entry_t *ae = (access_entry_t *)o;
if (ae->ae_dvr_config)
ret = idnode_uuid_as_str(&ae->ae_dvr_config->dvr_id);
else
ret = "";
return &ret;
return idnode_list_get1(&((access_entry_t *)o)->ae_dvr_configs);
}

static char *
access_entry_dvr_config_rend (void *o)
{
return idnode_list_get_csv1(&((access_entry_t *)o)->ae_dvr_configs);
}

static int
access_entry_profile_set(void *o, const void *v)
access_entry_profile_set_cb ( idnode_t *in1, idnode_t *in2, void *origin )
{
access_entry_t *ae = (access_entry_t *)o;
profile_t *pro = v ? profile_find_by_uuid(v) : NULL;
if (pro == NULL && ae->ae_profile) {
LIST_REMOVE(ae, ae_profile_link);
ae->ae_profile = NULL;
return 1;
} else if (ae->ae_profile != pro) {
if (ae->ae_profile)
LIST_REMOVE(ae, ae_profile_link);
ae->ae_profile = pro;
LIST_INSERT_HEAD(&pro->pro_accesses, ae, ae_profile_link);
access_entry_t *ae = (access_entry_t *)in1;
idnode_list_mapping_t *ilm;
profile_t *pro = (profile_t *)in2;
ilm = idnode_list_link(in1, &ae->ae_profiles, in2, &pro->pro_accesses, origin);
if (ilm) {
ilm->ilm_in1_save = 1;
return 1;
}
return 0;
}

static int
access_entry_profile_set(void *o, const void *v)
{
access_entry_t *ae = (access_entry_t *)o;
return idnode_list_set1(&ae->ae_id, &ae->ae_profiles,
&profile_class, (htsmsg_t *)v,
access_entry_profile_set_cb);
}

static const void *
access_entry_profile_get(void *o)
{
static const char *ret;
access_entry_t *ae = (access_entry_t *)o;
if (ae->ae_profile)
ret = idnode_uuid_as_str(&ae->ae_profile->pro_id);
else
ret = "";
return &ret;
return idnode_list_get1(&((access_entry_t *)o)->ae_profiles);
}

static char *
access_entry_profile_rend (void *o)
{
return idnode_list_get_csv1(&((access_entry_t *)o)->ae_profiles);
}

static htsmsg_t *
Expand Down Expand Up @@ -1292,11 +1291,13 @@ const idclass_t access_entry_class = {
},
{
.type = PT_STR,
.islist = 1,
.id = "profile",
.name = "Streaming Profile",
.set = access_entry_profile_set,
.get = access_entry_profile_get,
.list = profile_class_get_list,
.rend = access_entry_profile_rend,
},
{
.type = PT_BOOL,
Expand Down Expand Up @@ -1331,11 +1332,13 @@ const idclass_t access_entry_class = {
},
{
.type = PT_STR,
.islist = 1,
.id = "dvr_config",
.name = "DVR Config Profile",
.set = access_entry_dvr_config_set,
.get = access_entry_dvr_config_get,
.list = dvr_entry_class_config_name_list,
.rend = access_entry_dvr_config_rend,
},
{
.type = PT_BOOL,
Expand Down Expand Up @@ -1378,11 +1381,13 @@ const idclass_t access_entry_class = {
},
{
.type = PT_STR,
.islist = 1,
.id = "channel_tag",
.name = "Channel Tag",
.set = access_entry_chtag_set,
.get = access_entry_chtag_get,
.list = channel_tag_class_get_list,
.rend = access_entry_chtag_rend,
},
{
.type = PT_STR,
Expand Down
10 changes: 4 additions & 6 deletions src/access.h
Expand Up @@ -83,8 +83,7 @@ typedef struct access_entry {
int ae_adv_streaming;
int ae_htsp_streaming;

struct profile *ae_profile;
LIST_ENTRY(access_entry) ae_profile_link;
idnode_list_head_t ae_profiles;

int ae_conn_limit_type;
uint32_t ae_conn_limit;
Expand All @@ -94,17 +93,16 @@ typedef struct access_entry {
int ae_all_dvr;
int ae_all_rw_dvr;
int ae_failed_dvr;
struct dvr_config *ae_dvr_config;
LIST_ENTRY(access_entry) ae_dvr_config_link;

idnode_list_head_t ae_dvr_configs;

int ae_webui;
int ae_admin;

uint64_t ae_chmin;
uint64_t ae_chmax;

struct channel_tag *ae_chtag;
LIST_ENTRY(access_entry) ae_channel_tag_link;
idnode_list_head_t ae_chtags;

uint32_t ae_rights;

Expand Down
2 changes: 1 addition & 1 deletion src/channels.h
Expand Up @@ -102,7 +102,7 @@ typedef struct channel_tag {

struct dvr_autorec_entry_list ct_autorecs;

struct access_entry_list ct_accesses;
idnode_list_head_t ct_accesses;

int ct_htsp_id;

Expand Down

0 comments on commit 78d9eda

Please sign in to comment.