@ -1140,13 +1140,19 @@ TQString LDAPManager::readFullLineFromPtyProcess(PtyProcess* proc) {
return result ;
return result ;
}
}
int LDAPManager : : bindKAdmin ( TQString * errstr ) {
int LDAPManager : : bindKAdmin ( LDAPCredentials * administrativeCredentials , TQString * errstr ) {
int retcode = 1 ;
int retcode = 1 ;
kadm5_ret_t krb5adm_ret ;
kadm5_ret_t krb5adm_ret ;
kadm5_config_params params ;
kadm5_config_params params ;
LDAPCredentials admincreds = currentLDAPCredentials ( ) ;
LDAPCredentials admincreds ;
if ( administrativeCredentials ) {
admincreds = * administrativeCredentials ;
}
else {
admincreds = currentLDAPCredentials ( ) ;
}
if ( admincreds . use_gssapi ) {
if ( admincreds . use_gssapi ) {
// FIXME
// FIXME
// Heimdal has issues parsing the keytab file, so for now just prompt for password
// Heimdal has issues parsing the keytab file, so for now just prompt for password
@ -1291,7 +1297,14 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
int retcode ;
int retcode ;
kadm5_ret_t krb5adm_ret ;
kadm5_ret_t krb5adm_ret ;
retcode = bindKAdmin ( errstr ) ;
bool kadmin_unbind_needed = false ;
if ( m_krb5admHandle ) {
retcode = 0 ;
}
else {
retcode = bindKAdmin ( NULL , errstr ) ;
kadmin_unbind_needed = true ;
}
if ( retcode = = 0 ) {
if ( retcode = = 0 ) {
retcode = 1 ;
retcode = 1 ;
krb5_principal user_kadm5_principal ;
krb5_principal user_kadm5_principal ;
@ -1313,9 +1326,11 @@ int LDAPManager::setPasswordForUser(LDAPUserInfo user, TQString *errstr) {
krb5_free_principal ( m_krb5admContext , user_kadm5_principal ) ;
krb5_free_principal ( m_krb5admContext , user_kadm5_principal ) ;
}
}
if ( kadmin_unbind_needed ) {
unbindKAdmin ( ) ;
unbindKAdmin ( ) ;
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
}
}
}
return retcode ;
return retcode ;
}
}
@ -1843,16 +1858,19 @@ int LDAPManager::addGroupInfo(LDAPGroupInfo group, TQString *errstr) {
}
}
int LDAPManager : : kAdminAddNewPrincipal ( TQString principalName , TQString newPassword , TQString * errstr ) {
int LDAPManager : : kAdminAddNewPrincipal ( TQString principalName , TQString newPassword , TQString * errstr ) {
if ( bind ( ) < 0 ) {
return - 1 ;
}
else {
int retcode ;
int retcode ;
kadm5_ret_t krb5adm_ret ;
kadm5_ret_t krb5adm_ret ;
int i ;
int i ;
char * password = NULL ;
char * password = NULL ;
retcode = bindKAdmin ( errstr ) ;
bool kadmin_unbind_needed = false ;
if ( m_krb5admHandle ) {
retcode = 0 ;
}
else {
retcode = bindKAdmin ( NULL , errstr ) ;
kadmin_unbind_needed = true ;
}
if ( retcode = = 0 ) {
if ( retcode = = 0 ) {
retcode = 1 ;
retcode = 1 ;
bool generate_password ;
bool generate_password ;
@ -1978,12 +1996,13 @@ int LDAPManager::kAdminAddNewPrincipal(TQString principalName, TQString newPassw
free ( password ) ;
free ( password ) ;
}
}
if ( kadmin_unbind_needed ) {
unbindKAdmin ( ) ;
unbindKAdmin ( ) ;
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
}
}
}
return retcode ;
return retcode ;
}
}
}
int LDAPManager : : addMachineInfo ( LDAPMachineInfo machine , TQString * errstr ) {
int LDAPManager : : addMachineInfo ( LDAPMachineInfo machine , TQString * errstr ) {
@ -2584,127 +2603,105 @@ LDAPServiceInfoList LDAPManager::machineServices(TQString machine_dn, int* mretc
}
}
int LDAPManager : : exportKeytabForPrincipal ( TQString principal , TQString fileName , TQString * errstr ) {
int LDAPManager : : exportKeytabForPrincipal ( TQString principal , TQString fileName , TQString * errstr ) {
if ( bind ( ) < 0 ) {
int retcode ;
return - 1 ;
kadm5_ret_t krb5adm_ret ;
int i ;
bool kadmin_unbind_needed = false ;
if ( m_krb5admHandle ) {
retcode = 0 ;
}
}
else {
else {
// Use Kerberos kadmin to export the keytab
retcode = bindKAdmin ( NULL , errstr ) ;
LDAPCredentials admincreds = currentLDAPCredentials ( ) ;
kadmin_unbind_needed = true ;
if ( ( admincreds . username = = " " ) & & ( admincreds . password = = " " ) ) {
// Probably GSSAPI
// Get active ticket principal...
KerberosTicketInfoList tickets = LDAPManager : : getKerberosTicketList ( ) ;
TQStringList principalParts = TQStringList : : split ( " @ " , tickets [ 0 ] . cachePrincipal , false ) ;
admincreds . username = principalParts [ 0 ] ;
admincreds . realm = principalParts [ 1 ] ;
admincreds . use_gssapi = true ;
}
}
if ( retcode = = 0 ) {
retcode = 1 ;
TQCString command = " kadmin " ;
krb5_keytab keytab ;
QCStringList args ;
if ( fileName = = " " ) {
if ( m_host . startsWith ( " ldapi:// " ) ) {
krb5adm_ret = krb5_kt_default ( m_krb5admContext , & keytab ) ;
args < < TQCString ( " -l " ) < < TQCString ( " -r " ) < < TQCString ( admincreds . realm . upper ( ) ) ;
}
}
else {
else {
if ( admincreds . username = = " " ) {
krb5adm_ret = krb5_kt_resolve ( m_krb5admContext , fileName . ascii ( ) , & keytab ) ;
args < < TQCString ( " -r " ) < < TQCString ( admincreds . realm . upper ( ) ) ;
}
}
else {
if ( krb5adm_ret ) {
args < < TQCString ( " -p " ) < < TQCString ( admincreds . username . lower ( ) + " @ " + ( admincreds . realm . upper ( ) ) ) < < TQCString ( " -r " ) < < TQCString ( admincreds . realm . upper ( ) ) ;
if ( errstr ) * errstr = i18n ( " %1<p>Details:<br>Failed to open keytab file '%2' (code %3) " ) . arg ( krb5_get_error_message ( m_krb5admContext , krb5adm_ret ) ) . arg ( fileName ) . arg ( krb5adm_ret ) ;
}
}
else {
kadm5_principal_ent_rec principal_record ;
krb5_principal principal_entry = NULL ;
memset ( & principal_record , 0 , sizeof ( principal_record ) ) ;
krb5adm_ret = krb5_parse_name ( m_krb5admContext , principal . ascii ( ) , & principal_entry ) ;
if ( krb5adm_ret ) {
if ( errstr ) * errstr = i18n ( " %1<p>Details:<br>Failed to execute krb5_parse_name (code %2) " ) . arg ( krb5_get_error_message ( m_krb5admContext , krb5adm_ret ) ) . arg ( krb5adm_ret ) ;
}
}
else {
principal_record . principal = principal_entry ;
TQString prompt ;
krb5adm_ret = kadm5_get_principal ( m_krb5admHandle , principal_entry , & principal_record , KADM5_PRINCIPAL | KADM5_KVNO | KADM5_KEY_DATA ) ;
PtyProcess kadminProc ;
if ( krb5adm_ret ) {
kadminProc . exec ( command , args ) ;
if ( errstr ) * errstr = i18n ( " %1<p>Details:<br>Failed to execute kadm5_get_principal (code %2) " ) . arg ( krb5_get_error_message ( m_krb5admContext , krb5adm_ret ) ) . arg ( krb5adm_ret ) ;
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
retcode = 2 ;
prompt = prompt . stripWhiteSpace ( ) ;
if ( prompt = = " kadmin> " ) {
if ( fileName = = " " ) {
command = TQCString ( " ext_keytab " + principal ) ;
}
}
else {
else {
command = TQCString ( " ext_keytab --keytab= \" " + fileName + " \" " + principal ) ;
if ( principal_record . n_key_data = = 0 ) {
if ( errstr ) * errstr = i18n ( " No keys found!<p>If this principal is known to have valid keys, please check your access permissions and try again " ) ;
retcode = 2 ;
}
}
kadminProc . enableLocalEcho ( false ) ;
else {
kadminProc . writeLine ( command , true ) ;
// Extract keys
do { // Discard our own input
krb5_keytab_entry * keys = NULL ;
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
keys = ( krb5_keytab_entry * ) calloc ( sizeof ( * keys ) , principal_record . n_key_data ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
if ( keys = = NULL ) {
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
if ( errstr ) * errstr = i18n ( " Out of memory " ) ;
prompt = prompt . stripWhiteSpace ( ) ;
// Use all defaults
while ( prompt ! = " kadmin> " ) {
if ( prompt . endsWith ( " Password: " ) ) {
if ( admincreds . password = = " " ) {
if ( tqApp - > type ( ) ! = TQApplication : : Tty ) {
TQCString password ;
int result = KPasswordDialog : : getPassword ( password , prompt ) ;
if ( result = = KPasswordDialog : : Accepted ) {
admincreds . password = password ;
}
}
else {
int key_count = 0 ;
for ( i = 0 ; i < principal_record . n_key_data ; i + + ) {
krb5_key_data * kd = & principal_record . key_data [ i ] ;
keys [ i ] . principal = principal_record . principal ;
keys [ i ] . vno = kd - > key_data_kvno ;
keys [ i ] . keyblock . keytype = kd - > key_data_type [ 0 ] ;
keys [ i ] . keyblock . keyvalue . length = kd - > key_data_length [ 0 ] ;
keys [ i ] . keyblock . keyvalue . data = kd - > key_data_contents [ 0 ] ;
keys [ i ] . timestamp = time ( NULL ) ;
key_count + + ;
}
if ( key_count < 1 ) {
if ( errstr ) * errstr = i18n ( " No keys found!<p>If this principal is known to have valid keys, please check your access permissions and try again " ) ;
}
}
else {
else {
TQFile file ;
for ( i = 0 ; i < key_count ; i + + ) {
file . open ( IO_ReadOnly , stdin ) ;
krb5adm_ret = krb5_kt_add_entry ( m_krb5admContext , keytab , & keys [ i ] ) ;
TQTextStream qtin ( & file ) ;
if ( krb5adm_ret ) {
admincreds . password = qtin . readLine ( ) ;
if ( errstr ) * errstr = i18n ( " %1<p>Details:<br>Failed to execute krb5_kt_add_entry (code %2) " ) . arg ( krb5_get_error_message ( m_krb5admContext , krb5adm_ret ) ) . arg ( krb5adm_ret ) ;
}
}
}
}
if ( admincreds . password ! = " " ) {
if ( ! krb5adm_ret ) {
kadminProc . enableLocalEcho ( false ) ;
// Success!
kadminProc . writeLine ( admincreds . password , true ) ;
retcode = 0 ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
prompt = prompt . stripWhiteSpace ( ) ;
}
}
}
}
if ( prompt . contains ( " authentication failed " ) ) {
if ( errstr ) * errstr = detailedKAdminErrorMessage ( prompt ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
}
else {
// Extract whatever default is in the [brackets] and feed it back to kadmin
free ( keys ) ;
TQString defaultParam ;
int leftbracket = prompt . find ( " [ " ) ;
int rightbracket = prompt . find ( " ] " ) ;
if ( ( leftbracket > = 0 ) & & ( rightbracket > = 0 ) ) {
leftbracket + + ;
defaultParam = prompt . mid ( leftbracket , rightbracket - leftbracket ) ;
}
command = TQCString ( defaultParam ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( command , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
prompt = prompt . stripWhiteSpace ( ) ;
}
}
kadm5_free_principal_ent ( m_krb5admHandle , & principal_record ) ;
}
}
if ( prompt ! = " kadmin> " ) {
}
if ( errstr ) * errstr = detailedKAdminErrorMessage ( prompt ) ;
krb5_kt_close ( m_krb5admContext , keytab ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
}
// Success!
if ( kadmin_unbind_needed ) {
kadminProc . enableLocalEcho ( false ) ;
unbindKAdmin ( ) ;
kadminProc . writeLine ( " quit " , true ) ;
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
unbind ( true ) ; // Using kadmin can disrupt our LDAP connection
return 0 ;
}
}
if ( errstr ) * errstr = " Internal error. Verify that kadmin exists and can be executed. " ;
return 1 ; // Failure
}
}
return retcode ;
}
}
int LDAPManager : : writeCertificateFileIntoDirectory ( TQByteArray cert , TQString attr , TQString * errstr ) {
int LDAPManager : : writeCertificateFileIntoDirectory ( TQByteArray cert , TQString attr , TQString * errstr ) {
@ -5170,144 +5167,31 @@ int LDAPManager::writeOpenSSLConfigurationFile(LDAPRealmConfig realmcfg, LDAPUse
}
}
int LDAPManager : : bondRealm ( TQString adminUserName , const char * adminPassword , TQString adminRealm , TQString * errstr ) {
int LDAPManager : : bondRealm ( TQString adminUserName , const char * adminPassword , TQString adminRealm , TQString * errstr ) {
TQCString command = " kadmin " ;
LDAPCredentials admincreds ;
QCStringList args ;
admincreds . username = adminUserName ;
args < < TQCString ( " -p " ) < < TQCString ( adminUserName + " @ " + ( adminRealm . upper ( ) ) ) < < TQCString ( " -r " ) < < TQCString ( adminRealm . upper ( ) ) ;
admincreds . password = adminPassword ;
admincreds . realm = adminRealm ;
TQString hoststring = " host/ " + getMachineFQDN ( ) ;
admincreds . use_gssapi = false ;
TQString prompt ;
PtyProcess kadminProc ;
kadminProc . exec ( command , args ) ;
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
prompt = prompt . stripWhiteSpace ( ) ;
if ( prompt = = " kadmin> " ) {
command = TQCString ( " ext " + hoststring ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( command , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
prompt = prompt . stripWhiteSpace ( ) ;
if ( prompt . endsWith ( " Password: " ) ) {
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( adminPassword , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
prompt = prompt . stripWhiteSpace ( ) ;
}
if ( prompt . contains ( " authentication failed " ) ) {
if ( errstr ) * errstr = prompt ;
do { // Wait for command prompt
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
else if ( prompt . endsWith ( " Principal does not exist " ) ) {
do { // Wait for command prompt
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
command = TQCString ( " ank --random-key " + hoststring ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( command , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
prompt = prompt . stripWhiteSpace ( ) ;
// Use all defaults
while ( prompt ! = " kadmin> " ) {
if ( prompt . endsWith ( " Password: " ) ) {
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( adminPassword , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
prompt = prompt . stripWhiteSpace ( ) ;
}
if ( prompt . contains ( " authentication failed " ) ) {
if ( errstr ) * errstr = prompt ;
do { // Wait for command prompt
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
else {
// Extract whatever default is in the [brackets] and feed it back to kadmin
TQString defaultParam ;
int leftbracket = prompt . find ( " [ " ) ;
int rightbracket = prompt . find ( " ] " ) ;
if ( ( leftbracket > = 0 ) & & ( rightbracket > = 0 ) ) {
leftbracket + + ;
defaultParam = prompt . mid ( leftbracket , rightbracket - leftbracket ) ;
}
command = TQCString ( defaultParam ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( command , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
prompt = prompt . stripWhiteSpace ( ) ;
}
}
command = TQCString ( " ext " + hoststring ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( command , true ) ;
do { // Discard our own input
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( ( prompt = = TQString ( command ) ) | | ( prompt = = " " ) ) ;
prompt = prompt . stripWhiteSpace ( ) ;
if ( prompt ! = " kadmin> " ) {
if ( errstr ) * errstr = prompt ;
do { // Wait for command prompt
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
} while ( prompt = = " " ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
// Success!
TQString hoststring = " host/ " + getMachineFQDN ( ) ;
kadminProc . enableLocalEcho ( false ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 0 ;
int retcode ;
}
LDAPManager * ldap_mgr = new LDAPManager ( adminRealm , TQString : : null ) ;
else if ( prompt = = " kadmin> " ) {
retcode = ldap_mgr - > bindKAdmin ( & admincreds , errstr ) ;
// Success!
if ( ! retcode ) {
kadminProc . enableLocalEcho ( false ) ;
retcode = ldap_mgr - > exportKeytabForPrincipal ( hoststring , TQString : : null , errstr ) ;
kadminProc . writeLine ( " quit " , true ) ;
if ( retcode = = 2 ) {
// Principal not found, create it
return 0 ;
retcode = ldap_mgr - > kAdminAddNewPrincipal ( hoststring , TQString : : null , errstr ) ;
if ( ! retcode ) {
retcode = ldap_mgr - > exportKeytabForPrincipal ( hoststring , TQString : : null , errstr ) ;
}
}
// Failure
if ( errstr ) * errstr = prompt ;
while ( prompt = = " " ) { // Wait for command prompt
prompt = readFullLineFromPtyProcess ( & kadminProc ) ;
printf ( " (kadmin) '%s' \n " , prompt . ascii ( ) ) ;
}
}
kadminProc . enableLocalEcho ( false ) ;
ldap_mgr - > unbindKAdmin ( ) ;
kadminProc . writeLine ( " quit " , true ) ;
return 1 ;
}
}
delete ldap_mgr ;
if ( errstr ) * errstr = " Internal error. Verify that kadmin exists and can be executed. " ;
return retcode ;
return 1 ; // Failure
}
}
int LDAPManager : : unbondRealm ( LDAPRealmConfig realmcfg , TQString adminUserName , const char * adminPassword , TQString adminRealm , TQString * errstr ) {
int LDAPManager : : unbondRealm ( LDAPRealmConfig realmcfg , TQString adminUserName , const char * adminPassword , TQString adminRealm , TQString * errstr ) {