dvr_config_t *cfg;
LIST_FOREACH(cfg, &dvrconfigs, config_link)
- if (!idnode_perm((idnode_t *)cfg, perm, NULL))
+ if (!idnode_perm((idnode_t *)cfg, perm, NULL)) {
idnode_set_add(ins, (idnode_t*)cfg, &conf->filter);
+ idnode_perm_unset((idnode_t *)cfg);
+ }
}
static int
htsmsg_t *list, *e;
htsmsg_t *flist = api_idnode_flist_conf(args, "list");
api_idnode_grid_conf_t conf = { 0 };
+ idnode_t *in;
idnode_set_t ins = { 0 };
api_idnode_grid_callback_t cb = opaque;
for (i = conf.start; i < ins.is_count && conf.limit != 0; i++) {
e = htsmsg_create_map();
htsmsg_add_str(e, "uuid", idnode_uuid_as_str(ins.is_array[i]));
- idnode_read0(ins.is_array[i], e, flist, 0);
+ in = ins.is_array[i];
+ idnode_perm_set(in, perm);
+ idnode_read0(in, e, flist, 0);
+ idnode_perm_unset(in);
htsmsg_add_msg(list, NULL, e);
if (conf.limit > 0) conf.limit--;
}
e = idnode_serialize0(in, flist, 0);
htsmsg_destroy(flist);
}
-
+
if (e)
htsmsg_add_msg(l, NULL, e);
+
+ idnode_perm_unset(in);
}
free(is->is_array);
free(is);
htsmsg_add_msg(m, "meta", idclass_serialize0(in->in_class, flist, 0));
htsmsg_add_msg(l, NULL, m);
count++;
+ idnode_perm_unset(in);
}
if (count)
if (meta > 0)
htsmsg_add_msg(m, "meta", idclass_serialize0(in->in_class, flist, 0));
htsmsg_add_msg(l, NULL, m);
+ idnode_perm_unset(in);
}
}
}
goto exit;
}
idnode_update(in, msg);
+ idnode_perm_unset(in);
err = 0;
/* Multiple */
}
count++;
idnode_update(in, conf);
+ idnode_perm_unset(in);
}
if (count)
err = 0;
/* Root node */
if (isroot && node) {
- htsmsg_t *m = idnode_serialize(node);
+ htsmsg_t *m;
+ idnode_perm_set(node, perm);
+ m = idnode_serialize(node);
+ idnode_perm_unset(node);
htsmsg_add_u32(m, "leaf", idnode_is_leaf(node));
htsmsg_add_msg(*resp, NULL, m);
int i;
idnode_set_sort_by_title(v);
for(i = 0; i < v->is_count; i++) {
- htsmsg_t *m = idnode_serialize(v->is_array[i]);
+ idnode_t *in = v->is_array[i];
+ htsmsg_t *m;
+ idnode_perm_set(in, perm);
+ m = idnode_serialize(v->is_array[i]);
+ idnode_perm_unset(in);
htsmsg_add_u32(m, "leaf", idnode_is_leaf(v->is_array[i]));
htsmsg_add_msg(*resp, NULL, m);
}
err = EPERM;
} else {
handler(perm, in);
+ idnode_perm_unset(in);
}
htsmsg_destroy(msg);
}
return strtab2htsmsg(tab);
}
+static uint32_t
+dvr_autorec_entry_class_owner_opts(void *o)
+{
+ dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o;
+ if (dae && dae->dae_id.in_access &&
+ !access_verify2(dae->dae_id.in_access, ACCESS_ADMIN))
+ return 0;
+ return PO_RDONLY;
+}
+
const idclass_t dvr_autorec_entry_class = {
.ic_class = "dvrautorec",
.ic_caption = "DVR Auto-Record Entry",
.id = "owner",
.name = "Owner",
.off = offsetof(dvr_autorec_entry_t, dae_owner),
- .opts = PO_RDONLY,
+ .get_opts = dvr_autorec_entry_class_owner_opts,
},
{
.type = PT_STR,
.id = "creator",
.name = "Creator",
.off = offsetof(dvr_autorec_entry_t, dae_creator),
- .opts = PO_RDONLY,
+ .get_opts = dvr_autorec_entry_class_owner_opts,
},
{
.type = PT_STR,
return 0;
}
+static uint32_t
+dvr_entry_class_owner_opts(void *o)
+{
+ dvr_entry_t *de = (dvr_entry_t *)o;
+ if (de && de->de_id.in_access &&
+ !access_verify2(de->de_id.in_access, ACCESS_ADMIN))
+ return 0;
+ return PO_RDONLY;
+}
+
static uint32_t
dvr_entry_class_start_extra_opts(void *o)
{
.set = dvr_entry_class_start_extra_set,
.list = dvr_entry_class_extra_list,
.get_opts = dvr_entry_class_start_extra_opts,
- .opts = PO_DURATION | PO_SORTKEY,
+ .opts = PO_SORTKEY,
},
{
.type = PT_TIME,
.name = "Extra Stop Time",
.off = offsetof(dvr_entry_t, de_stop_extra),
.list = dvr_entry_class_extra_list,
- .opts = PO_DURATION | PO_SORTKEY,
+ .opts = PO_SORTKEY,
},
{
.type = PT_TIME,
.id = "owner",
.name = "Owner",
.off = offsetof(dvr_entry_t, de_owner),
- .opts = PO_RDONLY,
+ .get_opts = dvr_entry_class_owner_opts,
},
{
.type = PT_STR,
.id = "creator",
.name = "Creator",
.off = offsetof(dvr_entry_t, de_creator),
- .opts = PO_RDONLY,
+ .get_opts = dvr_entry_class_owner_opts,
},
{
.type = PT_STR,
return dvr_autorec_entry_class_weekdays_rend(dte->dte_weekdays);
}
+static uint32_t
+dvr_timerec_entry_class_owner_opts(void *o)
+{
+ dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o;
+ if (dte && dte->dte_id.in_access &&
+ !access_verify2(dte->dte_id.in_access, ACCESS_ADMIN))
+ return 0;
+ return PO_RDONLY;
+}
+
const idclass_t dvr_timerec_entry_class = {
.ic_class = "dvrtimerec",
.ic_caption = "DVR Time-Record Entry",
.id = "owner",
.name = "Owner",
.off = offsetof(dvr_timerec_entry_t, dte_creator),
- .opts = PO_RDONLY,
+ .get_opts = dvr_timerec_entry_class_owner_opts,
},
{
.type = PT_STR,
.id = "creator",
.name = "Creator",
.off = offsetof(dvr_timerec_entry_t, dte_creator),
- .opts = PO_RDONLY,
+ .get_opts = dvr_timerec_entry_class_owner_opts,
},
{
.type = PT_STR,
idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write)
{
const idclass_t *ic = self->in_class;
+ int r;
while (ic) {
if (ic->ic_perm)
- return self->in_class->ic_perm(self, a, msg_to_write);
- if (ic->ic_perm_def)
- return access_verify2(a, self->in_class->ic_perm_def);
- ic = ic->ic_super;
+ r = self->in_class->ic_perm(self, a, msg_to_write);
+ else if (ic->ic_perm_def)
+ r = access_verify2(a, self->in_class->ic_perm_def);
+ else {
+ ic = ic->ic_super;
+ continue;
+ }
+ if (!r) {
+ self->in_access = a;
+ return 0;
+ }
+ return r;
}
return 0;
}
RB_ENTRY(idnode) in_domain_link; ///< Root class link (domain)
idnodes_rb_t *in_domain; ///< Domain nodes
const idclass_t *in_class; ///< Class definition
+ struct access *in_access; ///< Actual permissions
+
};
/*
#define idnode_update(in, m) idnode_write0(in, m, PO_RDONLY | PO_WRONCE, 1)
int idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write);
+static inline void idnode_perm_set(idnode_t *self, struct access *a) { self->in_access = a; }
+static inline void idnode_perm_unset(idnode_t *self) { self->in_access = NULL; }
const char *idnode_get_str (idnode_t *self, const char *key );
int idnode_get_u32 (idnode_t *self, const char *key, uint32_t *u32);
var actions = tvheadend.dvrRowActions();
var list = 'disp_title,start,start_extra,stop,stop_extra,' +
'channel,config_name,comment';
+ var elist = tvheadend.accessUpdate.admin ? list + ',owner,creator' : list;
var abortButton = {
name: 'abort',
},
edit: {
params: {
- list: list
+ list: elist
}
},
del: true,