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/>.
28 #include "datatypes.h"
32 #include "secret_conf.h"
33 #include "virsecretobj.h"
34 #include "secret_driver.h"
35 #include "virthread.h"
38 #include "viridentity.h"
39 #include "virpidfile.h"
40 #include "configmake.h"
41 #include "viraccessapicheck.h"
42 #include "secret_event.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 */
61 virSecretObjList
*secrets
;
65 /* pid file FD, ensures two copies of the driver can't use the same root */
68 /* Immutable pointer, self-locking APIs */
69 virObjectEventState
*secretEventState
;
71 /* Immutable pointer, self-locking APIs */
72 virInhibitor
*inhibitor
;
75 static virSecretDriverState
*driver
;
78 secretObjFromSecret(virSecretPtr secret
)
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
);
93 /* Driver functions */
96 secretConnectNumOfSecrets(virConnectPtr conn
)
98 if (virConnectNumOfSecretsEnsureACL(conn
) < 0)
101 return virSecretObjListNumOfSecrets(driver
->secrets
,
102 virConnectNumOfSecretsCheckACL
,
108 secretConnectListSecrets(virConnectPtr conn
,
112 memset(uuids
, 0, maxuuids
* sizeof(*uuids
));
114 if (virConnectListSecretsEnsureACL(conn
) < 0)
117 return virSecretObjListGetUUIDs(driver
->secrets
, uuids
, maxuuids
,
118 virConnectListSecretsCheckACL
, conn
);
123 secretConnectListAllSecrets(virConnectPtr conn
,
124 virSecretPtr
**secrets
,
127 virCheckFlags(VIR_CONNECT_LIST_SECRETS_FILTERS_ALL
, -1);
129 if (virConnectListAllSecretsEnsureACL(conn
) < 0)
132 return virSecretObjListExport(conn
, driver
->secrets
, secrets
,
133 virConnectListAllSecretsCheckACL
,
139 secretLookupByUUID(virConnectPtr conn
,
140 const unsigned char *uuid
)
142 virSecretPtr ret
= NULL
;
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
);
154 def
= virSecretObjGetDef(obj
);
155 if (virSecretLookupByUUIDEnsureACL(conn
, def
) < 0)
158 ret
= virGetSecret(conn
,
164 virSecretObjEndAPI(&obj
);
170 secretLookupByUsage(virConnectPtr conn
,
174 virSecretPtr ret
= NULL
;
178 if (!(obj
= virSecretObjListFindByUsage(driver
->secrets
,
179 usageType
, usageID
))) {
180 virReportError(VIR_ERR_NO_SECRET
,
181 _("no secret with matching usage '%1$s'"), usageID
);
185 def
= virSecretObjGetDef(obj
);
186 if (virSecretLookupByUsageEnsureACL(conn
, def
) < 0)
189 ret
= virGetSecret(conn
,
195 virSecretObjEndAPI(&obj
);
201 secretDefineXML(virConnectPtr conn
,
205 virSecretPtr ret
= NULL
;
206 virSecretObj
*obj
= NULL
;
207 virSecretDef
*objDef
;
208 virSecretDef
*backup
= NULL
;
210 virObjectEvent
*event
= NULL
;
212 virCheckFlags(VIR_SECRET_DEFINE_VALIDATE
, NULL
);
214 if (!(def
= virSecretDefParse(xml
, NULL
, flags
)))
217 if (virSecretDefineXMLEnsureACL(conn
, def
) < 0)
220 if (!(obj
= virSecretObjListAdd(driver
->secrets
, &def
,
221 driver
->configDir
, &backup
)))
223 objDef
= virSecretObjGetDef(obj
);
225 if (!objDef
->isephemeral
) {
226 if (backup
&& backup
->isephemeral
) {
227 if (virSecretObjSaveData(obj
) < 0)
231 if (virSecretObjSaveConfig(obj
) < 0) {
232 if (backup
&& backup
->isephemeral
) {
233 /* Undo the virSecretObjSaveData() above; ignore errors */
234 virSecretObjDeleteData(obj
);
238 } else if (backup
&& !backup
->isephemeral
) {
239 if (virSecretObjDeleteConfig(obj
) < 0)
242 virSecretObjDeleteData(obj
);
244 /* Saved successfully - drop old values */
245 virSecretDefFree(backup
);
247 event
= virSecretEventLifecycleNew(objDef
->uuid
,
250 VIR_SECRET_EVENT_DEFINED
,
253 ret
= virGetSecret(conn
,
258 if (objDef
->isephemeral
)
259 virInhibitorHold(driver
->inhibitor
);
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. */
267 virSecretObjSetDef(obj
, backup
);
268 def
= g_steal_pointer(&objDef
);
270 virSecretObjListRemove(driver
->secrets
, obj
);
271 g_clear_pointer(&obj
, virObjectUnref
);
275 virSecretDefFree(def
);
276 virSecretObjEndAPI(&obj
);
279 virObjectEventStateQueue(driver
->secretEventState
, event
);
286 secretGetXMLDesc(virSecretPtr secret
,
293 virCheckFlags(0, NULL
);
295 if (!(obj
= secretObjFromSecret(secret
)))
298 def
= virSecretObjGetDef(obj
);
299 if (virSecretGetXMLDescEnsureACL(secret
->conn
, def
) < 0)
302 ret
= virSecretDefFormat(def
);
305 virSecretObjEndAPI(&obj
);
312 secretSetValue(virSecretPtr secret
,
313 const unsigned char *value
,
320 virObjectEvent
*event
= NULL
;
322 virCheckFlags(0, -1);
324 if (!(obj
= secretObjFromSecret(secret
)))
327 def
= virSecretObjGetDef(obj
);
328 if (virSecretSetValueEnsureACL(secret
->conn
, def
) < 0)
331 if (virSecretObjSetValue(obj
, value
, value_size
) < 0)
334 event
= virSecretEventValueChangedNew(def
->uuid
,
340 virSecretObjEndAPI(&obj
);
341 virObjectEventStateQueue(driver
->secretEventState
, event
);
347 static unsigned char *
348 secretGetValue(virSecretPtr secret
,
352 unsigned char *ret
= NULL
;
356 virCheckFlags(0, NULL
);
358 if (!(obj
= secretObjFromSecret(secret
)))
361 def
= virSecretObjGetDef(obj
);
362 if (virSecretGetValueEnsureACL(secret
->conn
, def
) < 0)
366 * For historical compat we want to deny access to
367 * private secrets, even if no ACL driver is
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
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();
386 virReportError(VIR_ERR_INVALID_SECRET
, "%s",
387 _("secret is private"));
392 if (!(ret
= virSecretObjGetValue(obj
)))
395 *value_size
= virSecretObjGetValueSize(obj
);
398 virSecretObjEndAPI(&obj
);
405 secretUndefine(virSecretPtr secret
)
410 virObjectEvent
*event
= NULL
;
412 if (!(obj
= secretObjFromSecret(secret
)))
415 def
= virSecretObjGetDef(obj
);
416 if (virSecretUndefineEnsureACL(secret
->conn
, def
) < 0)
419 if (virSecretObjDeleteConfig(obj
) < 0)
422 event
= virSecretEventLifecycleNew(def
->uuid
,
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
);
439 virSecretObjEndAPI(&obj
);
441 virObjectEventStateQueue(driver
->secretEventState
, event
);
448 secretStateCleanupLocked(void)
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
);
469 secretStateCleanup(void)
471 VIR_LOCK_GUARD lock
= virLockGuardLock(&mutex
);
473 return secretStateCleanupLocked();
477 static virDrvStateInitResult
478 secretStateInitialize(bool privileged
,
480 bool monolithic G_GNUC_UNUSED
,
481 virStateInhibitCallback callback
,
484 VIR_LOCK_GUARD lock
= virLockGuardLock(&mutex
);
486 driver
= g_new0(virSecretDriverState
, 1);
489 driver
->secretEventState
= virObjectEventStateNew();
490 driver
->privileged
= privileged
;
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
);
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'"),
516 if (g_mkdir_with_parents(driver
->stateDir
, S_IRWXU
) < 0) {
517 virReportSystemError(errno
, _("cannot create state directory '%1$s'"),
522 driver
->inhibitor
= virInhibitorNew(
523 VIR_INHIBITOR_WHAT_NONE
,
525 _("Ephemeral secrets are loaded"),
526 VIR_INHIBITOR_MODE_DELAY
,
530 if ((driver
->lockFD
=
531 virPidFileAcquire(driver
->stateDir
, "driver", getpid())) < 0)
534 if (!(driver
->secrets
= virSecretObjListNew()))
537 if (virSecretLoadAllConfigs(driver
->secrets
, driver
->configDir
) < 0)
540 return VIR_DRV_STATE_INIT_COMPLETE
;
543 secretStateCleanupLocked();
544 return VIR_DRV_STATE_INIT_ERROR
;
549 secretStateReload(void)
551 VIR_LOCK_GUARD lock
= virLockGuardLock(&mutex
);
556 ignore_value(virSecretLoadAllConfigs(driver
->secrets
, driver
->configDir
));
562 static virDrvOpenStatus
563 secretConnectOpen(virConnectPtr conn
,
564 virConnectAuthPtr auth G_GNUC_UNUSED
,
565 virConf
*conf G_GNUC_UNUSED
,
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");
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
;
594 if (!virConnectValidateURIPath(conn
->uri
->path
,
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
);
627 static int secretConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED
)
629 /* Trivially secure, since always inside the daemon */
634 static int secretConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED
)
636 /* Not encrypted, but remote driver takes care of that */
641 static int secretConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED
)
648 secretConnectSecretEventRegisterAny(virConnectPtr conn
,
651 virConnectSecretEventGenericCallback callback
,
653 virFreeCallback freecb
)
657 if (virConnectSecretEventRegisterAnyEnsureACL(conn
) < 0)
660 if (virSecretEventStateRegisterID(conn
, driver
->secretEventState
,
661 secret
, eventID
, callback
,
662 opaque
, freecb
, &callbackID
) < 0)
670 secretConnectSecretEventDeregisterAny(virConnectPtr conn
,
673 if (virConnectSecretEventDeregisterAnyEnsureACL(conn
) < 0)
676 if (virObjectEventStateDeregisterID(conn
,
677 driver
->secretEventState
,
678 callbackID
, true) < 0)
685 static virSecretDriver secretDriver
= {
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
= {
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
= {
714 .uriSchemes
= (const char *[]){ "secret", NULL
},
716 .hypervisorDriver
= &secretHypervisorDriver
,
717 .secretDriver
= &secretDriver
,
721 static virStateDriver stateDriver
= {
723 .stateInitialize
= secretStateInitialize
,
724 .stateCleanup
= secretStateCleanup
,
725 .stateReload
= secretStateReload
,
732 if (virRegisterConnectDriver(&secretConnectDriver
, false) < 0)
734 if (virSetSharedSecretDriver(&secretDriver
) < 0)
736 if (virRegisterStateDriver(&stateDriver
) < 0)