mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-08 09:14:10 +01:00
Merge branch 'update_user' into 'master'
Update user See merge request kasm-technologies/internal/KasmVNC!19
This commit is contained in:
commit
8422168154
@ -5,6 +5,7 @@ set(NETWORK_SOURCES
|
||||
Blacklist.cxx
|
||||
Socket.cxx
|
||||
TcpSocket.cxx
|
||||
jsonescape.c
|
||||
websocket.c
|
||||
websockify.c
|
||||
${CMAKE_SOURCE_DIR}/unix/kasmvncpasswd/kasmpasswd.c)
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <kasmpasswd.h>
|
||||
#include <pthread.h>
|
||||
#include <network/GetAPIEnums.h>
|
||||
#include <rfb/PixelBuffer.h>
|
||||
#include <rfb/PixelFormat.h>
|
||||
#include <stdint.h>
|
||||
@ -54,15 +55,15 @@ namespace network {
|
||||
uint32_t &len, uint8_t *staging);
|
||||
uint8_t netAddUser(const char name[], const char pw[], const bool write);
|
||||
uint8_t netRemoveUser(const char name[]);
|
||||
uint8_t netUpdateUser(const char name[], const uint64_t mask, const bool write,
|
||||
const bool owner);
|
||||
uint8_t netGiveControlTo(const char name[]);
|
||||
void netGetUsers(const char **ptr);
|
||||
void netGetBottleneckStats(char *buf, uint32_t len);
|
||||
void netGetFrameStats(char *buf, uint32_t len);
|
||||
uint8_t netServerFrameStatsReady();
|
||||
|
||||
enum USER_ACTION {
|
||||
//USER_ADD, - handled locally for interactivity
|
||||
USER_REMOVE,
|
||||
USER_GIVE_CONTROL,
|
||||
WANT_FRAME_STATS_SERVERONLY,
|
||||
WANT_FRAME_STATS_ALL,
|
||||
WANT_FRAME_STATS_OWNER,
|
||||
|
28
common/network/GetAPIEnums.h
Normal file
28
common/network/GetAPIEnums.h
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2021 Kasm
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORK_GET_API_ENUMS_H__
|
||||
#define __NETWORK_GET_API_ENUMS_H__
|
||||
|
||||
// Enums that need accessibility from both C and C++.
|
||||
enum USER_UPDATE_MASK {
|
||||
USER_UPDATE_WRITE_MASK = 1 << 0,
|
||||
USER_UPDATE_OWNER_MASK = 1 << 1,
|
||||
};
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <network/GetAPI.h>
|
||||
#include <network/jsonescape.h>
|
||||
#include <rfb/ConnParams.h>
|
||||
#include <rfb/EncodeManager.h>
|
||||
#include <rfb/LogWriter.h>
|
||||
@ -282,8 +283,6 @@ uint8_t GetAPIMessager::netAddUser(const char name[], const char pw[], const boo
|
||||
|
||||
action_data act;
|
||||
|
||||
memcpy(act.data.user, name, USERNAME_LEN);
|
||||
act.data.user[USERNAME_LEN - 1] = '\0';
|
||||
memcpy(act.data.password, pw, PASSWORD_LEN);
|
||||
act.data.password[PASSWORD_LEN - 1] = '\0';
|
||||
act.data.owner = 0;
|
||||
@ -299,8 +298,8 @@ uint8_t GetAPIMessager::netAddUser(const char name[], const char pw[], const boo
|
||||
struct kasmpasswd_t *set = readkasmpasswd(passwdfile);
|
||||
unsigned s;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, act.data.user)) {
|
||||
vlog.error("Can't create user %s, already exists", act.data.user);
|
||||
if (!strcmp(set->entries[s].user, name)) {
|
||||
vlog.error("Can't create user %s, already exists", name);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -311,10 +310,13 @@ uint8_t GetAPIMessager::netAddUser(const char name[], const char pw[], const boo
|
||||
set->entries[s] = act.data;
|
||||
|
||||
writekasmpasswd(passwdfile, set);
|
||||
vlog.info("User %s created", act.data.user);
|
||||
vlog.info("User %s created", name);
|
||||
out:
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -324,19 +326,90 @@ uint8_t GetAPIMessager::netRemoveUser(const char name[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
action_data act;
|
||||
act.action = USER_REMOVE;
|
||||
if (pthread_mutex_lock(&userMutex))
|
||||
return 0;
|
||||
|
||||
memcpy(act.data.user, name, USERNAME_LEN);
|
||||
act.data.user[USERNAME_LEN - 1] = '\0';
|
||||
struct kasmpasswd_t *set = readkasmpasswd(passwdfile);
|
||||
bool found = false;
|
||||
unsigned s;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, name)) {
|
||||
set->entries[s].user[0] = '\0';
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
writekasmpasswd(passwdfile, set);
|
||||
vlog.info("User %s removed", name);
|
||||
} else {
|
||||
vlog.error("Tried to remove nonexistent user %s", name);
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t GetAPIMessager::netUpdateUser(const char name[], const uint64_t mask,
|
||||
const bool write, const bool owner) {
|
||||
if (strlen(name) >= USERNAME_LEN) {
|
||||
vlog.error("Username too long");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mask) {
|
||||
vlog.error("Update_user without any updates?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pthread_mutex_lock(&userMutex))
|
||||
return 0;
|
||||
|
||||
actionQueue.push_back(act);
|
||||
struct kasmpasswd_t *set = readkasmpasswd(passwdfile);
|
||||
bool found = false;
|
||||
unsigned s;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, name)) {
|
||||
if (mask & USER_UPDATE_WRITE_MASK)
|
||||
set->entries[s].write = write;
|
||||
if (mask & USER_UPDATE_OWNER_MASK)
|
||||
set->entries[s].owner = owner;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
writekasmpasswd(passwdfile, set);
|
||||
vlog.info("User %s permissions updated", name);
|
||||
} else {
|
||||
vlog.error("Tried to update nonexistent user %s", name);
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -346,22 +419,91 @@ uint8_t GetAPIMessager::netGiveControlTo(const char name[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
action_data act;
|
||||
act.action = USER_GIVE_CONTROL;
|
||||
|
||||
memcpy(act.data.user, name, USERNAME_LEN);
|
||||
act.data.user[USERNAME_LEN - 1] = '\0';
|
||||
|
||||
if (pthread_mutex_lock(&userMutex))
|
||||
return 0;
|
||||
|
||||
actionQueue.push_back(act);
|
||||
struct kasmpasswd_t *set = readkasmpasswd(passwdfile);
|
||||
bool found = false;
|
||||
unsigned s;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, name)) {
|
||||
set->entries[s].write = 1;
|
||||
found = true;
|
||||
} else {
|
||||
set->entries[s].write = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
writekasmpasswd(passwdfile, set);
|
||||
vlog.info("User %s given control", name);
|
||||
} else {
|
||||
vlog.error("Tried to give control to nonexistent user %s", name);
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GetAPIMessager::netGetUsers(const char **outptr) {
|
||||
/*
|
||||
[
|
||||
{ "user": "username", "write": true, "owner": true },
|
||||
{ "user": "username", "write": true, "owner": true }
|
||||
]
|
||||
*/
|
||||
char *buf;
|
||||
char escapeduser[USERNAME_LEN * 2];
|
||||
|
||||
if (pthread_mutex_lock(&userMutex)) {
|
||||
*outptr = (char *) calloc(1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
struct kasmpasswd_t *set = readkasmpasswd(passwdfile);
|
||||
|
||||
buf = (char *) calloc(set->num, 80);
|
||||
FILE *f = fmemopen(buf, set->num * 80, "w");
|
||||
|
||||
fprintf(f, "[\n");
|
||||
|
||||
unsigned s;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
JSON_escape(set->entries[s].user, escapeduser);
|
||||
|
||||
fprintf(f, " { \"user\": \"%s\", \"write\": %s, \"owner\": %s }",
|
||||
escapeduser,
|
||||
set->entries[s].write ? "true" : "false",
|
||||
set->entries[s].owner ? "true" : "false");
|
||||
|
||||
if (s == set->num - 1)
|
||||
fprintf(f, "\n");
|
||||
else
|
||||
fprintf(f, ",\n");
|
||||
}
|
||||
|
||||
free(set->entries);
|
||||
free(set);
|
||||
|
||||
fprintf(f, "]\n");
|
||||
|
||||
fclose(f);
|
||||
|
||||
pthread_mutex_unlock(&userMutex);
|
||||
*outptr = buf;
|
||||
}
|
||||
|
||||
void GetAPIMessager::netGetBottleneckStats(char *buf, uint32_t len) {
|
||||
/*
|
||||
{
|
||||
|
@ -455,12 +455,25 @@ static uint8_t removeCb(void *messager, const char name[])
|
||||
return msgr->netRemoveUser(name);
|
||||
}
|
||||
|
||||
static uint8_t updateUserCb(void *messager, const char name[], const uint64_t mask,
|
||||
const uint8_t write, const uint8_t owner)
|
||||
{
|
||||
GetAPIMessager *msgr = (GetAPIMessager *) messager;
|
||||
return msgr->netUpdateUser(name, mask, write, owner);
|
||||
}
|
||||
|
||||
static uint8_t givecontrolCb(void *messager, const char name[])
|
||||
{
|
||||
GetAPIMessager *msgr = (GetAPIMessager *) messager;
|
||||
return msgr->netGiveControlTo(name);
|
||||
}
|
||||
|
||||
static void getUsersCb(void *messager, const char **ptr)
|
||||
{
|
||||
GetAPIMessager *msgr = (GetAPIMessager *) messager;
|
||||
msgr->netGetUsers(ptr);
|
||||
}
|
||||
|
||||
static void bottleneckStatsCb(void *messager, char *buf, uint32_t len)
|
||||
{
|
||||
GetAPIMessager *msgr = (GetAPIMessager *) messager;
|
||||
@ -613,7 +626,9 @@ WebsocketListener::WebsocketListener(const struct sockaddr *listenaddr,
|
||||
settings.screenshotCb = screenshotCb;
|
||||
settings.adduserCb = adduserCb;
|
||||
settings.removeCb = removeCb;
|
||||
settings.updateUserCb = updateUserCb;
|
||||
settings.givecontrolCb = givecontrolCb;
|
||||
settings.getUsersCb = getUsersCb;
|
||||
settings.bottleneckStatsCb = bottleneckStatsCb;
|
||||
settings.frameStatsCb = frameStatsCb;
|
||||
|
||||
|
81
common/network/jsonescape.c
Normal file
81
common/network/jsonescape.c
Normal file
@ -0,0 +1,81 @@
|
||||
/* Copyright (C) 2022 Kasm
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include "jsonescape.h"
|
||||
|
||||
void JSON_escape(const char *in, char *out) {
|
||||
for (; *in; in++) {
|
||||
if (in[0] == '\b') {
|
||||
*out++ = '\\';
|
||||
*out++ = 'b';
|
||||
} else if (in[0] == '\f') {
|
||||
*out++ = '\\';
|
||||
*out++ = 'f';
|
||||
} else if (in[0] == '\n') {
|
||||
*out++ = '\\';
|
||||
*out++ = 'n';
|
||||
} else if (in[0] == '\r') {
|
||||
*out++ = '\\';
|
||||
*out++ = 'r';
|
||||
} else if (in[0] == '\t') {
|
||||
*out++ = '\\';
|
||||
*out++ = 't';
|
||||
} else if (in[0] == '"') {
|
||||
*out++ = '\\';
|
||||
*out++ = '"';
|
||||
} else if (in[0] == '\\') {
|
||||
*out++ = '\\';
|
||||
*out++ = '\\';
|
||||
} else {
|
||||
*out++ = *in;
|
||||
}
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
void JSON_unescape(const char *in, char *out) {
|
||||
for (; *in; in++) {
|
||||
if (in[0] == '\\' && in[1] == 'b') {
|
||||
*out++ = '\b';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == 'f') {
|
||||
*out++ = '\f';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == 'n') {
|
||||
*out++ = '\n';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == 'r') {
|
||||
*out++ = '\r';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == 't') {
|
||||
*out++ = '\t';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == '"') {
|
||||
*out++ = '"';
|
||||
in++;
|
||||
} else if (in[0] == '\\' && in[1] == '\\') {
|
||||
*out++ = '\\';
|
||||
in++;
|
||||
} else {
|
||||
*out++ = *in;
|
||||
}
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
}
|
33
common/network/jsonescape.h
Normal file
33
common/network/jsonescape.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* Copyright (C) 2022 Kasm
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORK_JSON_ESCAPE_H__
|
||||
#define __NETWORK_JSON_ESCAPE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void JSON_escape(const char *in, char *out);
|
||||
void JSON_unescape(const char *in, char *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1074,7 +1074,51 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
||||
"200 OK");
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
|
||||
wserr("Passed remove_user request to main thread\n");
|
||||
ret = 1;
|
||||
} else entry("/api/update_user") {
|
||||
char decname[1024] = "";
|
||||
|
||||
param = parse_get(args, "name", &len);
|
||||
if (len) {
|
||||
memcpy(buf, param, len);
|
||||
buf[len] = '\0';
|
||||
percent_decode(buf, decname, 0);
|
||||
}
|
||||
|
||||
if (!decname[0])
|
||||
goto nope;
|
||||
|
||||
uint64_t mask = 0;
|
||||
uint8_t mywrite = 0;
|
||||
param = parse_get(args, "write", &len);
|
||||
if (len && isalpha(param[0])) {
|
||||
mask |= USER_UPDATE_WRITE_MASK;
|
||||
if (!strncmp(param, "true", len))
|
||||
mywrite = 1;
|
||||
}
|
||||
|
||||
uint8_t myowner = 0;
|
||||
param = parse_get(args, "owner", &len);
|
||||
if (len && isalpha(param[0])) {
|
||||
mask |= USER_UPDATE_OWNER_MASK;
|
||||
if (!strncmp(param, "true", len))
|
||||
myowner = 1;
|
||||
}
|
||||
|
||||
if (!settings.updateUserCb(settings.messager, decname, mask, mywrite, myowner)) {
|
||||
wserr("Invalid params to update_user\n");
|
||||
goto nope;
|
||||
}
|
||||
|
||||
sprintf(buf, "HTTP/1.1 200 OK\r\n"
|
||||
"Server: KasmVNC/4.0\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-type: text/plain\r\n"
|
||||
"Content-length: 6\r\n"
|
||||
"\r\n"
|
||||
"200 OK");
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
|
||||
ret = 1;
|
||||
} else entry("/api/give_control") {
|
||||
char decname[1024] = "";
|
||||
@ -1103,7 +1147,6 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
||||
"200 OK");
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
|
||||
wserr("Passed give_control request to main thread\n");
|
||||
ret = 1;
|
||||
} else entry("/api/get_bottleneck_stats") {
|
||||
char statbuf[4096];
|
||||
@ -1120,6 +1163,23 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in) {
|
||||
|
||||
wserr("Sent bottleneck stats to API caller\n");
|
||||
ret = 1;
|
||||
} else entry("/api/get_users") {
|
||||
const char *ptr;
|
||||
settings.getUsersCb(settings.messager, &ptr);
|
||||
|
||||
sprintf(buf, "HTTP/1.1 200 OK\r\n"
|
||||
"Server: KasmVNC/4.0\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Content-type: text/plain\r\n"
|
||||
"Content-length: %lu\r\n"
|
||||
"\r\n", strlen(ptr));
|
||||
ws_send(ws_ctx, buf, strlen(buf));
|
||||
ws_send(ws_ctx, ptr, strlen(ptr));
|
||||
|
||||
free((char *) ptr);
|
||||
|
||||
wserr("Sent user list to API caller\n");
|
||||
ret = 1;
|
||||
} else entry("/api/get_frame_stats") {
|
||||
char statbuf[4096], decname[1024];
|
||||
unsigned waitfor;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <openssl/ssl.h>
|
||||
#include <stdint.h>
|
||||
#include "GetAPIEnums.h"
|
||||
|
||||
#define BUFSIZE 65536
|
||||
#define DBUFSIZE (BUFSIZE * 3) / 4 - 20
|
||||
@ -83,6 +84,8 @@ typedef struct {
|
||||
uint8_t (*adduserCb)(void *messager, const char name[], const char pw[],
|
||||
const uint8_t write);
|
||||
uint8_t (*removeCb)(void *messager, const char name[]);
|
||||
uint8_t (*updateUserCb)(void *messager, const char name[], const uint64_t mask,
|
||||
const uint8_t write, const uint8_t owner);
|
||||
uint8_t (*givecontrolCb)(void *messager, const char name[]);
|
||||
void (*bottleneckStatsCb)(void *messager, char *buf, uint32_t len);
|
||||
void (*frameStatsCb)(void *messager, char *buf, uint32_t len);
|
||||
@ -94,6 +97,7 @@ typedef struct {
|
||||
|
||||
uint8_t (*ownerConnectedCb)(void *messager);
|
||||
uint8_t (*numActiveUsersCb)(void *messager);
|
||||
void (*getUsersCb)(void *messager, const char **buf);
|
||||
uint8_t (*getClientFrameStatsNumCb)(void *messager);
|
||||
uint8_t (*serverFrameStatsReadyCb)(void *messager);
|
||||
} settings_t;
|
||||
|
@ -805,49 +805,8 @@ static void checkAPIMessages(network::GetAPIMessager *apimessager,
|
||||
slog.info("Main thread processing user API request %u/%u", i + 1, num);
|
||||
|
||||
const network::GetAPIMessager::action_data &act = apimessager->actionQueue[i];
|
||||
struct kasmpasswd_t *set = NULL;
|
||||
unsigned s;
|
||||
bool found;
|
||||
|
||||
switch (act.action) {
|
||||
case network::GetAPIMessager::USER_REMOVE:
|
||||
set = readkasmpasswd(kasmpasswdpath);
|
||||
found = false;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, act.data.user)) {
|
||||
set->entries[s].user[0] = '\0';
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
writekasmpasswd(kasmpasswdpath, set);
|
||||
slog.info("User %s removed", act.data.user);
|
||||
} else {
|
||||
slog.error("Tried to remove nonexistent user %s", act.data.user);
|
||||
}
|
||||
break;
|
||||
case network::GetAPIMessager::USER_GIVE_CONTROL:
|
||||
set = readkasmpasswd(kasmpasswdpath);
|
||||
found = false;
|
||||
for (s = 0; s < set->num; s++) {
|
||||
if (!strcmp(set->entries[s].user, act.data.user)) {
|
||||
set->entries[s].write = 1;
|
||||
found = true;
|
||||
} else {
|
||||
set->entries[s].write = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
writekasmpasswd(kasmpasswdpath, set);
|
||||
slog.info("User %s given control", act.data.user);
|
||||
} else {
|
||||
slog.error("Tried to give control to nonexistent user %s", act.data.user);
|
||||
}
|
||||
break;
|
||||
|
||||
case network::GetAPIMessager::WANT_FRAME_STATS_SERVERONLY:
|
||||
trackingFrameStats = act.action;
|
||||
break;
|
||||
@ -862,11 +821,6 @@ static void checkAPIMessages(network::GetAPIMessager *apimessager,
|
||||
memcpy(trackingClient, act.data.password, 128);
|
||||
break;
|
||||
}
|
||||
|
||||
if (set) {
|
||||
free(set->entries);
|
||||
free(set);
|
||||
}
|
||||
}
|
||||
|
||||
apimessager->actionQueue.clear();
|
||||
|
Loading…
Reference in New Issue
Block a user