diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 0f465b98dcf413aaa7f614d5f217cf147c81b482..d851225a50f81237285c57f3b82a1507942f8e27 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 90071863be31b66ea2e76c55a001966f1934af6f..0f5829017305556dc1730ce14e269b3f54da7a71 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 8ccbbad5d6cddd58e3a945b2841f978674ce233e..0acd1563c7ff493fa13f7c94ee8d85c4f6a399c7 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 8b8d03178f52e1d3c1e1995729570afc5ae0fcc0..3275343ea9563fd7f97761d281e1b9c01fec1851 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 d4677581b4245888cad0600614abd77a0b662bdb..2edba1a5a8d00e8f6312c3c973b076455feb3aef 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 ef3d2f00e228d95d0403ce121efb20517679d2f4..716dd2fac35b09b20b07d2c081a0a74ff6752244 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 31417e85677914aca6ab03a33381793c15b1c711..dd8dab69f69244ac29b94aff905b5a91d64ec687 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 49b7dddabf56510c5b68bb53855858c8cfb9fb9d..9f1be6b3469572d75619eb648f24153a73c462ea 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 116b57292325ef0e3b5e1fec81c11d43a795eff1..48c3bd88605a79c907ef2688b9d9d72379abca0a 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, };