mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Feature: Allow mangement of <role>s via admin/ interface.
This allows to manage <role>s via admin interface if the role supports. Also format of admin/manageauth has been changed: - <source> was renamed to <role>. - mount parameter was removed. - <role> got new parameters: type, name, can-adduser, can-deleteuser, can-listuser. - can-* parameters are bools ("true" or "false"). They should be used to show or hide elements on the admin interface. Ticket #2123 is nearly complet with this, just admin/manageauth.xsl needs up be updated. Please close the bug in the commit that updates admin/manageauth.xsl. See #2123
This commit is contained in:
parent
a990756912
commit
0eb466b76d
127
src/admin.c
127
src/admin.c
@ -152,8 +152,8 @@ static const admin_command_t commands[] = {
|
|||||||
{COMMAND_TRANSFORMED_KILL_CLIENT, KILLCLIENT_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
{COMMAND_TRANSFORMED_KILL_CLIENT, KILLCLIENT_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
||||||
{COMMAND_RAW_KILL_SOURCE, KILLSOURCE_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
{COMMAND_RAW_KILL_SOURCE, KILLSOURCE_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
||||||
{COMMAND_TRANSFORMED_KILL_SOURCE, KILLSOURCE_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
{COMMAND_TRANSFORMED_KILL_SOURCE, KILLSOURCE_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
||||||
{COMMAND_RAW_MANAGEAUTH, MANAGEAUTH_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
{COMMAND_RAW_MANAGEAUTH, MANAGEAUTH_RAW_REQUEST, ADMINTYPE_GENERAL, RAW},
|
||||||
{COMMAND_TRANSFORMED_MANAGEAUTH, MANAGEAUTH_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
{COMMAND_TRANSFORMED_MANAGEAUTH, MANAGEAUTH_TRANSFORMED_REQUEST, ADMINTYPE_GENERAL, TRANSFORMED},
|
||||||
{COMMAND_RAW_UPDATEMETADATA, UPDATEMETADATA_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
{COMMAND_RAW_UPDATEMETADATA, UPDATEMETADATA_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
||||||
{COMMAND_TRANSFORMED_UPDATEMETADATA, UPDATEMETADATA_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
{COMMAND_TRANSFORMED_UPDATEMETADATA, UPDATEMETADATA_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
|
||||||
{COMMAND_BUILDM3U, BUILDM3U_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
{COMMAND_BUILDM3U, BUILDM3U_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
|
||||||
@ -197,8 +197,7 @@ static void command_queue_reload(client_t *client, int response);
|
|||||||
static void command_list_mounts(client_t *client, int response);
|
static void command_list_mounts(client_t *client, int response);
|
||||||
static void command_kill_client(client_t *client, source_t *source,
|
static void command_kill_client(client_t *client, source_t *source,
|
||||||
int response);
|
int response);
|
||||||
static void command_manageauth(client_t *client, source_t *source,
|
static void command_manageauth(client_t *client, int response);
|
||||||
int response);
|
|
||||||
static void command_buildm3u(client_t *client, const char *mount);
|
static void command_buildm3u(client_t *client, const char *mount);
|
||||||
static void command_kill_source(client_t *client, source_t *source,
|
static void command_kill_source(client_t *client, source_t *source,
|
||||||
int response);
|
int response);
|
||||||
@ -486,6 +485,12 @@ static void admin_handle_general_request(client_t *client)
|
|||||||
case COMMAND_TRANSFORMED_MOVE_CLIENTS:
|
case COMMAND_TRANSFORMED_MOVE_CLIENTS:
|
||||||
command_list_mounts(client, TRANSFORMED);
|
command_list_mounts(client, TRANSFORMED);
|
||||||
break;
|
break;
|
||||||
|
case COMMAND_TRANSFORMED_MANAGEAUTH:
|
||||||
|
command_manageauth(client, TRANSFORMED);
|
||||||
|
break;
|
||||||
|
case COMMAND_RAW_MANAGEAUTH:
|
||||||
|
command_manageauth(client, RAW);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ICECAST_LOG_WARN("General admin request not recognised");
|
ICECAST_LOG_WARN("General admin request not recognised");
|
||||||
client_send_error(client, 400, 0, "Unknown admin request");
|
client_send_error(client, 400, 0, "Unknown admin request");
|
||||||
@ -540,12 +545,6 @@ static void admin_handle_mount_request(client_t *client, source_t *source) {
|
|||||||
case COMMAND_TRANSFORMED_KILL_SOURCE:
|
case COMMAND_TRANSFORMED_KILL_SOURCE:
|
||||||
command_kill_source(client, source, TRANSFORMED);
|
command_kill_source(client, source, TRANSFORMED);
|
||||||
break;
|
break;
|
||||||
case COMMAND_TRANSFORMED_MANAGEAUTH:
|
|
||||||
command_manageauth(client, source, TRANSFORMED);
|
|
||||||
break;
|
|
||||||
case COMMAND_RAW_MANAGEAUTH:
|
|
||||||
command_manageauth(client, source, RAW);
|
|
||||||
break;
|
|
||||||
case COMMAND_TRANSFORMED_UPDATEMETADATA:
|
case COMMAND_TRANSFORMED_UPDATEMETADATA:
|
||||||
command_updatemetadata(client, source, TRANSFORMED);
|
command_updatemetadata(client, source, TRANSFORMED);
|
||||||
break;
|
break;
|
||||||
@ -777,35 +776,51 @@ static void command_buildm3u(client_t *client, const char *mount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void command_manageauth(client_t *client, source_t *source,
|
static void command_manageauth(client_t *client, int response) {
|
||||||
int response)
|
|
||||||
{
|
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr node, srcnode, msgnode;
|
xmlNodePtr node, rolenode, usersnode, msgnode;
|
||||||
const char *action = NULL;
|
const char *action = NULL;
|
||||||
const char *username = NULL;
|
const char *username = NULL;
|
||||||
|
const char *idstring = NULL;
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
int ret = AUTH_OK;
|
int ret = AUTH_OK;
|
||||||
ice_config_t *config = config_get_config ();
|
int error_code = 400;
|
||||||
mount_proxy *mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL);
|
const char *error_message = "missing parameter";
|
||||||
|
long unsigned int id;
|
||||||
|
ice_config_t *config = config_get_config();
|
||||||
auth_t *auth;
|
auth_t *auth;
|
||||||
|
char idbuf[32];
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
#if 0
|
/* get id */
|
||||||
if (mountinfo == NULL || mountinfo->auth == NULL)
|
COMMAND_REQUIRE(client, "id", idstring);
|
||||||
{
|
id = atol(idstring);
|
||||||
ICECAST_LOG_WARN("manage auth request for %s but no facility available", source->mount);
|
|
||||||
|
/* no find a auth_t for that id by looking up the config */
|
||||||
|
/* globals first */
|
||||||
|
auth = auth_stack_getbyid(config->authstack, id);
|
||||||
|
/* now mounts */
|
||||||
|
if (!auth) {
|
||||||
|
mount_proxy *mount = config->mounts;
|
||||||
|
while (mount) {
|
||||||
|
auth = auth_stack_getbyid(mount->authstack, id);
|
||||||
|
if (auth)
|
||||||
|
break;
|
||||||
|
mount = mount->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if we found one */
|
||||||
|
if (auth == NULL) {
|
||||||
|
ICECAST_LOG_WARN("Client requested mangement for unknown role %lu", id);
|
||||||
|
error_code = 404;
|
||||||
|
error_message = "Role not found";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auth = mountinfo->auth;
|
|
||||||
#else
|
|
||||||
ICECAST_LOG_WARN("manage auth request for %s but no facility available", source->mount);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
COMMAND_OPTIONAL(client, "action", action);
|
COMMAND_OPTIONAL(client, "action", action);
|
||||||
COMMAND_OPTIONAL (client, "username", username);
|
COMMAND_OPTIONAL(client, "username", username);
|
||||||
|
|
||||||
if (action == NULL)
|
if (action == NULL)
|
||||||
action = "list";
|
action = "list";
|
||||||
@ -815,42 +830,60 @@ static void command_manageauth(client_t *client, source_t *source,
|
|||||||
const char *password = NULL;
|
const char *password = NULL;
|
||||||
COMMAND_OPTIONAL(client, "password", password);
|
COMMAND_OPTIONAL(client, "password", password);
|
||||||
|
|
||||||
if (username == NULL || password == NULL)
|
if (username == NULL || password == NULL) {
|
||||||
{
|
ICECAST_LOG_WARN("manage auth request add for %lu but no user/pass", id);
|
||||||
ICECAST_LOG_WARN("manage auth request add for %s but no user/pass", source->mount);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!auth->adduser) {
|
||||||
|
error_message = "Adding users to role not supported by role";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ret = auth->adduser(auth, username, password);
|
ret = auth->adduser(auth, username, password);
|
||||||
if (ret == AUTH_FAILED) {
|
if (ret == AUTH_FAILED) {
|
||||||
message = strdup("User add failed - check the icecast error log");
|
message = strdup("User add failed - check the icecast error log");
|
||||||
}
|
} else if (ret == AUTH_USERADDED) {
|
||||||
if (ret == AUTH_USERADDED) {
|
|
||||||
message = strdup("User added");
|
message = strdup("User added");
|
||||||
}
|
} else if (ret == AUTH_USEREXISTS) {
|
||||||
if (ret == AUTH_USEREXISTS) {
|
|
||||||
message = strdup("User already exists - not added");
|
message = strdup("User already exists - not added");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!strcmp(action, "delete"))
|
if (!strcmp(action, "delete"))
|
||||||
{
|
{
|
||||||
if (username == NULL)
|
if (username == NULL) {
|
||||||
{
|
ICECAST_LOG_WARN("manage auth request delete for %lu but no username", id);
|
||||||
ICECAST_LOG_WARN("manage auth request delete for %s but no username", source->mount);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!auth->deleteuser) {
|
||||||
|
error_message = "Deleting users from role not supported by role";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ret = auth->deleteuser(auth, username);
|
ret = auth->deleteuser(auth, username);
|
||||||
if (ret == AUTH_FAILED) {
|
if (ret == AUTH_FAILED) {
|
||||||
message = strdup("User delete failed - check the icecast error log");
|
message = strdup("User delete failed - check the icecast error log");
|
||||||
}
|
} else if (ret == AUTH_USERDELETED) {
|
||||||
if (ret == AUTH_USERDELETED) {
|
|
||||||
message = strdup("User deleted");
|
message = strdup("User deleted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doc = xmlNewDoc(XMLSTR("1.0"));
|
doc = xmlNewDoc(XMLSTR("1.0"));
|
||||||
node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
|
node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
|
||||||
srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
|
rolenode = xmlNewChild(node, NULL, XMLSTR("role"), NULL);
|
||||||
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
|
|
||||||
|
snprintf(idbuf, sizeof(idbuf), "%lu", auth->id);
|
||||||
|
xmlSetProp(rolenode, XMLSTR("id"), XMLSTR(idbuf));
|
||||||
|
|
||||||
|
if (auth->type)
|
||||||
|
xmlSetProp(rolenode, XMLSTR("type"), XMLSTR(auth->type));
|
||||||
|
if (auth->role)
|
||||||
|
xmlSetProp(rolenode, XMLSTR("name"), XMLSTR(auth->role));
|
||||||
|
|
||||||
|
xmlSetProp(rolenode, XMLSTR("can-adduser"), XMLSTR(auth->adduser ? "true" : "false"));
|
||||||
|
xmlSetProp(rolenode, XMLSTR("can-deleteuser"), XMLSTR(auth->deleteuser ? "true" : "false"));
|
||||||
|
xmlSetProp(rolenode, XMLSTR("can-listuser"), XMLSTR(auth->listuser ? "true" : "false"));
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
msgnode = xmlNewChild(node, NULL, XMLSTR("iceresponse"), NULL);
|
msgnode = xmlNewChild(node, NULL, XMLSTR("iceresponse"), NULL);
|
||||||
@ -859,10 +892,13 @@ static void command_manageauth(client_t *client, source_t *source,
|
|||||||
|
|
||||||
xmlDocSetRootElement(doc, node);
|
xmlDocSetRootElement(doc, node);
|
||||||
|
|
||||||
if (auth && auth->listuser)
|
if (auth && auth->listuser) {
|
||||||
auth->listuser(auth, srcnode);
|
usersnode = xmlNewChild(rolenode, NULL, XMLSTR("users"), NULL);
|
||||||
|
auth->listuser(auth, usersnode);
|
||||||
|
}
|
||||||
|
|
||||||
config_release_config ();
|
config_release_config();
|
||||||
|
auth_release(auth);
|
||||||
|
|
||||||
admin_send_response(doc, client, response,
|
admin_send_response(doc, client, response,
|
||||||
MANAGEAUTH_TRANSFORMED_REQUEST);
|
MANAGEAUTH_TRANSFORMED_REQUEST);
|
||||||
@ -871,8 +907,9 @@ static void command_manageauth(client_t *client, source_t *source,
|
|||||||
return;
|
return;
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
config_release_config ();
|
config_release_config();
|
||||||
client_send_error(client, 400, 0, "missing parameter");
|
auth_release(auth);
|
||||||
|
client_send_error(client, error_code, 0, error_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void command_kill_source(client_t *client, source_t *source,
|
static void command_kill_source(client_t *client, source_t *source,
|
||||||
|
25
src/auth.c
25
src/auth.c
@ -691,6 +691,31 @@ auth_t *auth_stack_get(auth_stack_t *stack) {
|
|||||||
return auth;
|
return auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth_t *auth_stack_getbyid(auth_stack_t *stack, unsigned long id) {
|
||||||
|
auth_t *ret = NULL;
|
||||||
|
|
||||||
|
if (!stack)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
auth_stack_addref(stack);
|
||||||
|
|
||||||
|
while (!ret && stack) {
|
||||||
|
auth_t *auth = auth_stack_get(stack);
|
||||||
|
if (auth->id == id) {
|
||||||
|
ret = auth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auth_release(auth);
|
||||||
|
auth_stack_next(&stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack)
|
||||||
|
auth_stack_release(stack);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack) {
|
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack) {
|
||||||
acl_t *ret = NULL;
|
acl_t *ret = NULL;
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ int auth_stack_next(auth_stack_t **stack); /* returns -1 on error, 0 o
|
|||||||
int auth_stack_push(auth_stack_t **stack, auth_t *auth);
|
int auth_stack_push(auth_stack_t **stack, auth_t *auth);
|
||||||
int auth_stack_append(auth_stack_t *stack, auth_stack_t *tail);
|
int auth_stack_append(auth_stack_t *stack, auth_stack_t *tail);
|
||||||
auth_t *auth_stack_get(auth_stack_t *stack);
|
auth_t *auth_stack_get(auth_stack_t *stack);
|
||||||
|
auth_t *auth_stack_getbyid(auth_stack_t *stack, unsigned long id);
|
||||||
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack);
|
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -398,7 +398,7 @@ static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode)
|
|||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
htpasswd_user *user = (htpasswd_user *)node->key;
|
htpasswd_user *user = (htpasswd_user *)node->key;
|
||||||
newnode = xmlNewChild (srcnode, NULL, XMLSTR("User"), NULL);
|
newnode = xmlNewChild (srcnode, NULL, XMLSTR("user"), NULL);
|
||||||
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name));
|
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name));
|
||||||
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(user->pass));
|
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(user->pass));
|
||||||
node = avl_get_next (node);
|
node = avl_get_next (node);
|
||||||
|
@ -61,7 +61,7 @@ static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode) {
|
|||||||
auth_static_t *auth_info = auth->state;
|
auth_static_t *auth_info = auth->state;
|
||||||
xmlNodePtr newnode;
|
xmlNodePtr newnode;
|
||||||
|
|
||||||
newnode = xmlNewChild(srcnode, NULL, XMLSTR("User"), NULL);
|
newnode = xmlNewChild(srcnode, NULL, XMLSTR("user"), NULL);
|
||||||
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(auth_info->username));
|
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(auth_info->username));
|
||||||
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(auth_info->password));
|
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(auth_info->password));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user