For setting passwords of users inside the domain.
With the VIR_DOMAIN_PASSWORD_CRYPTED flag set, the password
is assumed to be already encrypted by crypt(3).
https://bugzilla.redhat.com/show_bug.cgi?id=1174177
---
include/libvirt/libvirt-domain.h | 9 ++++++++
src/access/viraccessperm.c | 2 +-
src/access/viraccessperm.h | 6 +++++
src/driver-hypervisor.h | 7 ++++++
src/libvirt-domain.c | 47 ++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 +++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 15 ++++++++++++-
src/remote_protocol-structs | 7 ++++++
9 files changed, 97 insertions(+), 2 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 0f465b9..b8e803d 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_CRYPTED = 1 << 0, /* the password is crypted by crypt(3)
*/
+} 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 9007186..0f58290 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 8ccbbad..0acd156 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 8b8d031..3275343 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 d467758..c4e2345 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_CRYPTED, the password
+ * is assumed to be crypted by crypt(3).
+ *
+ * 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 ef3d2f0..716dd2f 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 31417e8..dd8dab6 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 49b7ddd..9f1be6b 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<REMOTE_DOMAIN_INTERFACE_MAX>;
};
+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 116b572..48c3bd8 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,
};
--
2.0.5