remote_daemon_config.c 12.8 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 24 25
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

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

#define VIR_FROM_THIS VIR_FROM_CONF

41 42
VIR_LOG_INIT("daemon.libvirtd-config");

43

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

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

55
    if (!authstr)
56 57
        return 0;

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

74
    VIR_FREE(authstr);
75 76 77 78 79 80 81
    return 0;
}

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

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

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

    return 0;

99
 error:
100 101 102 103 104 105 106 107 108 109
    return -1;
}

struct daemonConfig*
daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
{
    struct daemonConfig *data;
    char *localhost;
    int ret;

110
    if (VIR_ALLOC(data) < 0)
111 112 113 114 115
        return NULL;

    data->listen_tls = 1;
    data->listen_tcp = 0;

116 117 118
    if (VIR_STRDUP(data->tls_port, LIBVIRTD_TLS_PORT) < 0 ||
        VIR_STRDUP(data->tcp_port, LIBVIRTD_TCP_PORT) < 0)
        goto error;
119 120

    /* Only default to PolicyKit if running as root */
121
#if WITH_POLKIT
122 123 124 125 126 127 128
    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;
129
#if WITH_POLKIT
130 131 132
    }
#endif

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

139
#if WITH_SASL
140 141 142 143 144 145 146 147 148 149
    data->auth_tcp = REMOTE_AUTH_SASL;
#else
    data->auth_tcp = REMOTE_AUTH_NONE;
#endif
    data->auth_tls = REMOTE_AUTH_NONE;

    data->mdns_adv = 0;

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

    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;

164 165 166 167 168 169 170 171 172
    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;

173 174
    data->ovs_timeout = VIR_NETDEV_OVS_DEFAULT_TIMEOUT;

175
    localhost = virGetHostname();
176 177 178 179 180
    if (localhost == NULL) {
        /* we couldn't resolve the hostname; assume that we are
         * running in disconnected operation, and report a less
         * useful Avahi string
         */
181
        ret = VIR_STRDUP(data->mdns_name, "Virtualization Host");
182 183 184 185 186 187 188 189 190 191
    } else {
        char *tmp;
        /* Extract the host part of the potentially FQDN */
        if ((tmp = strchr(localhost, '.')))
            *tmp = '\0';
        ret = virAsprintf(&data->mdns_name, "Virtualization Host %s",
                          localhost);
    }
    VIR_FREE(localhost);
    if (ret < 0)
192
        goto error;
193 194 195

    return data;

196
 error:
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    daemonConfigFree(data);
    return NULL;
}

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

    if (!data)
        return;

    VIR_FREE(data->listen_addr);
    VIR_FREE(data->tls_port);
    VIR_FREE(data->tcp_port);
212 213 214 215 216 217
    tmp = data->access_drivers;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->access_drivers);
218

219
    VIR_FREE(data->unix_sock_admin_perms);
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
    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);
    VIR_FREE(data->mdns_name);

    tmp = data->tls_allowed_dn_list;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->tls_allowed_dn_list);

    tmp = data->sasl_allowed_username_list;
    while (tmp && *tmp) {
        VIR_FREE(*tmp);
        tmp++;
    }
    VIR_FREE(data->sasl_allowed_username_list);
239
    VIR_FREE(data->tls_priority);
240 241 242 243 244 245

    VIR_FREE(data->key_file);
    VIR_FREE(data->ca_file);
    VIR_FREE(data->cert_file);
    VIR_FREE(data->crl_file);

A
Alex Jia 已提交
246
    VIR_FREE(data->host_uuid);
247
    VIR_FREE(data->host_uuid_source);
248 249 250 251 252 253
    VIR_FREE(data->log_filters);
    VIR_FREE(data->log_outputs);

    VIR_FREE(data);
}

254 255 256 257
static int
daemonConfigLoadOptions(struct daemonConfig *data,
                        const char *filename,
                        virConfPtr conf)
258
{
259 260 261 262 263 264 265 266 267 268
    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;
269

270
    if (remoteConfigGetAuth(conf, filename, "auth_unix_rw", &data->auth_unix_rw) < 0)
271
        goto error;
272
#if WITH_POLKIT
273 274 275 276 277
    /* 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);
278
        if (VIR_STRDUP(data->unix_sock_rw_perms, "0777") < 0)
279 280 281
            goto error;
    }
#endif
282
    if (remoteConfigGetAuth(conf, filename, "auth_unix_ro", &data->auth_unix_ro) < 0)
283
        goto error;
284
    if (remoteConfigGetAuth(conf, filename, "auth_tcp", &data->auth_tcp) < 0)
285
        goto error;
286
    if (remoteConfigGetAuth(conf, filename, "auth_tls", &data->auth_tls) < 0)
287 288
        goto error;

289 290
    if (virConfGetValueStringList(conf, "access_drivers", false,
                                  &data->access_drivers) < 0)
291 292
        goto error;

293 294 295 296 297 298 299 300
    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;
301

302 303
    if (virConfGetValueString(conf, "unix_sock_dir", &data->unix_sock_dir) < 0)
        goto error;
304

305 306 307 308
    if (virConfGetValueBool(conf, "mdns_adv", &data->mdns_adv) < 0)
        goto error;
    if (virConfGetValueString(conf, "mdns_name", &data->mdns_name) < 0)
        goto error;
309

310 311 312 313
    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;
314

315 316 317 318 319 320 321 322
    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;
323

324 325
    if (virConfGetValueStringList(conf, "tls_allowed_dn_list", false,
                                  &data->tls_allowed_dn_list) < 0)
326 327 328
        goto error;


329 330
    if (virConfGetValueStringList(conf, "sasl_allowed_username_list", false,
                                  &data->sasl_allowed_username_list) < 0)
331 332
        goto error;

333 334
    if (virConfGetValueString(conf, "tls_priority", &data->tls_priority) < 0)
        goto error;
335

336 337 338 339 340 341 342 343 344 345
    if (virConfGetValueUInt(conf, "min_workers", &data->min_workers) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "max_workers", &data->max_workers) < 0)
        goto error;
    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;
346

347 348
    if (virConfGetValueUInt(conf, "prio_workers", &data->prio_workers) < 0)
        goto error;
349

350 351
    if (virConfGetValueUInt(conf, "max_client_requests", &data->max_client_requests) < 0)
        goto error;
352

353 354 355 356 357 358 359 360 361 362
    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;
363

364 365 366 367
    if (virConfGetValueUInt(conf, "audit_level", &data->audit_level) < 0)
        goto error;
    if (virConfGetValueBool(conf, "audit_logging", &data->audit_logging) < 0)
        goto error;
368

369 370 371 372
    if (virConfGetValueString(conf, "host_uuid", &data->host_uuid) < 0)
        goto error;
    if (virConfGetValueString(conf, "host_uuid_source", &data->host_uuid_source) < 0)
        goto error;
373

374 375 376 377 378 379
    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;
380

381 382 383 384
    if (virConfGetValueInt(conf, "keepalive_interval", &data->keepalive_interval) < 0)
        goto error;
    if (virConfGetValueUInt(conf, "keepalive_count", &data->keepalive_count) < 0)
        goto error;
385

386 387 388 389
    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;
390

391 392 393
    if (virConfGetValueUInt(conf, "ovs_timeout", &data->ovs_timeout) < 0)
        goto error;

394 395
    return 0;

396
 error:
397 398
    return -1;
}
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 424 425 426 427 428 429 430 431 432


/* 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 已提交
433
    conf = virConfReadString(filedata, 0);
434 435 436 437 438 439 440
    if (!conf)
        return -1;

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