static int virLXCControllerSetupServer(virLXCControllerPtr ctrl) { virNetServerServicePtr svc = NULL; char *sockpath; if (virAsprintf(&sockpath, "%s/%s.sock", LXC_STATE_DIR, ctrl->name) < 0) { virReportOOMError(); return -1; } if (!(ctrl->server = virNetServerNew(0, 0, 0, 1, -1, 0, false, NULL, virLXCControllerClientPrivateNew, NULL, virLXCControllerClientPrivateFree, ctrl))) goto error; if (!(svc = virNetServerServiceNewUNIX(sockpath, 0700, 0, 0, #if WITH_GNUTLS NULL, #endif false, 5))) goto error; if (virNetServerAddService(ctrl->server, svc, NULL) < 0) goto error; virObjectUnref(svc); svc = NULL; if (!(ctrl->prog = virNetServerProgramNew(VIR_LXC_PROTOCOL_PROGRAM, VIR_LXC_PROTOCOL_PROGRAM_VERSION, virLXCProtocolProcs, virLXCProtocolNProcs))) goto error; virNetServerUpdateServices(ctrl->server, true); VIR_FREE(sockpath); return 0; error: VIR_FREE(sockpath); virObjectUnref(ctrl->server); ctrl->server = NULL; virObjectUnref(svc); return -1; }
virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object, virNetServerClientPrivNew clientPrivNew, virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart, virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, virFreeCallback clientPrivFree, void *clientPrivOpaque) { virNetServerPtr srv = NULL; virJSONValuePtr clients; virJSONValuePtr services; size_t i; int n; unsigned int min_workers; unsigned int max_workers; unsigned int priority_workers; unsigned int max_clients; unsigned int max_anonymous_clients; unsigned int keepaliveInterval; unsigned int keepaliveCount; bool keepaliveRequired; const char *mdnsGroupName = NULL; if (virJSONValueObjectGetNumberUint(object, "min_workers", &min_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing min_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "max_workers", &max_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing max_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "priority_workers", &priority_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing priority_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "max_clients", &max_clients) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing max_clients data in JSON document")); goto error; } if (virJSONValueObjectHasKey(object, "max_anonymous_clients")) { if (virJSONValueObjectGetNumberUint(object, "max_anonymous_clients", &max_anonymous_clients) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed max_anonymous_clients data in JSON document")); goto error; } } else { max_anonymous_clients = max_clients; } if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveInterval data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "keepaliveCount", &keepaliveCount) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveCount data in JSON document")); goto error; } if (virJSONValueObjectGetBoolean(object, "keepaliveRequired", &keepaliveRequired) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveRequired data in JSON document")); goto error; } if (virJSONValueObjectHasKey(object, "mdnsGroupName") && (!(mdnsGroupName = virJSONValueObjectGetString(object, "mdnsGroupName")))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed mdnsGroupName data in JSON document")); goto error; } if (!(srv = virNetServerNew(min_workers, max_clients, priority_workers, max_clients, max_anonymous_clients, keepaliveInterval, keepaliveCount, keepaliveRequired, mdnsGroupName, clientPrivNew, clientPrivPreExecRestart, clientPrivFree, clientPrivOpaque))) goto error; if (!(services = virJSONValueObjectGet(object, "services"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing services data in JSON document")); goto error; } n = virJSONValueArraySize(services); if (n < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed services data in JSON document")); goto error; } for (i = 0; i < n; i++) { virNetServerServicePtr service; virJSONValuePtr child = virJSONValueArrayGet(services, i); if (!child) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing service data in JSON document")); goto error; } if (!(service = virNetServerServiceNewPostExecRestart(child))) goto error; /* XXX mdns entry names ? */ if (virNetServerAddService(srv, service, NULL) < 0) { virObjectUnref(service); goto error; } } if (!(clients = virJSONValueObjectGet(object, "clients"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing clients data in JSON document")); goto error; } n = virJSONValueArraySize(clients); if (n < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed clients data in JSON document")); goto error; } for (i = 0; i < n; i++) { virNetServerClientPtr client; virJSONValuePtr child = virJSONValueArrayGet(clients, i); if (!child) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing client data in JSON document")); goto error; } if (!(client = virNetServerClientNewPostExecRestart(child, clientPrivNewPostExecRestart, clientPrivPreExecRestart, clientPrivFree, clientPrivOpaque))) goto error; if (virNetServerAddClient(srv, client) < 0) { virObjectUnref(client); goto error; } virObjectUnref(client); } return srv; error: virObjectUnref(srv); return NULL; }
static int daemonSetupNetworking(virNetServerPtr srv, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; virNetServerServicePtr svcTLS = NULL; gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return -1; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto error; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto error; } if (!(svc = virNetServerServiceNewUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, false, config->max_client_requests, NULL))) goto error; if (sock_path_ro && !(svcRO = virNetServerServiceNewUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, true, config->max_client_requests, NULL))) goto error; if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto error; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto error; if (ipsock) { if (config->listen_tcp) { if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, config->auth_tcp, false, config->max_client_requests, NULL))) goto error; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto error; } if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, config->auth_tls, false, config->max_client_requests, ctxt))) { virNetTLSContextFree(ctxt); goto error; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto error; virNetTLSContextFree(ctxt); } } #if HAVE_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || config->auth_tcp == REMOTE_AUTH_SASL || config->auth_tls == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto error; } #endif return 0; error: virNetServerServiceFree(svcTLS); virNetServerServiceFree(svcTCP); virNetServerServiceFree(svc); virNetServerServiceFree(svcRO); return -1; }
static int daemonSetupNetworking(virNetServerPtr srv, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; #if WITH_GNUTLS virNetServerServicePtr svcTLS = NULL; #endif gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return -1; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto error; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto error; } VIR_DEBUG("Registering unix socket %s", sock_path); if (!(svc = virNetServerServiceNewUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto error; if (sock_path_ro) { VIR_DEBUG("Registering unix socket %s", sock_path_ro); if (!(svcRO = virNetServerServiceNewUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, #if WITH_GNUTLS NULL, #endif true, config->max_queued_clients, config->max_client_requests))) goto error; } if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto error; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto error; if (ipsock) { if (config->listen_tcp) { VIR_DEBUG("Registering TCP socket %s:%s", config->listen_addr, config->tcp_port); if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, config->auth_tcp, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto error; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto error; } #if WITH_GNUTLS if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto error; } VIR_DEBUG("Registering TLS socket %s:%s", config->listen_addr, config->tls_port); if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, config->auth_tls, ctxt, false, config->max_queued_clients, config->max_client_requests))) { virObjectUnref(ctxt); goto error; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto error; virObjectUnref(ctxt); } #else (void)privileged; if (config->listen_tls) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This libvirtd build does not support TLS")); goto error; } #endif } #if WITH_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || # if WITH_GNUTLS config->auth_tls == REMOTE_AUTH_SASL || # endif config->auth_tcp == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto error; } #endif return 0; error: #if WITH_GNUTLS virObjectUnref(svcTLS); #endif virObjectUnref(svcTCP); virObjectUnref(svc); virObjectUnref(svcRO); return -1; }
static virNetServerPtr testCreateServer(const char *host, int family) { virNetServerPtr srv = NULL; virNetServerServicePtr svc1 = NULL, svc2 = NULL; virNetServerClientPtr cln1 = NULL, cln2 = NULL; virNetSocketPtr sk1 = NULL, sk2 = NULL; int fdclient[2]; if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdclient) < 0) { virReportSystemError(errno, "%s", "Cannot create socket pair"); goto cleanup; } if (!(srv = virNetServerNew(10, 50, 5, 100, 10, 120, 5, true, # ifdef WITH_AVAHI "libvirtTest", # else NULL, # endif NULL, NULL, NULL, NULL))) goto error; if (!(svc1 = virNetServerServiceNewTCP(host, NULL, family, VIR_NET_SERVER_SERVICE_AUTH_NONE, # ifdef WITH_GNUTLS NULL, # endif true, 5, 2))) goto error; if (!(svc2 = virNetServerServiceNewTCP(host, NULL, family, VIR_NET_SERVER_SERVICE_AUTH_POLKIT, # ifdef WITH_GNUTLS NULL, # endif false, 25, 5))) goto error; if (virNetServerAddService(srv, svc1, "libvirt-ro") < 0) goto error; if (virNetServerAddService(srv, svc2, "libvirt-ro") < 0) goto error; if (virNetSocketNewConnectSockFD(fdclient[0], &sk1) < 0) goto error; if (virNetSocketNewConnectSockFD(fdclient[1], &sk2) < 0) goto error; if (!(cln1 = virNetServerClientNew(sk1, VIR_NET_SERVER_SERVICE_AUTH_SASL, true, 15, # ifdef WITH_GNUTLS NULL, # endif NULL, NULL, NULL, NULL))) goto error; if (!(cln2 = virNetServerClientNew(sk2, VIR_NET_SERVER_SERVICE_AUTH_POLKIT, true, 66, # ifdef WITH_GNUTLS NULL, # endif NULL, NULL, NULL, NULL))) goto error; if (virNetServerAddClient(srv, cln1) < 0) goto error; if (virNetServerAddClient(srv, cln2) < 0) goto error; cleanup: virObjectUnref(cln1); virObjectUnref(cln2); virObjectUnref(svc1); virObjectUnref(svc2); return srv; error: virObjectUnref(srv); srv = NULL; goto cleanup; }
daemonSetupNetworking(virNetServerPtr srv, virNetServerPtr srvAdm, struct daemonConfig *config, const char *sock_path, const char *sock_path_ro, const char *sock_path_adm, bool ipsock, bool privileged) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcAdm = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; #if WITH_GNUTLS virNetServerServicePtr svcTLS = NULL; #endif gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; int unix_sock_adm_mask = 0; int ret = -1; unsigned int cur_fd = STDERR_FILENO + 1; unsigned int nfds = virGetListenFDs(); if (config->unix_sock_group) { if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0) return ret; } if (nfds > (sock_path_ro ? 2 : 1)) { VIR_ERROR(_("Too many (%u) FDs passed from caller"), nfds); return ret; } if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms); goto cleanup; } if (virStrToLong_i(config->unix_sock_admin_perms, NULL, 8, &unix_sock_adm_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_admin_perms); goto cleanup; } if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); goto cleanup; } if (!(svc = virNetServerServiceNewFDOrUNIX(sock_path, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests, nfds, &cur_fd))) goto cleanup; if (sock_path_ro) { if (!(svcRO = virNetServerServiceNewFDOrUNIX(sock_path_ro, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, #if WITH_GNUTLS NULL, #endif true, config->max_queued_clients, config->max_client_requests, nfds, &cur_fd))) goto cleanup; } if (virNetServerAddService(srv, svc, config->mdns_adv && !ipsock ? "_libvirt._tcp" : NULL) < 0) goto cleanup; if (svcRO && virNetServerAddService(srv, svcRO, NULL) < 0) goto cleanup; /* Temporarily disabled */ if (sock_path_adm && false) { VIR_DEBUG("Registering unix socket %s", sock_path_adm); if (!(svcAdm = virNetServerServiceNewUNIX(sock_path_adm, unix_sock_adm_mask, unix_sock_gid, REMOTE_AUTH_NONE, #if WITH_GNUTLS NULL, #endif true, config->admin_max_queued_clients, config->admin_max_client_requests))) goto cleanup; if (virNetServerAddService(srvAdm, svcAdm, NULL) < 0) goto cleanup; } if (ipsock) { if (config->listen_tcp) { VIR_DEBUG("Registering TCP socket %s:%s", config->listen_addr, config->tcp_port); if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, AF_UNSPEC, config->auth_tcp, #if WITH_GNUTLS NULL, #endif false, config->max_queued_clients, config->max_client_requests))) goto cleanup; if (virNetServerAddService(srv, svcTCP, config->mdns_adv ? "_libvirt._tcp" : NULL) < 0) goto cleanup; } #if WITH_GNUTLS if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; if (config->ca_file || config->cert_file || config->key_file) { if (!(ctxt = virNetTLSContextNewServer(config->ca_file, config->crl_file, config->cert_file, config->key_file, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto cleanup; } else { if (!(ctxt = virNetTLSContextNewServerPath(NULL, !privileged, (const char *const*)config->tls_allowed_dn_list, config->tls_no_sanity_certificate ? false : true, config->tls_no_verify_certificate ? false : true))) goto cleanup; } VIR_DEBUG("Registering TLS socket %s:%s", config->listen_addr, config->tls_port); if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, AF_UNSPEC, config->auth_tls, ctxt, false, config->max_queued_clients, config->max_client_requests))) { virObjectUnref(ctxt); goto cleanup; } if (virNetServerAddService(srv, svcTLS, config->mdns_adv && !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0) goto cleanup; virObjectUnref(ctxt); } #else (void)privileged; if (config->listen_tls) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This libvirtd build does not support TLS")); goto cleanup; } #endif } #if WITH_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || # if WITH_GNUTLS config->auth_tls == REMOTE_AUTH_SASL || # endif config->auth_tcp == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) goto cleanup; } #endif ret = 0; cleanup: #if WITH_GNUTLS virObjectUnref(svcTLS); #endif virObjectUnref(svcTCP); virObjectUnref(svcRO); virObjectUnref(svcAdm); virObjectUnref(svc); return ret; }