@@ -41,7 +41,8 @@ Kerberos::Kerberos()
41
41
Kerberos::~Kerberos () { cleanup (); }
42
42
43
43
void Kerberos::get_ldap_host (std::string &host) {
44
- if (initialize ()) host = m_ldap_server_host;
44
+ assert (m_initialized);
45
+ host = m_ldap_server_host;
45
46
}
46
47
47
48
bool Kerberos::initialize () {
@@ -57,11 +58,6 @@ bool Kerberos::initialize() {
57
58
log (res_kerberos);
58
59
goto EXIT;
59
60
}
60
- if (!get_kerberos_config ()) {
61
- log_error (
62
- " Failed to get required details from Kerberos configuration file." );
63
- goto EXIT;
64
- }
65
61
m_initialized = true ;
66
62
log_dbg (" Kerberos object initialized successfully." );
67
63
@@ -89,6 +85,16 @@ void Kerberos::cleanup() {
89
85
m_initialized = false ;
90
86
}
91
87
88
+ void Kerberos::set_user_and_password (const char *user, const char *password) {
89
+ assert (user);
90
+ assert (password);
91
+
92
+ m_user = user;
93
+ m_password = password;
94
+ auto pos = m_user.find (' @' );
95
+ m_realm = pos == std::string::npos ? " " : std::string (m_user, pos + 1 );
96
+ }
97
+
92
98
bool Kerberos::open_default_cache () {
93
99
if (m_krb_credentials_cache != nullptr ) return true ;
94
100
krb5_error_code res_kerberos =
@@ -250,117 +256,116 @@ bool Kerberos::obtain_store_credentials() {
250
256
return success;
251
257
}
252
258
253
- bool Kerberos::get_kerberos_config () {
254
- log_dbg (" Getting kerberos configuration." );
255
- /*
256
- Kerberos profile category/sub-category names.
257
- */
259
+ void Kerberos::get_ldap_server_from_kdc () {
260
+ assert (m_initialized);
261
+
258
262
static const char realms_heading[] = " realms" ;
259
- static const char host_default[] = " " ;
260
- static const char apps_heading[] = " appdefaults" ;
261
- static const char mysql_apps[] = " mysql" ;
262
- static const char ldap_host_option[] = " ldap_server_host" ;
263
- static const char ldap_destroy_option[] = " ldap_destroy_tgt" ;
264
263
static const char kdc_option[] = " kdc" ;
265
264
266
265
krb5_error_code res_kerberos = 0 ;
267
266
_profile_t *profile = nullptr ;
268
267
char *host_value = nullptr ;
269
- char *default_realm = nullptr ;
270
-
271
- /*
272
- Get default realm.
273
- */
274
- res_kerberos = krb5.krb5_get_default_realm ()(m_context, &default_realm);
275
- if (res_kerberos) {
276
- log_error (" Failed to get default realm from Kerberos configuration." );
277
- goto EXIT;
278
- }
279
268
280
269
res_kerberos = krb5.krb5_get_profile ()(m_context, &profile);
281
270
if (res_kerberos) {
282
271
log_error (" Failed to get Kerberos configuration profile." );
283
- goto EXIT ;
272
+ return ;
284
273
}
285
274
286
- /*
287
- 1. Getting ldap server host from mysql app section.
288
- 2. If failed to get from mysql app section, get from realm section.
289
- realm section should have kdc server info as without kdc info, kerberos
290
- authentication will not work. Authentication process will stop and consider
291
- failed if failed to get LDAP server host.
292
- */
293
275
res_kerberos =
294
- krb5.profile_get_string ()(profile, apps_heading, mysql_apps,
295
- ldap_host_option, host_default, &host_value);
296
- if (res_kerberos || !strcmp (host_value, " " )) {
297
- if (host_value) {
298
- krb5.profile_release_string ()(host_value);
299
- host_value = nullptr ;
300
- }
301
- res_kerberos =
302
- krb5.profile_get_string ()(profile, realms_heading, default_realm,
303
- kdc_option, host_default, &host_value);
304
- if (res_kerberos) {
305
- if (host_value) {
306
- krb5.profile_release_string ()(host_value);
307
- host_value = nullptr ;
308
- }
309
- log_error (" get_kerberos_config: failed to get ldap server host." );
310
- goto EXIT;
311
- }
312
- }
276
+ krb5.profile_get_string ()(profile, realms_heading, m_realm.c_str (),
277
+ kdc_option, nullptr , &host_value);
278
+ if (res_kerberos || host_value == nullptr )
279
+ log_warning (" Failed to get LDAP server host as KDC from [realms] section." );
280
+ else
281
+ m_ldap_server_host = host_value;
282
+
283
+ // Cleanup
313
284
if (host_value) {
314
285
m_ldap_server_host = host_value;
315
- log_info (" Kerberos configuration KDC : " , m_ldap_server_host.c_str ());
316
- size_t pos = m_ldap_server_host.npos ;
317
- /* IPV6 */
318
- if (m_ldap_server_host[0 ] == ' [' ) {
319
- pos = m_ldap_server_host.find (" ]" );
320
- if (pos != m_ldap_server_host.npos &&
321
- (m_ldap_server_host.length () > (pos + 1 )) &&
322
- (m_ldap_server_host[pos + 1 ] == ' :' )) {
323
- m_ldap_server_host = m_ldap_server_host.substr (1 , pos - 1 );
324
- }
325
- }
326
- /* IPV4 */
327
- else {
328
- pos = m_ldap_server_host.find (" :" );
329
- if (pos != m_ldap_server_host.npos ) {
330
- m_ldap_server_host.erase (pos);
331
- }
332
- }
333
- log_info (" Processed Kerberos KDC: " , m_ldap_server_host.c_str ());
286
+ krb5.profile_release_string ()(host_value);
287
+ host_value = nullptr ;
334
288
}
289
+ if (profile) {
290
+ krb5.profile_release ()(profile);
291
+ profile = nullptr ;
292
+ }
293
+ }
294
+
295
+ bool Kerberos::get_kerberos_config () {
296
+ assert (m_initialized);
297
+
298
+ static const char mysql_apps[] = " mysql" ;
299
+ static const char ldap_host_option[] = " ldap_server_host" ;
300
+ static const char ldap_destroy_option[] = " ldap_destroy_tgt" ;
301
+ krb5_principal principal (nullptr );
302
+ char *host_value = nullptr ;
303
+ bool result = true ;
304
+
305
+ log_dbg (" Getting kerberos configuration." );
306
+ m_ldap_server_host = " " ;
335
307
336
308
/*
337
- Get the LDAP destroy TGT from MySQL app section.
338
- If failed to get destroy TGT option, default option value will be false .
339
- This value is consistent with kerberos authentication usage as TGT was
340
- supposed to be used till it expires .
309
+ 1. Get ldap server host from [appdefaults] section, mysql application,
310
+ ldap_server_host option.
311
+ 2. If 1. failed, get from [realms] section, current realm, kdc option.
312
+ 3. If 2. failed, return failure .
341
313
*/
342
- res_kerberos = krb5.profile_get_boolean ()(profile, apps_heading, mysql_apps,
343
- ldap_destroy_option, m_destroy_tgt,
344
- (int *)&m_destroy_tgt);
314
+ auto res_kerberos =
315
+ krb5.krb5_parse_name ()(m_context, m_user.c_str (), &principal);
345
316
if (res_kerberos) {
346
- log_info (
347
- " get_kerberos_config: failed to get destroy TGT flag, default is set." );
317
+ log_error (" Failed to parse Kerberos client principal." );
318
+ result = false ;
319
+ goto EXIT;
348
320
}
321
+ krb5.krb5_appdefault_string ()(m_context, mysql_apps, &principal->realm ,
322
+ ldap_host_option, " " , &host_value);
323
+ if (host_value == nullptr || host_value[0 ] == 0 ) {
324
+ log_warning (" Failed to get LDAP server host from [appdefaults] section." );
325
+ get_ldap_server_from_kdc ();
326
+ } else
327
+ m_ldap_server_host = host_value;
349
328
350
- EXIT:
351
- if (host_value) {
352
- krb5. profile_release_string ()(host_value) ;
353
- host_value = nullptr ;
329
+ if (m_ldap_server_host. empty ()) {
330
+ log_error ( " Failed to get LDAP server host " );
331
+ result = false ;
332
+ goto EXIT ;
354
333
}
355
- if (default_realm) {
356
- krb5.krb5_free_default_realm ()(m_context, default_realm);
357
- default_realm = nullptr ;
334
+
335
+ log_dbg (" LDAP server host raw value: " , m_ldap_server_host.c_str ());
336
+
337
+ /* IPV6 */
338
+ if (m_ldap_server_host[0 ] == ' [' ) {
339
+ auto pos = m_ldap_server_host.find (" ]" );
340
+ if (pos != m_ldap_server_host.npos &&
341
+ (m_ldap_server_host.length () > (pos + 1 )) &&
342
+ (m_ldap_server_host[pos + 1 ] == ' :' )) {
343
+ m_ldap_server_host = m_ldap_server_host.substr (1 , pos - 1 );
344
+ }
358
345
}
359
- if (profile) {
360
- krb5.profile_release ()(profile);
361
- profile = nullptr ;
346
+ /* IPV4 */
347
+ else {
348
+ auto pos = m_ldap_server_host.find (" :" );
349
+ if (pos != m_ldap_server_host.npos ) {
350
+ m_ldap_server_host.erase (pos);
351
+ }
362
352
}
363
- return res_kerberos == 0 ;
353
+ log_info (" Processed LDAP server host: " , m_ldap_server_host.c_str ());
354
+
355
+ /*
356
+ Get the LDAP destroy TGT option from [appdefaults] section, mysql
357
+ application. If failed to get destroy TGT option, default option value will
358
+ be false. This value is consistent with kerberos authentication usage as TGT
359
+ was supposed to be used till it expires.
360
+ */
361
+ krb5.krb5_appdefault_boolean ()(m_context, mysql_apps, &principal->realm ,
362
+ ldap_destroy_option, 0 ,
363
+ reinterpret_cast <int *>(&m_destroy_tgt));
364
+
365
+ EXIT:
366
+ if (principal) krb5.krb5_free_principal ()(m_context, principal);
367
+ if (host_value) krb5.krb5_free_string ()(m_context, host_value);
368
+ return result;
364
369
}
365
370
366
371
bool Kerberos::credentials_valid () {
@@ -370,7 +375,6 @@ bool Kerberos::credentials_valid() {
370
375
krb5_timestamp krb_current_time = 0 ;
371
376
bool credentials_retrieve = false ;
372
377
krb5_creds matching_credential;
373
- char *realm = nullptr ;
374
378
375
379
memset (&matching_credential, 0 , sizeof (matching_credential));
376
380
memset (&credentials, 0 , sizeof (credentials));
@@ -390,15 +394,9 @@ bool Kerberos::credentials_valid() {
390
394
log_error (" Failed to parse Kerberos client principal." );
391
395
goto EXIT;
392
396
}
393
- res_kerberos = krb5.krb5_get_default_realm ()(m_context, &realm);
394
- if (res_kerberos) {
395
- log_error (" Failed to get default Kerberos realm." );
396
- goto EXIT;
397
- }
398
- log_info (" Default Kerberos realm is '" , realm, " '." );
399
- res_kerberos =
400
- krb5.krb5_build_principal ()(m_context, &matching_credential.server ,
401
- strlen (realm), realm, " krbtgt" , realm, NULL );
397
+ res_kerberos = krb5.krb5_build_principal ()(
398
+ m_context, &matching_credential.server , m_realm.length (), m_realm.c_str (),
399
+ " krbtgt" , m_realm.c_str (), NULL );
402
400
if (res_kerberos) {
403
401
log_error (" Failed to build Kerberos TGT principal." );
404
402
goto EXIT;
@@ -436,10 +434,6 @@ bool Kerberos::credentials_valid() {
436
434
437
435
EXIT:
438
436
if (res_kerberos) log (res_kerberos);
439
- if (realm) {
440
- krb5.krb5_free_default_realm ()(m_context, realm);
441
- realm = nullptr ;
442
- }
443
437
if (matching_credential.server ) {
444
438
krb5.krb5_free_principal ()(m_context, matching_credential.server );
445
439
}
0 commit comments