2010-07-06 16:59:50 +04:00
/* This is a copy of the hellolibvirt example demonstaring how to use
* virConnectOpenAuth with a custom auth callback */
# include <config.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <libvirt/libvirt.h>
# include <libvirt/virterror.h>
static void
showError ( virConnectPtr conn )
{
int ret ;
virErrorPtr err ;
err = malloc ( sizeof ( * err ) ) ;
if ( err = = NULL ) {
printf ( " Could not allocate memory for error data \n " ) ;
goto out ;
}
ret = virConnCopyLastError ( conn , err ) ;
switch ( ret ) {
case 0 :
printf ( " No error found \n " ) ;
break ;
case - 1 :
printf ( " Parameter error when attempting to get last error \n " ) ;
break ;
default :
printf ( " libvirt reported: \" %s \" \n " , err - > message ) ;
break ;
}
virResetError ( err ) ;
free ( err ) ;
2014-03-25 10:48:10 +04:00
out :
2010-07-06 16:59:50 +04:00
return ;
}
static int
showHypervisorInfo ( virConnectPtr conn )
{
int ret = 0 ;
unsigned long hvVer , major , minor , release ;
const char * hvType ;
/* virConnectGetType returns a pointer to a static string, so no
* allocation or freeing is necessary ; it is possible for the call
* to fail if , for example , there is no connection to a
* hypervisor , so check what it returns . */
hvType = virConnectGetType ( conn ) ;
if ( hvType = = NULL ) {
ret = 1 ;
printf ( " Failed to get hypervisor type \n " ) ;
showError ( conn ) ;
goto out ;
}
if ( virConnectGetVersion ( conn , & hvVer ) ! = 0 ) {
ret = 1 ;
printf ( " Failed to get hypervisor version \n " ) ;
showError ( conn ) ;
goto out ;
}
major = hvVer / 1000000 ;
hvVer % = 1000000 ;
minor = hvVer / 1000 ;
release = hvVer % 1000 ;
printf ( " Hypervisor: \" %s \" version: %lu.%lu.%lu \n " ,
hvType ,
major ,
minor ,
release ) ;
2014-03-25 10:48:10 +04:00
out :
2010-07-06 16:59:50 +04:00
return ret ;
}
static int
showDomains ( virConnectPtr conn )
{
Convert 'int i' to 'size_t i' in examples/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
int ret = 0 , numNames , numInactiveDomains , numActiveDomains ;
2016-12-20 12:29:52 +03:00
ssize_t i ;
2010-07-06 16:59:50 +04:00
char * * nameList = NULL ;
numActiveDomains = virConnectNumOfDomains ( conn ) ;
if ( numActiveDomains = = - 1 ) {
ret = 1 ;
printf ( " Failed to get number of active domains \n " ) ;
showError ( conn ) ;
goto out ;
}
numInactiveDomains = virConnectNumOfDefinedDomains ( conn ) ;
if ( numInactiveDomains = = - 1 ) {
ret = 1 ;
printf ( " Failed to get number of inactive domains \n " ) ;
showError ( conn ) ;
goto out ;
}
printf ( " There are %d active and %d inactive domains \n " ,
numActiveDomains , numInactiveDomains ) ;
nameList = malloc ( sizeof ( * nameList ) * numInactiveDomains ) ;
if ( nameList = = NULL ) {
ret = 1 ;
printf ( " Could not allocate memory for list of inactive domains \n " ) ;
goto out ;
}
numNames = virConnectListDefinedDomains ( conn ,
nameList ,
numInactiveDomains ) ;
if ( numNames = = - 1 ) {
ret = 1 ;
printf ( " Could not get list of defined domains from hypervisor \n " ) ;
showError ( conn ) ;
goto out ;
}
2014-11-13 17:20:27 +03:00
if ( numNames > 0 )
2010-07-06 16:59:50 +04:00
printf ( " Inactive domains: \n " ) ;
2013-05-21 12:04:26 +04:00
for ( i = 0 ; i < numNames ; i + + ) {
2010-07-06 16:59:50 +04:00
printf ( " %s \n " , * ( nameList + i ) ) ;
/* The API documentation doesn't say so, but the names
* returned by virConnectListDefinedDomains are strdup ' d and
* must be freed here . */
free ( * ( nameList + i ) ) ;
}
2014-03-25 10:48:10 +04:00
out :
2010-07-06 16:59:50 +04:00
free ( nameList ) ;
return ret ;
}
/* Struct to pass the credentials to the auth callback via the cbdata pointer */
struct _AuthData {
char * username ;
char * password ;
} ;
typedef struct _AuthData AuthData ;
/* This function will be called by libvirt to obtain credentials in order to
* authenticate to the hypervisor */
static int
authCallback ( virConnectCredentialPtr cred , unsigned int ncred , void * cbdata )
{
Convert 'int i' to 'size_t i' in examples/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2010-07-06 16:59:50 +04:00
AuthData * authData = cbdata ;
/* libvirt might request multiple credentials in a single call.
* This example supports VIR_CRED_AUTHNAME and VIR_CRED_PASSPHRASE
* credentials only , but there are several other types .
*
* A request may also contain a prompt message that can be displayed
* to the user and a challenge . The challenge is specific to the
* credential type and hypervisor type .
*
* For example the ESX driver passes the hostname of the ESX or vCenter
* server as challenge . This allows a auth callback to return the
* proper credentials . */
2013-05-21 12:04:26 +04:00
for ( i = 0 ; i < ncred ; + + i ) {
2010-07-06 16:59:50 +04:00
switch ( cred [ i ] . type ) {
case VIR_CRED_AUTHNAME :
cred [ i ] . result = strdup ( authData - > username ) ;
2014-11-13 17:20:27 +03:00
if ( cred [ i ] . result = = NULL )
2010-07-06 16:59:50 +04:00
return - 1 ;
cred [ i ] . resultlen = strlen ( cred [ i ] . result ) ;
break ;
case VIR_CRED_PASSPHRASE :
cred [ i ] . result = strdup ( authData - > password ) ;
2014-11-13 17:20:27 +03:00
if ( cred [ i ] . result = = NULL )
2010-07-06 16:59:50 +04:00
return - 1 ;
cred [ i ] . resultlen = strlen ( cred [ i ] . result ) ;
break ;
default :
return - 1 ;
}
}
return 0 ;
}
/* The list of credential types supported by our auth callback */
static int credTypes [ ] = {
VIR_CRED_AUTHNAME ,
VIR_CRED_PASSPHRASE
} ;
/* The auth struct that will be passed to virConnectOpenAuth */
static virConnectAuth auth = {
credTypes ,
sizeof ( credTypes ) / sizeof ( int ) ,
authCallback ,
2017-04-27 09:47:19 +03:00
NULL , /* cbdata will be initialized in main */
2010-07-06 16:59:50 +04:00
} ;
int
main ( int argc , char * argv [ ] )
{
int ret = 0 ;
virConnectPtr conn ;
char * uri ;
AuthData authData ;
if ( argc ! = 4 ) {
ret = 1 ;
printf ( " Usage: %s <uri> <username> <password> \n " , argv [ 0 ] ) ;
goto out ;
}
uri = argv [ 1 ] ;
authData . username = argv [ 2 ] ;
authData . password = argv [ 3 ] ;
auth . cbdata = & authData ;
printf ( " Attempting to connect to hypervisor \n " ) ;
conn = virConnectOpenAuth ( uri , & auth , 0 ) ;
if ( NULL = = conn ) {
ret = 1 ;
printf ( " No connection to hypervisor \n " ) ;
showError ( conn ) ;
goto out ;
}
uri = virConnectGetURI ( conn ) ;
if ( uri = = NULL ) {
ret = 1 ;
printf ( " Failed to get URI for hypervisor connection \n " ) ;
showError ( conn ) ;
goto disconnect ;
}
printf ( " Connected to hypervisor at \" %s \" \n " , uri ) ;
free ( uri ) ;
if ( showHypervisorInfo ( conn ) ! = 0 ) {
ret = 1 ;
goto disconnect ;
}
if ( showDomains ( conn ) ! = 0 ) {
ret = 1 ;
goto disconnect ;
}
2014-03-25 10:48:10 +04:00
disconnect :
2010-07-06 16:59:50 +04:00
if ( virConnectClose ( conn ) ! = 0 ) {
printf ( " Failed to disconnect from hypervisor \n " ) ;
showError ( conn ) ;
ret = 1 ;
} else {
printf ( " Disconnected from hypervisor \n " ) ;
}
2014-03-25 10:48:10 +04:00
out :
2010-07-06 16:59:50 +04:00
return ret ;
}