diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 443a78e698..2ea950c5cd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2396,6 +2396,7 @@ virHostGetBootTime; # util/viridentity.h +virIdentityElevateCurrent; virIdentityEnsureSystemToken; virIdentityGetCurrent; virIdentityGetGroupName; @@ -2412,6 +2413,7 @@ virIdentityGetUserName; virIdentityGetX509DName; virIdentityNew; virIdentityNewCopy; +virIdentityRestoreHelper; virIdentitySetCurrent; virIdentitySetGroupName; virIdentitySetParameters; diff --git a/src/util/viridentity.c b/src/util/viridentity.c index 01edabf2d7..2e3fcc5add 100644 --- a/src/util/viridentity.c +++ b/src/util/viridentity.c @@ -154,6 +154,53 @@ int virIdentitySetCurrent(virIdentity *ident) } +/** + * virIdentityElevateCurrent: + * + * Set the new identity to be associated with this thread, + * to an elevated copy of the current identity. The old + * current identity is returned and should be released by + * the caller when no longer required. + * + * Returns the previous identity, or NULL on error + */ +virIdentity *virIdentityElevateCurrent(void) +{ + g_autoptr(virIdentity) ident = virIdentityGetCurrent(); + const char *token; + int rc; + + if (!ident) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No current identity to elevate")); + return NULL; + } + + if ((rc = virIdentityGetSystemToken(ident, &token)) < 0) + return NULL; + + if (rc == 0) { + g_autoptr(virIdentity) identel = virIdentityNewCopy(ident); + + if (virIdentitySetSystemToken(identel, systemToken) < 0) + return NULL; + + if (virIdentitySetCurrent(identel) < 0) + return NULL; + } + + return g_steal_pointer(&ident); +} + + +void virIdentityRestoreHelper(virIdentity **identptr) +{ + virIdentity *ident = *identptr; + + if (ident != NULL) + virIdentitySetCurrent(ident); +} + #define TOKEN_BYTES 16 #define TOKEN_STRLEN (TOKEN_BYTES * 2) diff --git a/src/util/viridentity.h b/src/util/viridentity.h index 512bca286d..848e5b2056 100644 --- a/src/util/viridentity.h +++ b/src/util/viridentity.h @@ -27,8 +27,13 @@ #define VIR_TYPE_IDENTITY vir_identity_get_type() G_DECLARE_FINAL_TYPE(virIdentity, vir_identity, VIR, IDENTITY, GObject); +#define VIR_IDENTITY_AUTORESTORE __attribute__((cleanup(virIdentityRestoreHelper))) + virIdentity *virIdentityGetCurrent(void); int virIdentitySetCurrent(virIdentity *ident); +virIdentity *virIdentityElevateCurrent(void); + +void virIdentityRestoreHelper(virIdentity **identptr); virIdentity *virIdentityGetSystem(void);