#define ACCESS_FAILED_RECORDER (1<<9)
#define ACCESS_HTSP_ANONYMIZE (1<<10)
#define ACCESS_ADMIN (1<<11)
+#define ACCESS_NO_EMPTY_ARGS (1<<29)
#define ACCESS_OR (1<<30)
#define ACCESS_FULL \
ACCESS_ALL_RECORDER | ACCESS_ALL_RW_RECORDER | \
ACCESS_FAILED_RECORDER | ACCESS_ADMIN)
+#define ACCESS_INTERNAL \
+ (ACCESS_NO_EMPTY_ARGS)
+
/**
* Create a new ticket for the requested resource and generate a id for it
*/
api_hook_t h;
api_link_t *ah, skel;
const char *op;
+ uint32_t access;
/* Args and response must be set */
if (!args || !resp || !subsystem)
return ENOSYS; // TODO: is this really the right error code?
}
- if (access_verify2(perm, ah->hook->ah_access))
+ access = ah->hook->ah_access;
+ if ((access & ACCESS_NO_EMPTY_ARGS) != 0 && htsmsg_is_empty(args))
+ return EPERM;
+
+ if (access_verify2(perm, access & ~ACCESS_INTERNAL))
return EPERM;
/* Extract method */
htsmsg_add_msg(*resp, "uuid", list);
}
+#define ACCESS_IDNODE (ACCESS_ANONYMOUS | ACCESS_NO_EMPTY_ARGS)
+
void api_idnode_init ( void )
{
/*
* note: permissions are verified using idnode_perm() calls
*/
static api_hook_t ah[] = {
- { "idnode/load", ACCESS_ANONYMOUS, api_idnode_load, NULL },
- { "idnode/save", ACCESS_ANONYMOUS, api_idnode_save, NULL },
- { "idnode/tree", ACCESS_ANONYMOUS, api_idnode_tree, NULL },
- { "idnode/class", ACCESS_ANONYMOUS, api_idnode_class, NULL },
- { "idnode/delete", ACCESS_ANONYMOUS, api_idnode_delete, NULL },
- { "idnode/moveup", ACCESS_ANONYMOUS, api_idnode_moveup, NULL },
- { "idnode/movedown", ACCESS_ANONYMOUS, api_idnode_movedown, NULL },
+ { "idnode/load", ACCESS_IDNODE, api_idnode_load, NULL },
+ { "idnode/save", ACCESS_IDNODE, api_idnode_save, NULL },
+ { "idnode/tree", ACCESS_IDNODE, api_idnode_tree, NULL },
+ { "idnode/class", ACCESS_IDNODE, api_idnode_class, NULL },
+ { "idnode/delete", ACCESS_IDNODE, api_idnode_delete, NULL },
+ { "idnode/moveup", ACCESS_IDNODE, api_idnode_moveup, NULL },
+ { "idnode/movedown", ACCESS_IDNODE, api_idnode_movedown, NULL },
{ NULL },
};
{
int err;
- if (http_access_verify(hc, hp->hp_accessmask)) {
+ /* this is a special case when client probably requires authentication */
+ if ((hp->hp_accessmask & ACCESS_NO_EMPTY_ARGS) != 0 && TAILQ_EMPTY(&hc->hc_req_args)) {
+ err = http_noaccess_code(hc);
+ goto destroy;
+ }
+ if (http_access_verify(hc, hp->hp_accessmask & ~ACCESS_INTERNAL)) {
if ((hp->hp_flags & HTTP_PATH_NO_VERIFICATION) == 0) {
err = http_noaccess_code(hc);
goto destroy;