diff options
author | Andrew Bartlett <abartlet@samba.org> | 2007-04-28 16:38:06 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:51:43 -0500 |
commit | 729674054aa461b17a43a371f6891263d700ac7a (patch) | |
tree | e23ab3d59d95a505720791e27b2bfcf37c69ccc9 | |
parent | f34c57f4fc1a1817735ddb653011e6deb0edf912 (diff) | |
download | samba-729674054aa461b17a43a371f6891263d700ac7a.tar.gz samba-729674054aa461b17a43a371f6891263d700ac7a.tar.bz2 samba-729674054aa461b17a43a371f6891263d700ac7a.zip |
r22558: Move to a static list of enctypes to put into our keytab. In future,
I'll allow this to be configured from the secrets.ldb, but it should
fix some user issues.
Andrew Bartlett
(This used to be commit 0fd74ada220fb07d4ebe8c2d9b8ae50a387c2695)
-rw-r--r-- | source4/auth/credentials/credentials_krb5.c | 38 | ||||
-rw-r--r-- | source4/auth/kerberos/kerberos_util.c | 99 |
2 files changed, 74 insertions, 63 deletions
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index 7ba23ad9b6..69fb9e7b33 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -141,7 +141,10 @@ int cli_credentials_set_ccache(struct cli_credentials *cred, talloc_free(ccc); return ret; } - talloc_reference(ccc, ccc->smb_krb5_context); + if (!talloc_reference(ccc, ccc->smb_krb5_context)) { + talloc_free(ccc); + return ENOMEM; + } if (name) { ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache); @@ -218,7 +221,10 @@ int cli_credentials_new_ccache(struct cli_credentials *cred, struct ccache_conta talloc_free(ccc); return ret; } - talloc_reference(ccc, ccc->smb_krb5_context); + if (!talloc_reference(ccc, ccc->smb_krb5_context)) { + talloc_free(ccc); + return ENOMEM; + } ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name, &ccc->ccache); if (ret) { @@ -394,6 +400,7 @@ int cli_credentials_get_keytab(struct cli_credentials *cred, krb5_error_code ret; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; + const char **enctype_strings; TALLOC_CTX *mem_ctx; if (cred->keytab_obtained >= (MAX(cred->principal_obtained, @@ -416,7 +423,11 @@ int cli_credentials_get_keytab(struct cli_credentials *cred, return ENOMEM; } - ret = smb_krb5_create_memory_keytab(mem_ctx, cred, smb_krb5_context, &ktc); + enctype_strings = cli_credentials_get_enctype_strings(cred); + + ret = smb_krb5_create_memory_keytab(mem_ctx, cred, + smb_krb5_context, + enctype_strings, &ktc); if (ret) { talloc_free(mem_ctx); return ret; @@ -478,6 +489,7 @@ int cli_credentials_update_keytab(struct cli_credentials *cred) krb5_error_code ret; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; + const char **enctype_strings; TALLOC_CTX *mem_ctx; mem_ctx = talloc_new(cred); @@ -491,13 +503,15 @@ int cli_credentials_update_keytab(struct cli_credentials *cred) return ret; } + enctype_strings = cli_credentials_get_enctype_strings(cred); + ret = cli_credentials_get_keytab(cred, &ktc); if (ret != 0) { talloc_free(mem_ctx); return ret; } - ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, ktc); + ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, ktc); talloc_free(mem_ctx); return ret; @@ -594,6 +608,22 @@ int cli_credentials_get_kvno(struct cli_credentials *cred) return cred->kvno; } + +const char **cli_credentials_get_enctype_strings(struct cli_credentials *cred) +{ + /* If this is ever made user-configurable, we need to add code + * to remove/hide the other entries from the generated + * keytab */ + static const char *default_enctypes[] = { + "des-cbc-md5", + "aes256-cts-hmac-sha1-96", + "des3-cbc-sha1", + "arcfour-hmac-md5", + NULL + }; + return default_enctypes; +} + const char *cli_credentials_get_salt_principal(struct cli_credentials *cred) { return cred->salt_principal; diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 78fc95b649..631cc2d11f 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -273,17 +273,6 @@ int smb_krb5_open_keytab(TALLOC_CTX *mem_ctx, return 0; } -struct enctypes_container { - struct smb_krb5_context *smb_krb5_context; - krb5_enctype *enctypes; -}; - -static int free_enctypes(struct enctypes_container *etc) -{ - free_kerberos_etypes(etc->smb_krb5_context->krb5_context, etc->enctypes); - return 0; -} - static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx, const char *princ_string, krb5_principal princ, @@ -291,45 +280,34 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx, int kvno, const char *password_s, struct smb_krb5_context *smb_krb5_context, + const char **enctype_strings, krb5_keytab keytab) { int i; krb5_error_code ret; - krb5_enctype *enctypes; - char *enctype_string; - struct enctypes_container *etc; krb5_data password; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); if (!mem_ctx) { return ENOMEM; } - etc = talloc(mem_ctx, struct enctypes_container); - if (!etc) { - talloc_free(mem_ctx); - return ENOMEM; - } - ret = get_kerberos_allowed_etypes(smb_krb5_context->krb5_context, - &enctypes); - if (ret != 0) { - DEBUG(1,("keytab_add_keys: getting encrption types failed (%s)\n", - error_message(ret))); - talloc_free(mem_ctx); - return ret; - } - - etc->smb_krb5_context = talloc_reference(etc, smb_krb5_context); - etc->enctypes = enctypes; - - talloc_set_destructor(etc, free_enctypes); - password.data = discard_const_p(char *, password_s); password.length = strlen(password_s); - for (i=0; enctypes[i]; i++) { + for (i=0; enctype_strings[i]; i++) { krb5_keytab_entry entry; + krb5_enctype enctype; + ret = krb5_string_to_enctype(smb_krb5_context->krb5_context, enctype_strings[i], &enctype); + if (ret != 0) { + DEBUG(1, ("Failed to interpret %s as a krb5 encryption type: %s\n", + enctype_strings[i], + smb_get_krb5_error_message(smb_krb5_context->krb5_context, + ret, mem_ctx))); + talloc_free(mem_ctx); + return ret; + } ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context, - salt_princ, &password, &entry.keyblock, enctypes[i]); + salt_princ, &password, &entry.keyblock, enctype); if (ret != 0) { talloc_free(mem_ctx); return ret; @@ -338,25 +316,21 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx, entry.principal = princ; entry.vno = kvno; ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry); - enctype_string = NULL; - krb5_enctype_to_string(smb_krb5_context->krb5_context, enctypes[i], &enctype_string); if (ret != 0) { DEBUG(1, ("Failed to add %s entry for %s(kvno %d) to keytab: %s\n", - enctype_string, + enctype_strings[i], princ_string, kvno, smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); talloc_free(mem_ctx); - free(enctype_string); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); return ret; } DEBUG(5, ("Added %s(kvno %d) to keytab (%s)\n", princ_string, kvno, - enctype_string)); - free(enctype_string); + enctype_strings[i])); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); } @@ -367,12 +341,12 @@ static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx, static int create_keytab(TALLOC_CTX *parent_ctx, struct cli_credentials *machine_account, struct smb_krb5_context *smb_krb5_context, + const char **enctype_strings, krb5_keytab keytab, BOOL add_old) { krb5_error_code ret; const char *password_s; - char *enctype_string; const char *old_secret; int kvno; krb5_principal salt_princ; @@ -410,11 +384,18 @@ static int create_keytab(TALLOC_CTX *parent_ctx, /* Finally, do the dance to get the password to put in the entry */ password_s = cli_credentials_get_password(machine_account); if (!password_s) { - /* If we don't have the plaintext password, try for - * the MD4 password hash */ - krb5_keytab_entry entry; const struct samr_Password *mach_pwd; + + if (!str_list_check(enctype_strings, "arcfour-hmac-md5")) { + DEBUG(1, ("Asked to create keytab, but with only an NT hash supplied, " + "but not listing arcfour-hmac-md5 as an enc type to include in the keytab!\n")); + talloc_free(mem_ctx); + return EINVAL; + } + + /* If we don't have the plaintext password, try for + * the MD4 password hash */ mach_pwd = cli_credentials_get_nt_hash(machine_account, mem_ctx); if (!mach_pwd) { /* OK, nothing to do here */ @@ -446,14 +427,9 @@ static int create_keytab(TALLOC_CTX *parent_ctx, return ret; } - krb5_enctype_to_string(smb_krb5_context->krb5_context, - ETYPE_ARCFOUR_HMAC_MD5, - &enctype_string); - DEBUG(5, ("Added %s(kvno %d) to keytab (%s)\n", + DEBUG(5, ("Added %s(kvno %d) to keytab (arcfour-hmac-md5)\n", cli_credentials_get_principal(machine_account, mem_ctx), - cli_credentials_get_kvno(machine_account), - enctype_string)); - free(enctype_string); + cli_credentials_get_kvno(machine_account))); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); @@ -465,7 +441,8 @@ static int create_keytab(TALLOC_CTX *parent_ctx, kvno = cli_credentials_get_kvno(machine_account); /* good, we actually have the real plaintext */ ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ, - kvno, password_s, smb_krb5_context, keytab); + kvno, password_s, smb_krb5_context, + enctype_strings, keytab); if (!ret) { talloc_free(mem_ctx); return ret; @@ -483,7 +460,8 @@ static int create_keytab(TALLOC_CTX *parent_ctx, } ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ, - kvno - 1, old_secret, smb_krb5_context, keytab); + kvno - 1, old_secret, smb_krb5_context, + enctype_strings, keytab); if (!ret) { talloc_free(mem_ctx); return ret; @@ -627,6 +605,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, int smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, struct cli_credentials *machine_account, struct smb_krb5_context *smb_krb5_context, + const char **enctype_strings, struct keytab_container *keytab_container) { krb5_error_code ret; @@ -635,7 +614,7 @@ int smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, if (!mem_ctx) { return ENOMEM; } - + ret = remove_old_entries(mem_ctx, machine_account, smb_krb5_context, keytab_container->keytab, &found_previous); if (ret != 0) { @@ -648,6 +627,7 @@ int smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, * Otherwise, add kvno, and kvno -1 */ ret = create_keytab(mem_ctx, machine_account, smb_krb5_context, + enctype_strings, keytab_container->keytab, found_previous ? False : True); talloc_free(mem_ctx); @@ -655,9 +635,10 @@ int smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, } _PUBLIC_ int smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx, - struct cli_credentials *machine_account, - struct smb_krb5_context *smb_krb5_context, - struct keytab_container **keytab_container) + struct cli_credentials *machine_account, + struct smb_krb5_context *smb_krb5_context, + const char **enctype_strings, + struct keytab_container **keytab_container) { krb5_error_code ret; TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); @@ -687,7 +668,7 @@ _PUBLIC_ int smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx, return ret; } - ret = smb_krb5_update_keytab(mem_ctx, machine_account, smb_krb5_context, *keytab_container); + ret = smb_krb5_update_keytab(mem_ctx, machine_account, smb_krb5_context, enctype_strings, *keytab_container); if (ret == 0) { talloc_steal(parent_ctx, *keytab_container); } else { |