libvirt/src/admin/admin_server.c
Zhang Bo 29e68c932f admin: Introduce virAdmServerUpdateTlsFiles
The server needs to use CA certificate, CRL, server certificate/key to
complete the TLS handshake. If these files change, we needed to restart
libvirtd for them to take effect. This API can update the TLS context
*ONLINE* without restarting libvirtd.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Zhang Bo <oscar.zhangbo@huawei.com>
Signed-off-by: Wu Qingliang <wuqingliang4@huawei.com>
2020-03-13 17:07:32 +00:00

379 lines
12 KiB
C

/*
* admin_server.c: admin methods to manage daemons and clients
*
* Copyright (C) 2016 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "admin_server.h"
#include "datatypes.h"
#include "viralloc.h"
#include "virerror.h"
#include "viridentity.h"
#include "virlog.h"
#include "rpc/virnetdaemon.h"
#include "rpc/virnetserver.h"
#include "virstring.h"
#include "virthreadpool.h"
#include "virtypedparam.h"
#define VIR_FROM_THIS VIR_FROM_ADMIN
VIR_LOG_INIT("daemon.admin_server");
int
adminConnectListServers(virNetDaemonPtr dmn,
virNetServerPtr **servers,
unsigned int flags)
{
int ret = -1;
virNetServerPtr *srvs = NULL;
virCheckFlags(0, -1);
if ((ret = virNetDaemonGetServers(dmn, &srvs)) < 0)
goto cleanup;
if (servers) {
*servers = srvs;
srvs = NULL;
}
cleanup:
if (ret > 0)
virObjectListFreeCount(srvs, ret);
return ret;
}
virNetServerPtr
adminConnectLookupServer(virNetDaemonPtr dmn,
const char *name,
unsigned int flags)
{
virCheckFlags(flags, NULL);
return virNetDaemonGetServer(dmn, name);
}
int
adminServerGetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
size_t minWorkers;
size_t maxWorkers;
size_t nWorkers;
size_t freeWorkers;
size_t nPrioWorkers;
size_t jobQueueDepth;
g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
virCheckFlags(0, -1);
if (virNetServerGetThreadPoolParameters(srv, &minWorkers, &maxWorkers,
&nWorkers, &freeWorkers,
&nPrioWorkers,
&jobQueueDepth) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to retrieve threadpool parameters"));
return -1;
}
if (virTypedParamListAddUInt(paramlist, minWorkers,
"%s", VIR_THREADPOOL_WORKERS_MIN) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist, maxWorkers,
"%s", VIR_THREADPOOL_WORKERS_MAX) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist, nWorkers,
"%s", VIR_THREADPOOL_WORKERS_CURRENT) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist, freeWorkers,
"%s", VIR_THREADPOOL_WORKERS_FREE) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist, nPrioWorkers,
"%s", VIR_THREADPOOL_WORKERS_PRIORITY) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist, jobQueueDepth,
"%s", VIR_THREADPOOL_JOB_QUEUE_DEPTH) < 0)
return -1;
*nparams = virTypedParamListStealParams(paramlist, params);
return 0;
}
int
adminServerSetThreadPoolParameters(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags)
{
long long int minWorkers = -1;
long long int maxWorkers = -1;
long long int prioWorkers = -1;
virTypedParameterPtr param = NULL;
virCheckFlags(0, -1);
if (virTypedParamsValidate(params, nparams,
VIR_THREADPOOL_WORKERS_MIN,
VIR_TYPED_PARAM_UINT,
VIR_THREADPOOL_WORKERS_MAX,
VIR_TYPED_PARAM_UINT,
VIR_THREADPOOL_WORKERS_PRIORITY,
VIR_TYPED_PARAM_UINT,
NULL) < 0)
return -1;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_MIN)))
minWorkers = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_MAX)))
maxWorkers = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_THREADPOOL_WORKERS_PRIORITY)))
prioWorkers = param->value.ui;
if (virNetServerSetThreadPoolParameters(srv, minWorkers,
maxWorkers, prioWorkers) < 0)
return -1;
return 0;
}
int
adminServerListClients(virNetServerPtr srv,
virNetServerClientPtr **clients,
unsigned int flags)
{
int ret = -1;
virNetServerClientPtr *clts;
virCheckFlags(0, -1);
if ((ret = virNetServerGetClients(srv, &clts)) < 0)
return -1;
if (clients) {
*clients = clts;
clts = NULL;
}
virObjectListFreeCount(clts, ret);
return ret;
}
virNetServerClientPtr
adminServerLookupClient(virNetServerPtr srv,
unsigned long long id,
unsigned int flags)
{
virCheckFlags(0, NULL);
return virNetServerGetClient(srv, id);
}
int
adminClientGetInfo(virNetServerClientPtr client,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
bool readonly;
g_autofree char *sock_addr = NULL;
const char *attr = NULL;
g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
g_autoptr(virIdentity) identity = NULL;
int rc;
virCheckFlags(0, -1);
if (virNetServerClientGetInfo(client, &readonly,
&sock_addr, &identity) < 0)
return -1;
if (virTypedParamListAddBoolean(paramlist, readonly,
"%s", VIR_CLIENT_INFO_READONLY) < 0)
return -1;
if ((rc = virIdentityGetSASLUserName(identity, &attr)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddString(paramlist, attr,
"%s", VIR_CLIENT_INFO_SASL_USER_NAME) < 0)
return -1;
if (!virNetServerClientIsLocal(client)) {
if (virTypedParamListAddString(paramlist, sock_addr,
"%s", VIR_CLIENT_INFO_SOCKET_ADDR) < 0)
return -1;
if ((rc = virIdentityGetX509DName(identity, &attr)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddString(paramlist, attr,
"%s", VIR_CLIENT_INFO_X509_DISTINGUISHED_NAME) < 0)
return -1;
} else {
pid_t pid;
uid_t uid;
gid_t gid;
if ((rc = virIdentityGetUNIXUserID(identity, &uid)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddInt(paramlist, uid,
"%s", VIR_CLIENT_INFO_UNIX_USER_ID) < 0)
return -1;
if ((rc = virIdentityGetUserName(identity, &attr)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddString(paramlist, attr,
"%s", VIR_CLIENT_INFO_UNIX_USER_NAME) < 0)
return -1;
if ((rc = virIdentityGetUNIXGroupID(identity, &gid)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddInt(paramlist, gid,
"%s", VIR_CLIENT_INFO_UNIX_GROUP_ID) < 0)
return -1;
if ((rc = virIdentityGetGroupName(identity, &attr)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddString(paramlist, attr,
"%s", VIR_CLIENT_INFO_UNIX_GROUP_NAME) < 0)
return -1;
if ((rc = virIdentityGetProcessID(identity, &pid)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddInt(paramlist, pid,
"%s", VIR_CLIENT_INFO_UNIX_PROCESS_ID) < 0)
return -1;
}
if ((rc = virIdentityGetSELinuxContext(identity, &attr)) < 0)
return -1;
if (rc == 1 &&
virTypedParamListAddString(paramlist, attr,
"%s", VIR_CLIENT_INFO_SELINUX_CONTEXT) < 0)
return -1;
*nparams = virTypedParamListStealParams(paramlist, params);
return 0;
}
int adminClientClose(virNetServerClientPtr client,
unsigned int flags)
{
virCheckFlags(0, -1);
virNetServerClientClose(client);
return 0;
}
int
adminServerGetClientLimits(virNetServerPtr srv,
virTypedParameterPtr *params,
int *nparams,
unsigned int flags)
{
g_autoptr(virTypedParamList) paramlist = g_new0(virTypedParamList, 1);
virCheckFlags(0, -1);
if (virTypedParamListAddUInt(paramlist,
virNetServerGetMaxClients(srv),
"%s", VIR_SERVER_CLIENTS_MAX) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist,
virNetServerGetCurrentClients(srv),
"%s", VIR_SERVER_CLIENTS_CURRENT) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist,
virNetServerGetMaxUnauthClients(srv),
"%s", VIR_SERVER_CLIENTS_UNAUTH_MAX) < 0)
return -1;
if (virTypedParamListAddUInt(paramlist,
virNetServerGetCurrentUnauthClients(srv),
"%s", VIR_SERVER_CLIENTS_UNAUTH_CURRENT) < 0)
return -1;
*nparams = virTypedParamListStealParams(paramlist, params);
return 0;
}
int
adminServerSetClientLimits(virNetServerPtr srv,
virTypedParameterPtr params,
int nparams,
unsigned int flags)
{
long long int maxClients = -1;
long long int maxClientsUnauth = -1;
virTypedParameterPtr param = NULL;
virCheckFlags(0, -1);
if (virTypedParamsValidate(params, nparams,
VIR_SERVER_CLIENTS_MAX,
VIR_TYPED_PARAM_UINT,
VIR_SERVER_CLIENTS_UNAUTH_MAX,
VIR_TYPED_PARAM_UINT,
NULL) < 0)
return -1;
if ((param = virTypedParamsGet(params, nparams,
VIR_SERVER_CLIENTS_MAX)))
maxClients = param->value.ui;
if ((param = virTypedParamsGet(params, nparams,
VIR_SERVER_CLIENTS_UNAUTH_MAX)))
maxClientsUnauth = param->value.ui;
if (virNetServerSetClientLimits(srv, maxClients,
maxClientsUnauth) < 0)
return -1;
return 0;
}
int
adminServerUpdateTlsFiles(virNetServerPtr srv,
unsigned int flags)
{
virCheckFlags(0, -1);
return virNetServerUpdateTlsFiles(srv);
}