diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 0f465b98dc..d851225a50 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -3818,4 +3818,13 @@ int virDomainInterfaceAddresses(virDomainPtr dom, void virDomainInterfaceFree(virDomainInterfacePtr iface); +typedef enum { + VIR_DOMAIN_PASSWORD_ENCRYPTED = 1 << 0, /* the password is already encrypted */ +} virDomainSetUserPasswordFlags; + +int virDomainSetUserPassword(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags); + #endif /* __VIR_LIBVIRT_DOMAIN_H__ */ diff --git a/src/access/viraccessperm.c b/src/access/viraccessperm.c index 90071863be..0f58290173 100644 --- a/src/access/viraccessperm.c +++ b/src/access/viraccessperm.c @@ -43,7 +43,7 @@ VIR_ENUM_IMPL(virAccessPermDomain, "fs_trim", "fs_freeze", "block_read", "block_write", "mem_read", "open_graphics", "open_device", "screenshot", - "open_namespace", "set_time"); + "open_namespace", "set_time", "set_password"); VIR_ENUM_IMPL(virAccessPermInterface, VIR_ACCESS_PERM_INTERFACE_LAST, diff --git a/src/access/viraccessperm.h b/src/access/viraccessperm.h index 8ccbbad5d6..0acd1563c7 100644 --- a/src/access/viraccessperm.h +++ b/src/access/viraccessperm.h @@ -300,6 +300,12 @@ typedef enum { */ VIR_ACCESS_PERM_DOMAIN_SET_TIME, + /** + * @desc: Set password of the domain's account + * @message: Setting the domain accounts' password requires authorization + */ + VIR_ACCESS_PERM_DOMAIN_SET_PASSWORD, + VIR_ACCESS_PERM_DOMAIN_LAST, } virAccessPermDomain; diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 8b8d03178f..3275343ea9 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1201,6 +1201,12 @@ typedef int unsigned int source, unsigned int flags); +typedef int +(*virDrvDomainSetUserPassword)(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags); + typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1430,6 +1436,7 @@ struct _virHypervisorDriver { virDrvNodeAllocPages nodeAllocPages; virDrvDomainGetFSInfo domainGetFSInfo; virDrvDomainInterfaceAddresses domainInterfaceAddresses; + virDrvDomainSetUserPassword domainSetUserPassword; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index d4677581b4..2edba1a5a8 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -11001,6 +11001,53 @@ virDomainSetTime(virDomainPtr dom, } +/** + * virDomainSetUserPassword: + * @dom: a domain object + * @user: the username that will get a new password + * @password: the password to set + * @flags: bitwise-OR of virDomainSetUserPasswordFlags + * + * Sets the @user password to the value specified by @password. + * If @flags contain VIR_DOMAIN_PASSWORD_ENCRYPTED, the password + * is assumed to be encrypted by the method required by the guest OS. + * + * Please note that some hypervisors may require guest agent to + * be configured and running in order to be able to run this API. + * + * Returns 0 on success, -1 otherwise. + */ +int +virDomainSetUserPassword(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags) +{ + VIR_DOMAIN_DEBUG(dom, "user=%s, password=%s, flags=%x", + NULLSTR(user), NULLSTR(password), flags); + + virResetLastError(); + + virCheckDomainReturn(dom, -1); + virCheckReadOnlyGoto(dom->conn->flags, error); + virCheckNonNullArgGoto(user, error); + virCheckNonNullArgGoto(password, error); + + if (dom->conn->driver->domainSetUserPassword) { + int ret = dom->conn->driver->domainSetUserPassword(dom, user, password, + flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(dom->conn); + return -1; +} + /** * virConnectGetDomainCapabilities: diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index ef3d2f00e2..716dd2fac3 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -710,4 +710,9 @@ LIBVIRT_1.2.15 { virDomainDelIOThread; } LIBVIRT_1.2.14; +LIBVIRT_1.2.16 { + global: + virDomainSetUserPassword; +} LIBVIRT_1.2.15; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 31417e8567..dd8dab69f6 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8389,6 +8389,7 @@ static virHypervisorDriver hypervisor_driver = { .nodeAllocPages = remoteNodeAllocPages, /* 1.2.9 */ .domainGetFSInfo = remoteDomainGetFSInfo, /* 1.2.11 */ .domainInterfaceAddresses = remoteDomainInterfaceAddresses, /* 1.2.14 */ + .domainSetUserPassword = remoteDomainSetUserPassword, /* 1.2.16 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 49b7dddabf..9f1be6b346 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3223,6 +3223,13 @@ struct remote_domain_interface_addresses_ret { remote_domain_interface ifaces; }; +struct remote_domain_set_user_password_args { + remote_nonnull_domain dom; + remote_string user; + remote_string password; + unsigned int flags; +}; + /*----- Protocol. -----*/ @@ -5683,5 +5690,11 @@ enum remote_procedure { * @acl: domain:save:!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE * @acl: domain:save:VIR_DOMAIN_AFFECT_CONFIG */ - REMOTE_PROC_DOMAIN_DEL_IOTHREAD = 356 + REMOTE_PROC_DOMAIN_DEL_IOTHREAD = 356, + + /** + * @generate:both + * @acl: domain:set_password + */ + REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 116b572923..48c3bd8860 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2678,6 +2678,12 @@ struct remote_domain_interface_addresses_ret { remote_domain_interface * ifaces_val; } ifaces; }; +struct remote_domain_set_user_password_args { + remote_nonnull_domain dom; + remote_string user; + remote_string password; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -3035,4 +3041,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_DEVICE_ADDED = 354, REMOTE_PROC_DOMAIN_ADD_IOTHREAD = 355, REMOTE_PROC_DOMAIN_DEL_IOTHREAD = 356, + REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357, };