Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ACL/DVR: Rewrite channel tag and add DVR config selection
- remove also obsolete only_tag
- accept only uuid for DVR entry config name
- try to lock DVR entry when used in dvr_thread
  • Loading branch information
perexg committed Sep 8, 2014
1 parent 3c64f87 commit 7fdf5f1
Show file tree
Hide file tree
Showing 16 changed files with 479 additions and 149 deletions.
25 changes: 7 additions & 18 deletions docs/html/config_access.html
Expand Up @@ -68,13 +68,11 @@
<dd>
Enables access to all video recording functions. This also include administration of the auto recordings.

<dt>All Configs (VR)
<dt>DVR Config Profile
<dd>
Allow to use all DVR configuration profiles. If not set, a DVR
configuration profile matched to the authorized user by name is always used
(the configuration profile must have same name as the user). If the DVR
configuration profile does not exists, the default profile is used.
The user is also not allowed to select another profile.
If set, the user will only be able to use the DVR config profile
equal to this value.
Note that this field is unset when the DVR Config Profile is removed.

<dt>Web interface
<dd>
Expand All @@ -84,13 +82,6 @@
<dd>
Enables access to the Configuration tab.

<dt>Username Channel Tag Match
<dd>
If enabled, the user will only be able to access channels with a tag the
same name as the username.

This provides a very rudimentary way of limiting access to certain channels.

<dt>Min Channel Num
<dd>
If nonzero, the user will only be able to access channels with
Expand All @@ -103,11 +94,9 @@

<dt>Channel Tag
<dd>
If set, the user will only be able to access channels with
a channel tag equal to this value. Note that this field stores
the tag name (not identified). It means that this field would not be
updated when the tag name is changed. A manual re-set of this field
is required (for security reasons).
If set, the user will only be able to access channels containing
this channel tag.
Note that this field is unset when the channel tag is removed.

<dt>Comment
<dd>
Expand Down
140 changes: 116 additions & 24 deletions src/access.c
Expand Up @@ -37,6 +37,7 @@
#include "access.h"
#include "settings.h"
#include "channels.h"
#include "dvr/dvr.h"
#include "tcp.h"

struct access_entry_queue access_entries;
Expand Down Expand Up @@ -161,6 +162,7 @@ access_destroy(access_t *a)
{
free(a->aa_username);
free(a->aa_representative);
htsmsg_destroy(a->aa_dvrcfgs);
htsmsg_destroy(a->aa_chtags);
free(a);
}
Expand Down Expand Up @@ -295,10 +297,16 @@ access_update(access_t *a, access_entry_t *ae)
}
}

if(ae->ae_chtag && ae->ae_chtag[0] != '\0') {
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));
}

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, ae->ae_chtag);
htsmsg_add_str(a->aa_chtags, NULL, idnode_uuid_as_str(&ae->ae_chtag->ct_id));
}

a->aa_rights |= ae->ae_rights;
Expand Down Expand Up @@ -557,12 +565,8 @@ access_entry_update_rights(access_entry_t *ae)
r |= ACCESS_ADVANCED_STREAMING;
if (ae->ae_dvr)
r |= ACCESS_RECORDER;
if (ae->ae_dvrallcfg)
r |= ACCESS_RECORDER_ALL;
if (ae->ae_webui)
r |= ACCESS_WEB_INTERFACE;
if (ae->ae_tag_only)
r |= ACCESS_TAG_ONLY;
if (ae->ae_admin)
r |= ACCESS_ADMIN;
ae->ae_rights = r;
Expand Down Expand Up @@ -639,6 +643,11 @@ access_entry_destroy(access_entry_t *ae)
TAILQ_REMOVE(&access_entries, ae, ae_link);
idnode_unlink(&ae->ae_id);

if (ae->ae_dvr_config)
LIST_REMOVE(ae, ae_dvr_config_link);
if (ae->ae_chtag)
LIST_REMOVE(ae, ae_channel_tag_link);

while((ai = TAILQ_FIRST(&ae->ae_ipmasks)) != NULL)
{
TAILQ_REMOVE(&ae->ae_ipmasks, ai, ai_link);
Expand All @@ -653,6 +662,38 @@ access_entry_destroy(access_entry_t *ae)
free(ae);
}

/*
*
*/
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);
}
}

/*
*
*/
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);
}
}

/**
*
*/
Expand Down Expand Up @@ -806,14 +847,66 @@ access_entry_class_password2_set(void *o, const void *v)
return 0;
}

static htsmsg_t *
access_entry_chtag_list ( void *o )
static int
access_entry_chtag_set(void *o, const void *v)
{
channel_tag_t *ct;
htsmsg_t *m = htsmsg_create_list();
TAILQ_FOREACH(ct, &channel_tags, ct_link)
htsmsg_add_str(m, NULL, ct->ct_name);
return m;
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);
return 1;
}
return 0;
}

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;
}

static int
access_entry_dvr_config_set(void *o, const void *v)
{
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);
return 1;
}
return 0;
}

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;
}

const idclass_t access_entry_class = {
Expand Down Expand Up @@ -886,10 +979,13 @@ const idclass_t access_entry_class = {
.off = offsetof(access_entry_t, ae_dvr),
},
{
.type = PT_BOOL,
.id = "dvrallcfg",
.name = "All Configs (VR)",
.off = offsetof(access_entry_t, ae_dvrallcfg),
.type = PT_STR,
.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,
.off = offsetof(access_entry_t, ae_dvr_config),
},
{
.type = PT_BOOL,
Expand All @@ -903,12 +999,6 @@ const idclass_t access_entry_class = {
.name = "Admin",
.off = offsetof(access_entry_t, ae_admin),
},
{
.type = PT_BOOL,
.id = "tag_only",
.name = "Username Channel Tag Match",
.off = offsetof(access_entry_t, ae_tag_only),
},
{
.type = PT_U32,
.id = "channel_min",
Expand All @@ -926,7 +1016,9 @@ const idclass_t access_entry_class = {
.id = "channel_tag",
.name = "Channel Tag",
.off = offsetof(access_entry_t, ae_chtag),
.list = access_entry_chtag_list,
.set = access_entry_chtag_set,
.get = access_entry_chtag_get,
.list = channel_tag_class_get_list,
},
{
.type = PT_STR,
Expand Down
32 changes: 24 additions & 8 deletions src/access.h
Expand Up @@ -22,6 +22,9 @@
#include "idnode.h"
#include "htsmsg.h"

struct dvr_config;
struct channel_tag;

typedef struct access_ipmask {
TAILQ_ENTRY(access_ipmask) ai_link;

Expand All @@ -48,18 +51,25 @@ typedef struct access_entry {
char *ae_password;
char *ae_password2;
char *ae_comment;

int ae_index;
int ae_enabled;

int ae_streaming;
int ae_adv_streaming;

int ae_dvr;
int ae_dvrallcfg;
struct dvr_config *ae_dvr_config;
LIST_ENTRY(access_entry) ae_dvr_config_link;

int ae_webui;
int ae_admin;
int ae_tag_only;

uint32_t ae_chmin;
uint32_t ae_chmax;
char *ae_chtag;

struct channel_tag *ae_chtag;
LIST_ENTRY(access_entry) ae_channel_tag_link;

uint32_t ae_rights;

Expand All @@ -85,6 +95,7 @@ typedef struct access {
char *aa_username;
char *aa_representative;
uint32_t aa_rights;
htsmsg_t *aa_dvrcfgs;
uint32_t aa_chmin;
uint32_t aa_chmax;
htsmsg_t *aa_chtags;
Expand All @@ -96,14 +107,11 @@ typedef struct access {
#define ACCESS_ADVANCED_STREAMING (1<<1)
#define ACCESS_WEB_INTERFACE (1<<2)
#define ACCESS_RECORDER (1<<3)
#define ACCESS_RECORDER_ALL (1<<4)
#define ACCESS_TAG_ONLY (1<<5)
#define ACCESS_ADMIN (1<<6)
#define ACCESS_ADMIN (1<<4)

#define ACCESS_FULL \
(ACCESS_STREAMING | ACCESS_ADVANCED_STREAMING | \
ACCESS_WEB_INTERFACE | ACCESS_RECORDER | \
ACCESS_RECORDER_ALL | ACCESS_ADMIN)
ACCESS_WEB_INTERFACE | ACCESS_RECORDER | ACCESS_ADMIN)

/**
* Create a new ticket for the requested resource and generate a id for it
Expand Down Expand Up @@ -165,6 +173,14 @@ access_entry_create(const char *uuid, htsmsg_t *conf);
void
access_entry_save(access_entry_t *ae);

/**
*
*/
void
access_destroy_by_dvr_config(struct dvr_config *cfg, int delconf);
void
access_destroy_by_channel_tag(struct channel_tag *ct, int delconf);

/**
*
*/
Expand Down

0 comments on commit 7fdf5f1

Please sign in to comment.