remote_daemon_config.c 12.3 KB
Newer Older
1
/*
2
 * remote_daemon_config.c: libvirtd config file handling
3
 *
4
 * Copyright (C) 2006-2018 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006 Daniel P. Berrange
 *
 * 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
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
20 21 22 23
 */

#include <config.h>

24
#include "remote_daemon_config.h"
25
#include "virconf.h"
26
#include "viralloc.h"
27
#include "virerror.h"
28
#include "virlog.h"
29
#include "rpc/virnetserver.h"
30
#include "configmake.h"
31 32
#include "remote_protocol.h"
#include "remote_driver.h"
33
#include "util/virnetdevopenvswitch.h"
34 35
#include "virstring.h"
#include "virutil.h"
36 37 38

#define VIR_FROM_THIS VIR_FROM_CONF

39 40
VIR_LOG_INIT("daemon.libvirtd-config");

41

42 43
static int
remoteConfigGetAuth(virConfPtr conf,
44
                    const char *filename,
45
                    const char *key,
46
                    int *auth)
47
{
48
    char *authstr = NULL;
49

50
    if (virConfGetValueString(conf, key, &authstr) < 0)
51 52
        return -1;

53
    if (!authstr)
54 55
        return 0;

56
    if (STREQ(authstr, "none")) {
57
        *auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
58
#if WITH_SASL
59
    } else if (STREQ(authstr, "sasl")) {
60 61
        *auth = VIR_NET_SERVER_SERVICE_AUTH_SASL;
#endif
62
    } else if (STREQ(authstr, "polkit")) {
63 64
        *auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT;
    } else {
65
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
66 67 68
                       _("%s: %s: unsupported auth %s"),
                       filename, key, authstr);
        VIR_FREE(authstr);
69 70 71
        return -1;
    }

72
    VIR_FREE(authstr);
73 74 75 76 77 78 79
    return 0;
}

int
daemonConfigFilePath(bool privileged, char **configfile)
{
    if (privileged) {
80 81
        if (VIR_STRDUP(*configfile,
                       SYSCONFDIR "/libvirt/" DAEMON_NAME ".conf") < 0)
82
            goto error;
83
    } else {
84
        char *configdir = NULL;
85

86
        if (!(configdir = virGetUserConfigDirectory()))
87 88
            goto error;

89
        if (virAsprintf(configfile, "%s/%s.conf", configdir, DAEMON_NAME) < 0) {
90
            VIR_FREE(configdir);
91
            goto error;
92
        }
93
        VIR_FREE(configdir);
94 95 96 97
    }

    return 0;

98
 error:
99 100 101 102 103 104 105 106
    return -1;
}

struct daemonConfig*
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
{
    struct daemonConfig *data;

107
    if (VIR_ALLOC(data) < 0)
108 109
        return NULL;

110
#ifdef WITH_IP
111 112 113
    data->listen_tls = 1;
    data->listen_tcp = 0;

114 115 116
    if (VIR_STRDUP(data->tls_port, LIBVIRTD_TLS_PORT) < 0 ||
        VIR_STRDUP(data->tcp_port, LIBVIRTD_TCP_PORT) < 0)
        goto error;
117
#endif /* !WITH_IP */
118 119

    /* Only default to PolicyKit if running as root */
120
#if WITH_POLKIT
121 122 123 124 125 126 127
    if (privileged) {
        data->auth_unix_rw = REMOTE_AUTH_POLKIT;
        data->auth_unix_ro = REMOTE_AUTH_POLKIT;
    } else {
#endif
        data->auth_unix_rw = REMOTE_AUTH_NONE;
        data->auth_unix_ro = REMOTE_AUTH_NONE;
128
#if WITH_POLKIT
129 130 131
    }
#endif

132 133
    if (VIR_STRDUP(data->unix_sock_rw_perms,
                   data->auth_unix_rw == REMOTE_AUTH_POLKIT ? "0777" : "0700") < 0 ||
134 135
        VIR_STRDUP(data->unix_sock_ro_perms, "0777") < 0 ||
        VIR_STRDUP(data->unix_sock_admin_perms, "0700") < 0)
136
        goto error;
137

138 139
#ifdef WITH_IP
# if WITH_SASL
140
    data->auth_tcp = REMOTE_AUTH_SASL;
141
# else
142
    data->auth_tcp = REMOTE_AUTH_NONE;
143
# endif
144
    data->auth_tls = REMOTE_AUTH_NONE;
145
#endif /* ! WITH_IP */
146 147 148

    data->min_workers = 5;
    data->max_workers = 20;
149
    data->max_clients = 5000;
150
    data->max_queued_clients = 1000;
151
    data->max_anonymous_clients = 20;
152 153 154 155 156 157 158 159 160 161 162

    data->prio_workers = 5;

    data->max_client_requests = 5;

    data->audit_level = 1;
    data->audit_logging = 0;

    data->keepalive_interval = 5;
    data->keepalive_count = 5;

163 164 165 166 167 168 169 170 171
    data->admin_min_workers = 5;
    data->admin_max_workers = 20;
    data->admin_max_clients = 5000;
    data->admin_max_queued_clients = 20;
    data->admin_max_client_requests = 5;

    data->admin_keepalive_interval = 5;
    data->admin_keepalive_count = 5;

172 173
    data->ovs_timeout = VIR_NETDEV_OVS_DEFAULT_TIMEOUT;

174 175
    return data;

176
 error:
177 178 179 180 181 182 183 184 185 186 187 188
    daemonConfigFree(data);
    return NULL;
}

void
daemonConfigFree(struct daemonConfig *data)
{
    char **tmp;

    if (!data)
        return;

189
#ifdef WITH_IP
190 191 192
    VIR_FREE(data->listen_addr);
    VIR_FREE(data->tls_port);
    VIR_FREE(data->tcp_port);
193 194
#endif /* ! WITH_IP */

195 196 197 198 199 200
    tmp = data->access_drivers;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->access_drivers);
201

202
    VIR_FREE(data->unix_sock_admin_perms);
203 204 205 206 207
    VIR_FREE(data->unix_sock_ro_perms);
    VIR_FREE(data->unix_sock_rw_perms);
    VIR_FREE(data->unix_sock_group);
    VIR_FREE(data->unix_sock_dir);

208
    tmp = data->sasl_allowed_username_list;
209 210 211 212
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
213
    VIR_FREE(data->sasl_allowed_username_list);
214

215 216
#ifdef WITH_IP
    tmp = data->tls_allowed_dn_list;
217 218 219 220
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
221 222
    VIR_FREE(data->tls_allowed_dn_list);

223
    VIR_FREE(data->tls_priority);
224 225 226 227 228

    VIR_FREE(data->key_file);
    VIR_FREE(data->ca_file);
    VIR_FREE(data->cert_file);
    VIR_FREE(data->crl_file);
229
#endif /* ! WITH_IP */
230

A
Alex Jia 已提交
231
    VIR_FREE(data->host_uuid);
232
    VIR_FREE(data->host_uuid_source);
233 234 235 236 237 238
    VIR_FREE(data->log_filters);
    VIR_FREE(data->log_outputs);

    VIR_FREE(data);
}

239 240 241 242
static int
daemonConfigLoadOptions(struct daemonConfig *data,
                        const char *filename,
                        virConfPtr conf)
243
{
244
#ifdef WITH_IP
245 246 247 248 249 250 251 252 253 254
    if (virConfGetValueBool(conf, "listen_tcp", &data->listen_tcp) < 0)
        goto error;
    if (virConfGetValueBool(conf, "listen_tls", &data->listen_tls) < 0)
        goto error;
    if (virConfGetValueString(conf, "tls_port", &data->tls_port) < 0)
        goto error;
    if (virConfGetValueString(conf, "tcp_port", &data->tcp_port) < 0)
        goto error;
    if (virConfGetValueString(conf, "listen_addr", &data->listen_addr) < 0)
        goto error;
255
#endif /* !WITH_IP */
256

257
    if (remoteConfigGetAuth(conf, filename, "auth_unix_rw", &data->auth_unix_rw) < 0)
258
        goto error;
259
#if WITH_POLKIT
260 261 262 263 264
    /* Change default perms to be wide-open if PolicyKit is enabled.
     * Admin can always override in config file
     */
    if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
        VIR_FREE(data->unix_sock_rw_perms);
265
        if (VIR_STRDUP(data->unix_sock_rw_perms, "0777") < 0)
266 267 268
            goto error;
    }
#endif
269
    if (remoteConfigGetAuth(conf, filename, "auth_unix_ro", &data->auth_unix_ro) < 0)
270
        goto error;
271 272

#ifdef WITH_IP
273
    if (remoteConfigGetAuth(conf, filename, "auth_tcp", &data->auth_tcp) < 0)
274
        goto error;
275
    if (remoteConfigGetAuth(conf, filename, "auth_tls", &data->auth_tls) < 0)
276
        goto error;
277
#endif /* ! WITH_IP */
278

279 280
    if (virConfGetValueStringList(conf, "access_drivers", false,
                                  &data->access_drivers) < 0)
281 282
        goto error;

283 284 285 286 287 288 289 290
    if (virConfGetValueString(conf, "unix_sock_group", &data->unix_sock_group) < 0)
        goto error;
    if (virConfGetValueString(conf, "unix_sock_admin_perms", &data->unix_sock_admin_perms) < 0)
        goto error;
    if (virConfGetValueString(conf, "unix_sock_ro_perms", &data->unix_sock_ro_perms) < 0)
        goto error;
    if (virConfGetValueString(conf, "unix_sock_rw_perms", &data->unix_sock_rw_perms) < 0)
        goto error;
291

292 293
    if (virConfGetValueString(conf, "unix_sock_dir", &data->unix_sock_dir) < 0)
        goto error;
294

295
#ifdef WITH_IP
296 297 298 299
    if (virConfGetValueBool(conf, "tls_no_sanity_certificate", &data->tls_no_sanity_certificate) < 0)
        goto error;
    if (virConfGetValueBool(conf, "tls_no_verify_certificate", &data->tls_no_verify_certificate) < 0)
        goto error;
300

301 302 303 304 305 306 307 308
    if (virConfGetValueString(conf, "key_file", &data->key_file) < 0)
        goto error;
    if (virConfGetValueString(conf, "cert_file", &data->cert_file) < 0)
        goto error;
    if (virConfGetValueString(conf, "ca_file", &data->ca_file) < 0)
        goto error;
    if (virConfGetValueString(conf, "crl_file", &data->crl_file) < 0)
        goto error;
309

310 311
    if (virConfGetValueStringList(conf, "tls_allowed_dn_list", false,
                                  &data->tls_allowed_dn_list) < 0)
312 313
        goto error;

314 315 316
    if (virConfGetValueString(conf, "tls_priority", &data->tls_priority) < 0)
        goto error;
#endif /* ! WITH_IP */
317

318 319
    if (virConfGetValueStringList(conf, "sasl_allowed_username_list", false,
                                  &data->sasl_allowed_username_list) < 0)
320 321
        goto error;

322 323 324 325
    if (virConfGetValueUInt(conf, "min_workers", &data->min_workers) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "max_workers", &data->max_workers) < 0)
        goto error;
326 327 328 329 330
    if (data->max_workers < 1) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("'max_workers' must be greater than 0"));
        goto error;
    }
331 332 333 334 335 336
    if (virConfGetValueUInt(conf, "max_clients", &data->max_clients) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "max_queued_clients", &data->max_queued_clients) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "max_anonymous_clients", &data->max_anonymous_clients) < 0)
        goto error;
337

338 339
    if (virConfGetValueUInt(conf, "prio_workers", &data->prio_workers) < 0)
        goto error;
340

341 342
    if (virConfGetValueUInt(conf, "max_client_requests", &data->max_client_requests) < 0)
        goto error;
343

344 345 346 347 348 349 350 351 352 353
    if (virConfGetValueUInt(conf, "admin_min_workers", &data->admin_min_workers) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "admin_max_workers", &data->admin_max_workers) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "admin_max_clients", &data->admin_max_clients) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "admin_max_queued_clients", &data->admin_max_queued_clients) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "admin_max_client_requests", &data->admin_max_client_requests) < 0)
        goto error;
354

355 356 357 358
    if (virConfGetValueUInt(conf, "audit_level", &data->audit_level) < 0)
        goto error;
    if (virConfGetValueBool(conf, "audit_logging", &data->audit_logging) < 0)
        goto error;
359

360 361 362 363
    if (virConfGetValueString(conf, "host_uuid", &data->host_uuid) < 0)
        goto error;
    if (virConfGetValueString(conf, "host_uuid_source", &data->host_uuid_source) < 0)
        goto error;
364

365 366 367 368 369 370
    if (virConfGetValueUInt(conf, "log_level", &data->log_level) < 0)
        goto error;
    if (virConfGetValueString(conf, "log_filters", &data->log_filters) < 0)
        goto error;
    if (virConfGetValueString(conf, "log_outputs", &data->log_outputs) < 0)
        goto error;
371

372 373 374 375
    if (virConfGetValueInt(conf, "keepalive_interval", &data->keepalive_interval) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "keepalive_count", &data->keepalive_count) < 0)
        goto error;
376

377 378 379 380
    if (virConfGetValueInt(conf, "admin_keepalive_interval", &data->admin_keepalive_interval) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "admin_keepalive_count", &data->admin_keepalive_count) < 0)
        goto error;
381

382 383 384
    if (virConfGetValueUInt(conf, "ovs_timeout", &data->ovs_timeout) < 0)
        goto error;

385 386
    return 0;

387
 error:
388 389
    return -1;
}
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423


/* Read the config file if it exists.
 * Only used in the remote case, hence the name.
 */
int
daemonConfigLoadFile(struct daemonConfig *data,
                     const char *filename,
                     bool allow_missing)
{
    virConfPtr conf;
    int ret;

    if (allow_missing &&
        access(filename, R_OK) == -1 &&
        errno == ENOENT)
        return 0;

    conf = virConfReadFile(filename, 0);
    if (!conf)
        return -1;

    ret = daemonConfigLoadOptions(data, filename, conf);
    virConfFree(conf);
    return ret;
}

int daemonConfigLoadData(struct daemonConfig *data,
                         const char *filename,
                         const char *filedata)
{
    virConfPtr conf;
    int ret;

J
Ján Tomko 已提交
424
    conf = virConfReadString(filedata, 0);
425 426 427 428 429 430 431
    if (!conf)
        return -1;

    ret = daemonConfigLoadOptions(data, filename, conf);
    virConfFree(conf);
    return ret;
}