~serge-hallyn/ubuntu/raring/libvirt/libvirt-hugepages

« back to all changes in this revision

Viewing changes to src/conf/secret_conf.c

  • Committer: James Westby
  • Author(s): Jamie Strandboge
  • Date: 2009-12-02 14:22:21 UTC
  • mfrom: (1.2.3 upstream) (3.4.9 squeeze)
  • Revision ID: james.westby@canonical.com-20091202142221-ltkr0to6h52mla1y
Tags: 0.7.2-4ubuntu1
* Merge from debian testing. Remaining changes:
  - debian/control:
    + Don't build-depend on QEmu
    + Bump bridge-utils, dnsmasq-base, netcat-openbsd, and iptables
      to Depends of libvirt-bin
    + Recommends qemu-kvm (>= 0.11.0-0ubuntu6)
    + Add versioned Conflicts/Replaces to libvirt0 for libvirt0-dbg,
      since we used to ship them as such
    + We call libxen-dev libxen3-dev, so change all references
    + Build-Depends on libxml2-utils
    + Build-Depends on open-iscsi-utils instead of open-iscsi due to
      LP: #414986
  - debian/postinst:
    + rename the libvirt group to libvirtd
    + add each admin user to the libvirtd group
  - debian/libvirt-bin.postrm: rename the libvirt group to libvirtd
  - debian/rules: add DEB_MAKE_CHECK_TARGET := check
  - debian/patches/900[0-7]: updated/refreshed for new paths in 0.7.2
  - debian/patches/series: don't apply 0002-qemu-disable-network.diff.patch
  - AppArmor integration:
    + debian/control: Build-Depends on libapparmor-dev and Suggests
      apparmor (>= 2.3+1289-0ubuntu14)
    + debian/libvirt-bin.dirs: add /etc/apparmor.d/abstractions,
      /etc/apparmor.d/force-complain, /etc/apparmor.d/libvirt,
      /etc/cron.daily and /usr/share/apport/package-hooks
    + add debian/libvirt-bin.cron.daily (LP: #438165)
    + add debian/libvirt-bin.apport
    + debian/libvirt-bin.install: install apparmor profiles, abstractions
      and apport hook
    + debian/postinst: reload apparmor profiles
    + debian/libvirt-bin.postrm: remove apparmor symlinks on purge
    + debian/libvirt-bin.preinst: added to force complain on certain
      upgrades
    + debian/README.Debian: add AppArmor section based on the upstream
      documentation
    + debian/rules: use --with-apparmor and copy apparmor and apport hook to
      debian/tmp
  - Dropped the following patches now included upstream:
    + 0005-Close-logfile-fd-after-spawning-qemu.patch
    + 9090-reenable-nonfile-labels.patch
    + 9091-apparmor.patch
    + 9092-apparmor-autoreconf.patch
* AppArmor integration updates:
  - debian/apparmor/usr.sbin.libvirtd: allow libvirtd access to
    /usr/lib/libvirt/* (LP: #480478)
  - debian/apparmor/libvirt-qemu: allow guests access to
    /etc/pki/libvirt-vnc/** (LP: #484562)
  - debian/libvirt-bin.postinst: 0.7.2 moved /usr/bin/virt-aa-helper to
    /usr/lib/libvirt, so the profile changed from usr.bin.virt-aa-helper
    to usr.lib.libvirt.virt-aa-helper and needs to be migrated. If the user
    made no changes to the old profile, remove it, otherwise, update the
    paths, preserving the shipped usr.lib.libvirt.virt-aa-helper
  - update to 0.7.4 version of the sVirt AppArmor driver (can be dropped in
    0.7.4):
    + debian/patches/9008-apparmor-caps-mockup.patch
    + debian/patches/9009-apparmor-lp453335.patch
    + debian/patches/9010-apparmor-lp460271.patch
    + debian/patches/9011-apparmor-code-cleanups.patch
  - add virt-aa-helper-test and examples/apparmor that were omitted from the
    upstream tarball (can be dropped in 0.7.5):
    + debian/patches/9012-apparmor-add-virt-aa-helper-test.patch
    + debian/patches/9013-apparmor-examples.patch
    + debian/rules: add post-patches target to make virt-aa-helper-test
      executable
* debian/patches/0005-Fix-SELinux-linking-issues.patch: updated to work
  when both apparmor and selinux are available. This patch should be
  dropped in 0.7.4.
* debian/patches/9007-default-config-test-case.patch: updated to not fail
  if building in a deep directory
* debian/patches/9014-event-fuzz.patch: add a little fuzz to not be quite
  so precise with expected expiry time. Fixes FTBFS with HZ=100 kernels.
  Can be dropped in 0.7.5.
* debian/patches/9015-hal-startup-failure-is-nonfatal.patch: disable hal
  driver if hald is not running instead of dying. Can be dropped in
  0.7.4.
* debian/control: temporarily remove Build-Depends on libcap-ng-dev, which
  isn't available in Ubuntu main yet
* revert change to new source format 3.0 (quilt) since Launchpad can't
  handle it yet (see LP: #293106)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * secret_conf.c: internal <secret> XML handling
 
3
 *
 
4
 * Copyright (C) 2009 Red Hat, Inc.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 
19
 *
 
20
 * Red Hat Author: Miloslav Trmač <mitr@redhat.com>
 
21
 */
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#include "internal.h"
 
26
#include "buf.h"
 
27
#include "datatypes.h"
 
28
#include "logging.h"
 
29
#include "memory.h"
 
30
#include "secret_conf.h"
 
31
#include "virterror_internal.h"
 
32
#include "util.h"
 
33
#include "xml.h"
 
34
#include "uuid.h"
 
35
 
 
36
#define VIR_FROM_THIS VIR_FROM_SECRET
 
37
 
 
38
VIR_ENUM_IMPL(virSecretUsageType, VIR_SECRET_USAGE_TYPE_VOLUME + 1, "none", "volume")
 
39
 
 
40
void
 
41
virSecretDefFree(virSecretDefPtr def)
 
42
{
 
43
    if (def == NULL)
 
44
        return;
 
45
 
 
46
    VIR_FREE(def->description);
 
47
    switch (def->usage_type) {
 
48
    case VIR_SECRET_USAGE_TYPE_NONE:
 
49
        break;
 
50
 
 
51
    case VIR_SECRET_USAGE_TYPE_VOLUME:
 
52
        VIR_FREE(def->usage.volume);
 
53
        break;
 
54
 
 
55
    default:
 
56
        VIR_ERROR(_("unexpected secret usage type %d"), def->usage_type);
 
57
        break;
 
58
    }
 
59
    VIR_FREE(def);
 
60
}
 
61
 
 
62
static int
 
63
virSecretDefParseUsage(virConnectPtr conn, xmlXPathContextPtr ctxt,
 
64
                       virSecretDefPtr def)
 
65
{
 
66
    char *type_str;
 
67
    int type;
 
68
 
 
69
    type_str = virXPathString(conn, "string(./usage/@type)", ctxt);
 
70
    if (type_str == NULL) {
 
71
        virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
 
72
                             _("unknown secret usage type"));
 
73
        return -1;
 
74
    }
 
75
    type = virSecretUsageTypeTypeFromString(type_str);
 
76
    if (type < 0) {
 
77
        virSecretReportError(conn, VIR_ERR_XML_ERROR,
 
78
                             _("unknown secret usage type %s"), type_str);
 
79
        VIR_FREE(type_str);
 
80
        return -1;
 
81
    }
 
82
    VIR_FREE(type_str);
 
83
    def->usage_type = type;
 
84
    switch (def->usage_type) {
 
85
    case VIR_SECRET_USAGE_TYPE_NONE:
 
86
        break;
 
87
 
 
88
    case VIR_SECRET_USAGE_TYPE_VOLUME:
 
89
        def->usage.volume = virXPathString(conn, "string(./usage/volume)",
 
90
                                           ctxt);
 
91
        if (!def->usage.volume) {
 
92
            virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
 
93
                                 _("volume usage specified, but volume path is missing"));
 
94
            return -1;
 
95
        }
 
96
        break;
 
97
 
 
98
    default:
 
99
        virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
 
100
                             _("unexpected secret usage type %d"),
 
101
                             def->usage_type);
 
102
        return -1;
 
103
    }
 
104
    return 0;
 
105
}
 
106
 
 
107
static virSecretDefPtr
 
108
secretXMLParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root)
 
109
{
 
110
    xmlXPathContextPtr ctxt = NULL;
 
111
    virSecretDefPtr def = NULL, ret = NULL;
 
112
    char *prop = NULL;
 
113
    char *uuidstr = NULL;
 
114
 
 
115
    if (!xmlStrEqual(root->name, BAD_CAST "secret")) {
 
116
        virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
 
117
                             _("incorrect root element"));
 
118
        goto cleanup;
 
119
    }
 
120
 
 
121
    ctxt = xmlXPathNewContext(xml);
 
122
    if (ctxt == NULL) {
 
123
        virReportOOMError(conn);
 
124
        goto cleanup;
 
125
    }
 
126
    ctxt->node = root;
 
127
 
 
128
    if (VIR_ALLOC(def) < 0) {
 
129
        virReportOOMError(conn);
 
130
        goto cleanup;
 
131
    }
 
132
 
 
133
    prop = virXPathString(conn, "string(./@ephemeral)", ctxt);
 
134
    if (prop != NULL) {
 
135
        if (STREQ(prop, "yes"))
 
136
            def->ephemeral = 1;
 
137
        else if (STREQ(prop, "no"))
 
138
            def->ephemeral = 0;
 
139
        else {
 
140
            virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
 
141
                                 _("invalid value of 'ephemeral'"));
 
142
            goto cleanup;
 
143
        }
 
144
        VIR_FREE(prop);
 
145
    }
 
146
 
 
147
    prop = virXPathString(conn, "string(./@private)", ctxt);
 
148
    if (prop != NULL) {
 
149
        if (STREQ(prop, "yes"))
 
150
            def->private = 1;
 
151
        else if (STREQ(prop, "no"))
 
152
            def->private = 0;
 
153
        else {
 
154
            virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
 
155
                                 _("invalid value of 'private'"));
 
156
            goto cleanup;
 
157
        }
 
158
        VIR_FREE(prop);
 
159
    }
 
160
 
 
161
    uuidstr = virXPathString(conn, "string(./uuid)", ctxt);
 
162
    if (!uuidstr) {
 
163
        if (virUUIDGenerate(def->uuid)) {
 
164
            virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
 
165
                                 "%s", _("Failed to generate UUID"));
 
166
            goto cleanup;
 
167
        }
 
168
    } else {
 
169
        if (virUUIDParse(uuidstr, def->uuid) < 0) {
 
170
            virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
 
171
                                 "%s", _("malformed uuid element"));
 
172
            goto cleanup;
 
173
        }
 
174
        VIR_FREE(uuidstr);
 
175
    }
 
176
 
 
177
    def->description = virXPathString(conn, "string(./description)", ctxt);
 
178
    if (virXPathNode(conn, "./usage", ctxt) != NULL
 
179
        && virSecretDefParseUsage(conn, ctxt, def) < 0)
 
180
        goto cleanup;
 
181
    ret = def;
 
182
    def = NULL;
 
183
 
 
184
 cleanup:
 
185
    VIR_FREE(prop);
 
186
    virSecretDefFree(def);
 
187
    xmlXPathFreeContext(ctxt);
 
188
    return ret;
 
189
}
 
190
 
 
191
/* Called from SAX on parsing errors in the XML. */
 
192
static void
 
193
catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
 
194
{
 
195
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
 
196
 
 
197
    if (ctxt) {
 
198
        virConnectPtr conn = ctxt->_private;
 
199
 
 
200
        if (virGetLastError() == NULL &&
 
201
            ctxt->lastError.level == XML_ERR_FATAL &&
 
202
            ctxt->lastError.message != NULL) {
 
203
            virSecretReportError(conn,  VIR_ERR_XML_DETAIL, _("at line %d: %s"),
 
204
                                 ctxt->lastError.line, ctxt->lastError.message);
 
205
        }
 
206
    }
 
207
}
 
208
 
 
209
static virSecretDefPtr
 
210
virSecretDefParse(virConnectPtr conn, const char *xmlStr, const char *filename)
 
211
{
 
212
    xmlParserCtxtPtr pctxt;
 
213
    xmlDocPtr xml = NULL;
 
214
    xmlNodePtr root;
 
215
    virSecretDefPtr ret = NULL;
 
216
 
 
217
    pctxt = xmlNewParserCtxt();
 
218
    if (pctxt == NULL || pctxt->sax == NULL)
 
219
        goto cleanup;
 
220
    pctxt->sax->error = catchXMLError;
 
221
    pctxt->_private = conn;
 
222
 
 
223
    if (filename != NULL)
 
224
        xml = xmlCtxtReadFile(pctxt, filename, NULL,
 
225
                              XML_PARSE_NOENT | XML_PARSE_NONET |
 
226
                              XML_PARSE_NOWARNING);
 
227
    else
 
228
        xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, "secret.xml", NULL,
 
229
                             XML_PARSE_NOENT | XML_PARSE_NONET |
 
230
                             XML_PARSE_NOWARNING);
 
231
    if (xml == NULL) {
 
232
        if (conn->err.code == VIR_ERR_NONE)
 
233
            virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s",
 
234
                                 _("failed to parse xml document"));
 
235
        goto cleanup;
 
236
    }
 
237
 
 
238
    root = xmlDocGetRootElement(xml);
 
239
    if (root == NULL) {
 
240
        virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
 
241
                             _("missing root element"));
 
242
        goto cleanup;
 
243
    }
 
244
 
 
245
    ret = secretXMLParseNode(conn, xml, root);
 
246
 
 
247
 cleanup:
 
248
    xmlFreeDoc(xml);
 
249
    xmlFreeParserCtxt(pctxt);
 
250
    return ret;
 
251
}
 
252
 
 
253
virSecretDefPtr
 
254
virSecretDefParseString(virConnectPtr conn, const char *xmlStr)
 
255
{
 
256
    return virSecretDefParse(conn, xmlStr, NULL);
 
257
}
 
258
 
 
259
virSecretDefPtr
 
260
virSecretDefParseFile(virConnectPtr conn, const char *filename)
 
261
{
 
262
    return virSecretDefParse(conn, NULL, filename);
 
263
}
 
264
 
 
265
static int
 
266
virSecretDefFormatUsage(virConnectPtr conn, virBufferPtr buf,
 
267
                        const virSecretDefPtr def)
 
268
{
 
269
    const char *type;
 
270
 
 
271
    type = virSecretUsageTypeTypeToString(def->usage_type);
 
272
    if (type == NULL) {
 
273
        virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
 
274
                             _("unexpected secret usage type %d"),
 
275
                             def->usage_type);
 
276
        return -1;
 
277
    }
 
278
    virBufferVSprintf(buf, "  <usage type='%s'>\n", type);
 
279
    switch (def->usage_type) {
 
280
    case VIR_SECRET_USAGE_TYPE_NONE:
 
281
        break;
 
282
 
 
283
    case VIR_SECRET_USAGE_TYPE_VOLUME:
 
284
        if (def->usage.volume != NULL)
 
285
            virBufferEscapeString(buf, "    <volume>%s</volume>\n",
 
286
                                  def->usage.volume);
 
287
        break;
 
288
 
 
289
    default:
 
290
        virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
 
291
                             _("unexpected secret usage type %d"),
 
292
                             def->usage_type);
 
293
        return -1;
 
294
    }
 
295
    virBufferAddLit(buf, "  </usage>\n");
 
296
 
 
297
    return 0;
 
298
}
 
299
 
 
300
char *
 
301
virSecretDefFormat(virConnectPtr conn, const virSecretDefPtr def)
 
302
{
 
303
    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
304
    unsigned char *uuid;
 
305
    char uuidstr[VIR_UUID_STRING_BUFLEN];
 
306
    char *tmp;
 
307
 
 
308
    virBufferVSprintf(&buf, "<secret ephemeral='%s' private='%s'>\n",
 
309
                      def->ephemeral ? "yes" : "no",
 
310
                      def->private ? "yes" : "no");
 
311
 
 
312
    uuid = def->uuid;
 
313
    virUUIDFormat(uuid, uuidstr);
 
314
    virBufferEscapeString(&buf, "  <uuid>%s</uuid>\n", uuidstr);
 
315
    if (def->description != NULL)
 
316
        virBufferEscapeString(&buf, "  <description>%s</description>\n",
 
317
                              def->description);
 
318
    if (def->usage_type != VIR_SECRET_USAGE_TYPE_NONE &&
 
319
        virSecretDefFormatUsage(conn, &buf, def) < 0)
 
320
        goto error;
 
321
    virBufferAddLit(&buf, "</secret>\n");
 
322
 
 
323
    if (virBufferError(&buf))
 
324
        goto no_memory;
 
325
 
 
326
    return virBufferContentAndReset(&buf);
 
327
 
 
328
 no_memory:
 
329
    virReportOOMError(conn);
 
330
 error:
 
331
    tmp = virBufferContentAndReset(&buf);
 
332
    VIR_FREE(tmp);
 
333
    return NULL;
 
334
}