node_device_udev: add error reporting to udevProcessCCWGroup
[libvirt.git] / src / secret / secret_driver.c
blob04c3ca49f18d1740dba6d2491a6f1b4d8f61b289
1 /*
2 * secret_driver.c: local driver for secret manipulation API
4 * Copyright (C) 2009-2016 Red Hat, Inc.
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
27 #include "internal.h"
28 #include "datatypes.h"
29 #include "driver.h"
30 #include "virlog.h"
31 #include "viralloc.h"
32 #include "secret_conf.h"
33 #include "virsecretobj.h"
34 #include "secret_driver.h"
35 #include "virthread.h"
36 #include "viruuid.h"
37 #include "virerror.h"
38 #include "viridentity.h"
39 #include "virpidfile.h"
40 #include "configmake.h"
41 #include "viraccessapicheck.h"
42 #include "secret_event.h"
43 #include "virutil.h"
44 #include "virinhibitor.h"
46 #define VIR_FROM_THIS VIR_FROM_SECRET
48 VIR_LOG_INIT("secret.secret_driver");
50 enum { SECRET_MAX_XML_FILE = 10*1024*1024 };
52 /* Internal driver state */
54 static virMutex mutex = VIR_MUTEX_INITIALIZER;
56 typedef struct _virSecretDriverState virSecretDriverState;
57 struct _virSecretDriverState {
58 bool privileged; /* readonly */
59 char *embeddedRoot; /* readonly */
60 int embeddedRefs;
61 virSecretObjList *secrets;
62 char *stateDir;
63 char *configDir;
65 /* pid file FD, ensures two copies of the driver can't use the same root */
66 int lockFD;
68 /* Immutable pointer, self-locking APIs */
69 virObjectEventState *secretEventState;
71 /* Immutable pointer, self-locking APIs */
72 virInhibitor *inhibitor;
75 static virSecretDriverState *driver;
77 static virSecretObj *
78 secretObjFromSecret(virSecretPtr secret)
80 virSecretObj *obj;
81 char uuidstr[VIR_UUID_STRING_BUFLEN];
83 virUUIDFormat(secret->uuid, uuidstr);
84 if (!(obj = virSecretObjListFindByUUID(driver->secrets, uuidstr))) {
85 virReportError(VIR_ERR_NO_SECRET,
86 _("no secret with matching uuid '%1$s'"), uuidstr);
87 return NULL;
89 return obj;
93 /* Driver functions */
95 static int
96 secretConnectNumOfSecrets(virConnectPtr conn)
98 if (virConnectNumOfSecretsEnsureACL(conn) < 0)
99 return -1;
101 return virSecretObjListNumOfSecrets(driver->secrets,
102 virConnectNumOfSecretsCheckACL,
103 conn);
107 static int
108 secretConnectListSecrets(virConnectPtr conn,
109 char **uuids,
110 int maxuuids)
112 memset(uuids, 0, maxuuids * sizeof(*uuids));
114 if (virConnectListSecretsEnsureACL(conn) < 0)
115 return -1;
117 return virSecretObjListGetUUIDs(driver->secrets, uuids, maxuuids,
118 virConnectListSecretsCheckACL, conn);
122 static int
123 secretConnectListAllSecrets(virConnectPtr conn,
124 virSecretPtr **secrets,
125 unsigned int flags)
127 virCheckFlags(VIR_CONNECT_LIST_SECRETS_FILTERS_ALL, -1);
129 if (virConnectListAllSecretsEnsureACL(conn) < 0)
130 return -1;
132 return virSecretObjListExport(conn, driver->secrets, secrets,
133 virConnectListAllSecretsCheckACL,
134 flags);
138 static virSecretPtr
139 secretLookupByUUID(virConnectPtr conn,
140 const unsigned char *uuid)
142 virSecretPtr ret = NULL;
143 virSecretObj *obj;
144 virSecretDef *def;
145 char uuidstr[VIR_UUID_STRING_BUFLEN];
147 virUUIDFormat(uuid, uuidstr);
148 if (!(obj = virSecretObjListFindByUUID(driver->secrets, uuidstr))) {
149 virReportError(VIR_ERR_NO_SECRET,
150 _("no secret with matching uuid '%1$s'"), uuidstr);
151 goto cleanup;
154 def = virSecretObjGetDef(obj);
155 if (virSecretLookupByUUIDEnsureACL(conn, def) < 0)
156 goto cleanup;
158 ret = virGetSecret(conn,
159 def->uuid,
160 def->usage_type,
161 def->usage_id);
163 cleanup:
164 virSecretObjEndAPI(&obj);
165 return ret;
169 static virSecretPtr
170 secretLookupByUsage(virConnectPtr conn,
171 int usageType,
172 const char *usageID)
174 virSecretPtr ret = NULL;
175 virSecretObj *obj;
176 virSecretDef *def;
178 if (!(obj = virSecretObjListFindByUsage(driver->secrets,
179 usageType, usageID))) {
180 virReportError(VIR_ERR_NO_SECRET,
181 _("no secret with matching usage '%1$s'"), usageID);
182 goto cleanup;
185 def = virSecretObjGetDef(obj);
186 if (virSecretLookupByUsageEnsureACL(conn, def) < 0)
187 goto cleanup;
189 ret = virGetSecret(conn,
190 def->uuid,
191 def->usage_type,
192 def->usage_id);
194 cleanup:
195 virSecretObjEndAPI(&obj);
196 return ret;
200 static virSecretPtr
201 secretDefineXML(virConnectPtr conn,
202 const char *xml,
203 unsigned int flags)
205 virSecretPtr ret = NULL;
206 virSecretObj *obj = NULL;
207 virSecretDef *objDef;
208 virSecretDef *backup = NULL;
209 virSecretDef *def;
210 virObjectEvent *event = NULL;
212 virCheckFlags(VIR_SECRET_DEFINE_VALIDATE, NULL);
214 if (!(def = virSecretDefParse(xml, NULL, flags)))
215 return NULL;
217 if (virSecretDefineXMLEnsureACL(conn, def) < 0)
218 goto cleanup;
220 if (!(obj = virSecretObjListAdd(driver->secrets, &def,
221 driver->configDir, &backup)))
222 goto cleanup;
223 objDef = virSecretObjGetDef(obj);
225 if (!objDef->isephemeral) {
226 if (backup && backup->isephemeral) {
227 if (virSecretObjSaveData(obj) < 0)
228 goto restore_backup;
231 if (virSecretObjSaveConfig(obj) < 0) {
232 if (backup && backup->isephemeral) {
233 /* Undo the virSecretObjSaveData() above; ignore errors */
234 virSecretObjDeleteData(obj);
236 goto restore_backup;
238 } else if (backup && !backup->isephemeral) {
239 if (virSecretObjDeleteConfig(obj) < 0)
240 goto restore_backup;
242 virSecretObjDeleteData(obj);
244 /* Saved successfully - drop old values */
245 virSecretDefFree(backup);
247 event = virSecretEventLifecycleNew(objDef->uuid,
248 objDef->usage_type,
249 objDef->usage_id,
250 VIR_SECRET_EVENT_DEFINED,
253 ret = virGetSecret(conn,
254 objDef->uuid,
255 objDef->usage_type,
256 objDef->usage_id);
258 if (objDef->isephemeral)
259 virInhibitorHold(driver->inhibitor);
261 goto cleanup;
263 restore_backup:
264 /* If we have a backup, then secret was defined before, so just restore
265 * the backup; otherwise, this is a new secret, thus remove it. */
266 if (backup) {
267 virSecretObjSetDef(obj, backup);
268 def = g_steal_pointer(&objDef);
269 } else {
270 virSecretObjListRemove(driver->secrets, obj);
271 g_clear_pointer(&obj, virObjectUnref);
274 cleanup:
275 virSecretDefFree(def);
276 virSecretObjEndAPI(&obj);
279 virObjectEventStateQueue(driver->secretEventState, event);
281 return ret;
285 static char *
286 secretGetXMLDesc(virSecretPtr secret,
287 unsigned int flags)
289 char *ret = NULL;
290 virSecretObj *obj;
291 virSecretDef *def;
293 virCheckFlags(0, NULL);
295 if (!(obj = secretObjFromSecret(secret)))
296 goto cleanup;
298 def = virSecretObjGetDef(obj);
299 if (virSecretGetXMLDescEnsureACL(secret->conn, def) < 0)
300 goto cleanup;
302 ret = virSecretDefFormat(def);
304 cleanup:
305 virSecretObjEndAPI(&obj);
307 return ret;
311 static int
312 secretSetValue(virSecretPtr secret,
313 const unsigned char *value,
314 size_t value_size,
315 unsigned int flags)
317 int ret = -1;
318 virSecretObj *obj;
319 virSecretDef *def;
320 virObjectEvent *event = NULL;
322 virCheckFlags(0, -1);
324 if (!(obj = secretObjFromSecret(secret)))
325 goto cleanup;
327 def = virSecretObjGetDef(obj);
328 if (virSecretSetValueEnsureACL(secret->conn, def) < 0)
329 goto cleanup;
331 if (virSecretObjSetValue(obj, value, value_size) < 0)
332 goto cleanup;
334 event = virSecretEventValueChangedNew(def->uuid,
335 def->usage_type,
336 def->usage_id);
337 ret = 0;
339 cleanup:
340 virSecretObjEndAPI(&obj);
341 virObjectEventStateQueue(driver->secretEventState, event);
343 return ret;
347 static unsigned char *
348 secretGetValue(virSecretPtr secret,
349 size_t *value_size,
350 unsigned int flags)
352 unsigned char *ret = NULL;
353 virSecretObj *obj;
354 virSecretDef *def;
356 virCheckFlags(0, NULL);
358 if (!(obj = secretObjFromSecret(secret)))
359 goto cleanup;
361 def = virSecretObjGetDef(obj);
362 if (virSecretGetValueEnsureACL(secret->conn, def) < 0)
363 goto cleanup;
366 * For historical compat we want to deny access to
367 * private secrets, even if no ACL driver is
368 * present.
370 * We need to validate the identity requesting
371 * the secret value is running as the same user
372 * credentials as this driver.
374 * ie a non-root libvirt client should not be
375 * able to request the value from privileged
376 * libvirt driver.
378 * To apply restrictions to processes running under
379 * the same user account is out of scope.
381 if (def->isprivate) {
382 int rv = virIdentityIsCurrentElevated();
383 if (rv < 0)
384 goto cleanup;
385 if (rv == 0) {
386 virReportError(VIR_ERR_INVALID_SECRET, "%s",
387 _("secret is private"));
388 goto cleanup;
392 if (!(ret = virSecretObjGetValue(obj)))
393 goto cleanup;
395 *value_size = virSecretObjGetValueSize(obj);
397 cleanup:
398 virSecretObjEndAPI(&obj);
400 return ret;
404 static int
405 secretUndefine(virSecretPtr secret)
407 int ret = -1;
408 virSecretObj *obj;
409 virSecretDef *def;
410 virObjectEvent *event = NULL;
412 if (!(obj = secretObjFromSecret(secret)))
413 goto cleanup;
415 def = virSecretObjGetDef(obj);
416 if (virSecretUndefineEnsureACL(secret->conn, def) < 0)
417 goto cleanup;
419 if (virSecretObjDeleteConfig(obj) < 0)
420 goto cleanup;
422 event = virSecretEventLifecycleNew(def->uuid,
423 def->usage_type,
424 def->usage_id,
425 VIR_SECRET_EVENT_UNDEFINED,
428 if (def->isephemeral)
429 virInhibitorRelease(driver->inhibitor);
431 virSecretObjDeleteData(obj);
433 virSecretObjListRemove(driver->secrets, obj);
434 g_clear_pointer(&obj, virObjectUnref);
436 ret = 0;
438 cleanup:
439 virSecretObjEndAPI(&obj);
441 virObjectEventStateQueue(driver->secretEventState, event);
443 return ret;
447 static int
448 secretStateCleanupLocked(void)
450 if (!driver)
451 return -1;
453 virObjectUnref(driver->secrets);
454 VIR_FREE(driver->configDir);
456 virObjectUnref(driver->secretEventState);
457 virInhibitorFree(driver->inhibitor);
459 if (driver->lockFD != -1)
460 virPidFileRelease(driver->stateDir, "driver", driver->lockFD);
462 VIR_FREE(driver->stateDir);
463 VIR_FREE(driver);
465 return 0;
468 static int
469 secretStateCleanup(void)
471 VIR_LOCK_GUARD lock = virLockGuardLock(&mutex);
473 return secretStateCleanupLocked();
477 static virDrvStateInitResult
478 secretStateInitialize(bool privileged,
479 const char *root,
480 bool monolithic G_GNUC_UNUSED,
481 virStateInhibitCallback callback,
482 void *opaque)
484 VIR_LOCK_GUARD lock = virLockGuardLock(&mutex);
486 driver = g_new0(virSecretDriverState, 1);
488 driver->lockFD = -1;
489 driver->secretEventState = virObjectEventStateNew();
490 driver->privileged = privileged;
492 if (root) {
493 driver->embeddedRoot = g_strdup(root);
494 driver->configDir = g_strdup_printf("%s/etc/secrets", root);
495 driver->stateDir = g_strdup_printf("%s/run/secrets", root);
496 } else if (privileged) {
497 driver->configDir = g_strdup_printf("%s/libvirt/secrets", SYSCONFDIR);
498 driver->stateDir = g_strdup_printf("%s/libvirt/secrets", RUNSTATEDIR);
499 } else {
500 g_autofree char *rundir = NULL;
501 g_autofree char *cfgdir = NULL;
503 cfgdir = virGetUserConfigDirectory();
504 driver->configDir = g_strdup_printf("%s/secrets/", cfgdir);
506 rundir = virGetUserRuntimeDirectory();
507 driver->stateDir = g_strdup_printf("%s/secrets/run", rundir);
510 if (g_mkdir_with_parents(driver->configDir, S_IRWXU) < 0) {
511 virReportSystemError(errno, _("cannot create config directory '%1$s'"),
512 driver->configDir);
513 goto error;
516 if (g_mkdir_with_parents(driver->stateDir, S_IRWXU) < 0) {
517 virReportSystemError(errno, _("cannot create state directory '%1$s'"),
518 driver->stateDir);
519 goto error;
522 driver->inhibitor = virInhibitorNew(
523 VIR_INHIBITOR_WHAT_NONE,
524 _("Libvirt Secret"),
525 _("Ephemeral secrets are loaded"),
526 VIR_INHIBITOR_MODE_DELAY,
527 callback,
528 opaque);
530 if ((driver->lockFD =
531 virPidFileAcquire(driver->stateDir, "driver", getpid())) < 0)
532 goto error;
534 if (!(driver->secrets = virSecretObjListNew()))
535 goto error;
537 if (virSecretLoadAllConfigs(driver->secrets, driver->configDir) < 0)
538 goto error;
540 return VIR_DRV_STATE_INIT_COMPLETE;
542 error:
543 secretStateCleanupLocked();
544 return VIR_DRV_STATE_INIT_ERROR;
548 static int
549 secretStateReload(void)
551 VIR_LOCK_GUARD lock = virLockGuardLock(&mutex);
553 if (!driver)
554 return -1;
556 ignore_value(virSecretLoadAllConfigs(driver->secrets, driver->configDir));
558 return 0;
562 static virDrvOpenStatus
563 secretConnectOpen(virConnectPtr conn,
564 virConnectAuthPtr auth G_GNUC_UNUSED,
565 virConf *conf G_GNUC_UNUSED,
566 unsigned int flags)
568 virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
570 if (driver == NULL) {
571 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
572 _("secret state driver is not active"));
573 return VIR_DRV_OPEN_ERROR;
576 if (driver->embeddedRoot) {
577 const char *root = virURIGetParam(conn->uri, "root");
578 if (!root)
579 return VIR_DRV_OPEN_ERROR;
581 if (STRNEQ(conn->uri->path, "/embed")) {
582 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
583 _("URI must be secret:///embed"));
584 return VIR_DRV_OPEN_ERROR;
587 if (STRNEQ(root, driver->embeddedRoot)) {
588 virReportError(VIR_ERR_INTERNAL_ERROR,
589 _("Cannot open embedded driver at path '%1$s', already open with path '%2$s'"),
590 root, driver->embeddedRoot);
591 return VIR_DRV_OPEN_ERROR;
593 } else {
594 if (!virConnectValidateURIPath(conn->uri->path,
595 "secret",
596 driver->privileged))
597 return VIR_DRV_OPEN_ERROR;
600 if (virConnectOpenEnsureACL(conn) < 0)
601 return VIR_DRV_OPEN_ERROR;
603 if (driver->embeddedRoot) {
604 VIR_WITH_MUTEX_LOCK_GUARD(&mutex) {
605 if (driver->embeddedRefs == 0)
606 virSetConnectSecret(conn);
607 driver->embeddedRefs++;
611 return VIR_DRV_OPEN_SUCCESS;
614 static int secretConnectClose(virConnectPtr conn G_GNUC_UNUSED)
616 VIR_LOCK_GUARD lock = virLockGuardLock(&mutex);
618 if (driver->embeddedRoot) {
619 driver->embeddedRefs--;
620 if (driver->embeddedRefs == 0)
621 virSetConnectSecret(NULL);
623 return 0;
627 static int secretConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED)
629 /* Trivially secure, since always inside the daemon */
630 return 1;
634 static int secretConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED)
636 /* Not encrypted, but remote driver takes care of that */
637 return 0;
641 static int secretConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED)
643 return 1;
647 static int
648 secretConnectSecretEventRegisterAny(virConnectPtr conn,
649 virSecretPtr secret,
650 int eventID,
651 virConnectSecretEventGenericCallback callback,
652 void *opaque,
653 virFreeCallback freecb)
655 int callbackID = -1;
657 if (virConnectSecretEventRegisterAnyEnsureACL(conn) < 0)
658 return -1;
660 if (virSecretEventStateRegisterID(conn, driver->secretEventState,
661 secret, eventID, callback,
662 opaque, freecb, &callbackID) < 0)
663 callbackID = -1;
665 return callbackID;
669 static int
670 secretConnectSecretEventDeregisterAny(virConnectPtr conn,
671 int callbackID)
673 if (virConnectSecretEventDeregisterAnyEnsureACL(conn) < 0)
674 return -1;
676 if (virObjectEventStateDeregisterID(conn,
677 driver->secretEventState,
678 callbackID, true) < 0)
679 return -1;
681 return 0;
685 static virSecretDriver secretDriver = {
686 .name = "secret",
687 .connectNumOfSecrets = secretConnectNumOfSecrets, /* 0.7.1 */
688 .connectListSecrets = secretConnectListSecrets, /* 0.7.1 */
689 .connectListAllSecrets = secretConnectListAllSecrets, /* 0.10.2 */
690 .secretLookupByUUID = secretLookupByUUID, /* 0.7.1 */
691 .secretLookupByUsage = secretLookupByUsage, /* 0.7.1 */
692 .secretDefineXML = secretDefineXML, /* 0.7.1 */
693 .secretGetXMLDesc = secretGetXMLDesc, /* 0.7.1 */
694 .secretSetValue = secretSetValue, /* 0.7.1 */
695 .secretGetValue = secretGetValue, /* 0.7.1 */
696 .secretUndefine = secretUndefine, /* 0.7.1 */
697 .connectSecretEventRegisterAny = secretConnectSecretEventRegisterAny, /* 3.0.0 */
698 .connectSecretEventDeregisterAny = secretConnectSecretEventDeregisterAny, /* 3.0.0 */
702 static virHypervisorDriver secretHypervisorDriver = {
703 .name = "secret",
704 .connectOpen = secretConnectOpen, /* 4.1.0 */
705 .connectClose = secretConnectClose, /* 4.1.0 */
706 .connectIsEncrypted = secretConnectIsEncrypted, /* 4.1.0 */
707 .connectIsSecure = secretConnectIsSecure, /* 4.1.0 */
708 .connectIsAlive = secretConnectIsAlive, /* 4.1.0 */
712 static virConnectDriver secretConnectDriver = {
713 .localOnly = true,
714 .uriSchemes = (const char *[]){ "secret", NULL },
715 .embeddable = true,
716 .hypervisorDriver = &secretHypervisorDriver,
717 .secretDriver = &secretDriver,
721 static virStateDriver stateDriver = {
722 .name = "secret",
723 .stateInitialize = secretStateInitialize,
724 .stateCleanup = secretStateCleanup,
725 .stateReload = secretStateReload,
730 secretRegister(void)
732 if (virRegisterConnectDriver(&secretConnectDriver, false) < 0)
733 return -1;
734 if (virSetSharedSecretDriver(&secretDriver) < 0)
735 return -1;
736 if (virRegisterStateDriver(&stateDriver) < 0)
737 return -1;
738 return 0;