1 /* This is a copy of the hellolibvirt example demonstaring how to use
2 * virConnectOpenAuth with a custom auth callback */
7 #include <libvirt/libvirt.h>
8 #include <libvirt/virterror.h>
11 showError(virConnectPtr conn
)
16 err
= malloc(sizeof(*err
));
18 printf("Could not allocate memory for error data\n");
22 ret
= virConnCopyLastError(conn
, err
);
26 printf("No error found\n");
30 printf("Parameter error when attempting to get last error\n");
34 printf("libvirt reported: \"%s\"\n", err
->message
);
47 showHypervisorInfo(virConnectPtr conn
)
50 unsigned long hvVer
, major
, minor
, release
;
53 /* virConnectGetType returns a pointer to a static string, so no
54 * allocation or freeing is necessary; it is possible for the call
55 * to fail if, for example, there is no connection to a
56 * hypervisor, so check what it returns. */
57 hvType
= virConnectGetType(conn
);
60 printf("Failed to get hypervisor type\n");
65 if (virConnectGetVersion(conn
, &hvVer
) != 0) {
67 printf("Failed to get hypervisor version\n");
72 major
= hvVer
/ 1000000;
75 release
= hvVer
% 1000;
77 printf("Hypervisor: \"%s\" version: %lu.%lu.%lu\n",
89 showDomains(virConnectPtr conn
)
91 int ret
= 0, numNames
, numInactiveDomains
, numActiveDomains
;
93 char **nameList
= NULL
;
95 numActiveDomains
= virConnectNumOfDomains(conn
);
96 if (numActiveDomains
== -1) {
98 printf("Failed to get number of active domains\n");
103 numInactiveDomains
= virConnectNumOfDefinedDomains(conn
);
104 if (numInactiveDomains
== -1) {
106 printf("Failed to get number of inactive domains\n");
111 printf("There are %d active and %d inactive domains\n",
112 numActiveDomains
, numInactiveDomains
);
114 nameList
= malloc(sizeof(*nameList
) * numInactiveDomains
);
116 if (nameList
== NULL
) {
118 printf("Could not allocate memory for list of inactive domains\n");
122 numNames
= virConnectListDefinedDomains(conn
,
126 if (numNames
== -1) {
128 printf("Could not get list of defined domains from hypervisor\n");
134 printf("Inactive domains:\n");
136 for (i
= 0; i
< numNames
; i
++) {
137 printf(" %s\n", *(nameList
+ i
));
138 /* The API documentation doesn't say so, but the names
139 * returned by virConnectListDefinedDomains are strdup'd and
140 * must be freed here. */
141 free(*(nameList
+ i
));
149 /* Struct to pass the credentials to the auth callback via the cbdata pointer */
155 typedef struct _AuthData AuthData
;
157 /* This function will be called by libvirt to obtain credentials in order to
158 * authenticate to the hypervisor */
160 authCallback(virConnectCredentialPtr cred
, unsigned int ncred
, void *cbdata
)
163 AuthData
*authData
= cbdata
;
165 /* libvirt might request multiple credentials in a single call.
166 * This example supports VIR_CRED_AUTHNAME and VIR_CRED_PASSPHRASE
167 * credentials only, but there are several other types.
169 * A request may also contain a prompt message that can be displayed
170 * to the user and a challenge. The challenge is specific to the
171 * credential type and hypervisor type.
173 * For example the ESX driver passes the hostname of the ESX or vCenter
174 * server as challenge. This allows a auth callback to return the
175 * proper credentials. */
176 for (i
= 0; i
< ncred
; ++i
) {
177 switch (cred
[i
].type
) {
178 case VIR_CRED_AUTHNAME
:
179 cred
[i
].result
= strdup(authData
->username
);
181 if (cred
[i
].result
== NULL
)
184 cred
[i
].resultlen
= strlen(cred
[i
].result
);
187 case VIR_CRED_PASSPHRASE
:
188 cred
[i
].result
= strdup(authData
->password
);
190 if (cred
[i
].result
== NULL
)
193 cred
[i
].resultlen
= strlen(cred
[i
].result
);
205 /* The list of credential types supported by our auth callback */
206 static int credTypes
[] = {
212 /* The auth struct that will be passed to virConnectOpenAuth */
213 static virConnectAuth auth
= {
215 sizeof(credTypes
) / sizeof(int),
217 NULL
, /* cbdata will be initialized in main */
222 main(int argc
, char *argv
[])
231 printf("Usage: %s <uri> <username> <password>\n", argv
[0]);
236 authData
.username
= argv
[2];
237 authData
.password
= argv
[3];
238 auth
.cbdata
= &authData
;
240 printf("Attempting to connect to hypervisor\n");
242 conn
= virConnectOpenAuth(uri
, &auth
, 0);
246 printf("No connection to hypervisor\n");
251 uri
= virConnectGetURI(conn
);
254 printf("Failed to get URI for hypervisor connection\n");
259 printf("Connected to hypervisor at \"%s\"\n", uri
);
262 if (showHypervisorInfo(conn
) != 0) {
267 if (showDomains(conn
) != 0) {
273 if (virConnectClose(conn
) != 0) {
274 printf("Failed to disconnect from hypervisor\n");
278 printf("Disconnected from hypervisor\n");