summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/kerberos_keytab.c114
1 files changed, 62 insertions, 52 deletions
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 9fc3410e5c..97e68f2bcb 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -60,7 +60,6 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads)
krb5_data password;
krb5_enctype *enctypes = NULL;
krb5_kvno kvno;
- krb5_keyblock *key = NULL;
char *principal = NULL;
char *princ_s = NULL;
@@ -95,12 +94,6 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads)
goto out;
}
- ret = get_kerberos_allowed_etypes(context,&enctypes);
- if (ret) {
- DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret)));
- goto out;
- }
-
/* retrieve the password */
if (!secrets_init()) {
DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n"));
@@ -139,8 +132,9 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads)
if (ret != KRB5_KT_END && ret != ENOENT ) {
DEBUG(3,("ads_keytab_add_entry: Will try to delete old keytab entries\n"));
while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
+ BOOL compare_ok = False;
- ret = krb5_unparse_name(context, entry.principal, &ktprinc);
+ ret = krb5_unparse_name(context, kt_entry.principal, &ktprinc);
if (ret) {
DEBUG(1,("ads_keytab_add_entry: krb5_unparse_name failed (%s)\n", error_message(ret)));
goto out;
@@ -155,96 +149,112 @@ int ads_keytab_add_entry(const char *srvPrinc, ADS_STRUCT *ads)
* with the new kvno.
*/
- HERE
-
#ifdef HAVE_KRB5_KT_COMPARE
- if (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True && kt_entry.vno != kvno - 1) {
+ compare_ok = ((krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True) && (kt_entry.vno != kvno - 1));
#else
- if (strcmp(ktprinc, princ_s) == 0 && kt_entry.vno != kvno - 1) {
+ compare_ok = ((strcmp(ktprinc, princ_s) == 0) && (kt_entry.vno != kvno - 1));
#endif
- SAFE_FREE(ktprinc);
- DEBUG(1,("Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
- princ_s, entry.vno));
+ SAFE_FREE(ktprinc);
+
+ if (compare_ok) {
+ DEBUG(3,("ads_keytab_add_entry: Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
+ princ_s, kt_entry.vno));
ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+ cursor = NULL;
if (ret) {
- DEBUG(1,("krb5_kt_end_seq_get() failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get() failed (%s)\n",
+ error_message(ret)));
goto out;
}
- ret = krb5_kt_remove_entry(context, keytab, &entry);
+ ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
if (ret) {
- DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n",
+ error_message(ret)));
goto out;
}
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if (ret) {
- DEBUG(1,("krb5_kt_start_seq failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_start_seq failed (%s)\n",
+ error_message(ret)));
goto out;
}
- ret = krb5_kt_free_entry(context, &entry);
+ ret = krb5_kt_free_entry(context, &kt_entry);
+ ZERO_STRUCT(kt_entry);
if (ret) {
- DEBUG(1,("krb5_kt_remove_entry failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_remove_entry failed (%s)\n",
+ error_message(ret)));
goto out;
}
continue;
- } else {
- SAFE_FREE(ktprinc);
}
- ret = krb5_kt_free_entry(context, &entry);
+ /* Not a match, just free this entry and continue. */
+ ret = krb5_kt_free_entry(context, &kt_entry);
+ ZERO_STRUCT(kt_entry);
if (ret) {
- DEBUG(1,("krb5_kt_free_entry failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_free_entry failed (%s)\n", error_message(ret)));
goto out;
}
}
ret = krb5_kt_end_seq_get(context, keytab, &cursor);
+ cursor = NULL;
if (ret) {
- DEBUG(1,("krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
+ DEBUG(1,("ads_keytab_add_entry: krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
goto out;
}
}
- /* Add keytab entries for all encryption types */
- for (i = 0; enctypes[i]; i++) {
+ /* Ensure we don't double free. */
+ ZERO_STRUCT(kt_entry);
+ cursor = NULL;
- key = (krb5_keyblock *) malloc(sizeof(*key));
- if (!key) {
- DEBUG(1,("Failed to allocate memory to store the keyblock.\n"));
- ret = ENOMEM;
- goto out;
- }
+ /* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */
- if (create_kerberos_key_from_string(context, princ, &password, key, enctypes[i])) {
- continue;
- }
+ ret = get_kerberos_allowed_etypes(context,&enctypes);
+ if (ret) {
+ DEBUG(1,("ads_keytab_add_entry: get_kerberos_allowed_etypes failed (%s)\n",error_message(ret)));
+ goto out;
+ }
- entry.principal = princ;
- entry.vno = kvno;
+ /* Now add keytab entries for all encryption types */
+ for (i = 0; enctypes[i]; i++) {
+ krb5_keyblock *keyp;
#if !defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) && !defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK)
#error krb5_keytab_entry has no key or keyblock member
#endif
#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */
- entry.key = *key;
+ keyp = &kt_entry.key;
#endif
#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
- entry.keyblock = *key;
+ keyp = &kt_entry.keyblock;
#endif
- DEBUG(3,("adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
- princ_s, enctypes[i], entry.vno));
- ret = krb5_kt_add_entry(context, keytab, &entry);
- krb5_free_keyblock(context, key);
+ if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i])) {
+ continue;
+ }
+
+ kt_entry.principal = princ;
+ kt_entry.vno = kvno;
+
+ DEBUG(3,("ads_keytab_add_entry: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
+ princ_s, enctypes[i], kt_entry.vno));
+ ret = krb5_kt_add_entry(context, keytab, &kt_entry);
+ krb5_free_keyblock(context, keyp);
+ ZERO_STRUCT(kt_entry);
if (ret) {
- DEBUG(1,("adding entry to keytab failed (%s)\n", error_message(ret)));
- krb5_kt_close(context, keytab);
+ DEBUG(1,("ads_keytab_add_entry: adding entry to keytab failed (%s)\n", error_message(ret)));
goto out;
}
}
+ krb5_kt_close(context, keytab);
+ keytab = NULL; /* Done with keytab now. No double free. */
+
/* Update the LDAP with the SPN */
- DEBUG(1,("Attempting to add/update '%s'\n", princ_s));
+ DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s));
if (!ADS_ERR_OK(ads_add_spn(ads, global_myname(), srvPrinc))) {
- DEBUG(1,("ads_add_spn failed.\n"));
+ DEBUG(1,("ads_keytab_add_entry: ads_add_spn failed.\n"));
goto out;
}
@@ -279,10 +289,10 @@ out:
return (int)ret;
}
-
-/*
+/**********************************************************************
Flushes all entries from the system keytab.
-*/
+***********************************************************************/
+
int ads_keytab_flush(ADS_STRUCT *ads)
{
krb5_error_code ret;