summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/kerberos/kerberos_verify.c100
1 files changed, 60 insertions, 40 deletions
diff --git a/source4/auth/kerberos/kerberos_verify.c b/source4/auth/kerberos/kerberos_verify.c
index 4cd48ed63b..927b12d454 100644
--- a/source4/auth/kerberos/kerberos_verify.c
+++ b/source4/auth/kerberos/kerberos_verify.c
@@ -222,7 +222,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
struct cli_credentials *machine_account,
krb5_context context,
krb5_auth_context auth_context,
- krb5_principal host_princ,
+ krb5_principal salt_princ,
const DATA_BLOB *ticket, krb5_data *p_packet,
krb5_ticket **pp_tkt,
krb5_keyblock *keyblock)
@@ -237,7 +237,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
DEBUG(1, ("ads_secrets_verify_ticket: Could not obtain password for our local machine account!\n"));
return ENOENT;
}
-
+
ZERO_STRUCTP(keyblock);
password.data = password_s;
@@ -248,6 +248,8 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
DEBUG(1,("ads_secrets_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n",
error_message(ret)));
+
+ krb5_free_principal(context, salt_princ);
return ret;
}
@@ -264,7 +266,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
break;
}
- if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
+ if (create_kerberos_key_from_string(context, salt_princ, &password, key, enctypes[i])) {
SAFE_FREE(key);
continue;
}
@@ -318,16 +320,62 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
krb5_rcache rcache = NULL;
int ret;
- krb5_principal host_princ = NULL;
- char *host_princ_s = NULL;
BOOL got_replay_mutex = False;
char *malloc_principal;
+ char *machine_username;
+ krb5_principal salt_princ = NULL;
+
+ NTSTATUS creds_nt_status;
+ struct cli_credentials *machine_account;
ZERO_STRUCT(packet);
ZERO_STRUCTP(auth_data);
ZERO_STRUCTP(ap_rep);
+ machine_account = cli_credentials_init(mem_ctx);
+ cli_credentials_set_conf(machine_account);
+ creds_nt_status = cli_credentials_set_machine_account(machine_account);
+
+ if (!NT_STATUS_IS_OK(creds_nt_status)) {
+ DEBUG(3, ("Could not obtain machine account credentials from the local database\n"));
+
+ /* This just becomes a locking key, if we don't have creds, we must be using the keytab */
+ ret = krb5_make_principal(context, &salt_princ, lp_realm(),
+ "host", lp_netbios_name(), NULL);
+ } else {
+
+ machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account));
+
+ if (!machine_username) {
+ ret = ENOMEM;
+ } else {
+ char *salt_body;
+ char *lower_realm = strlower_talloc(mem_ctx, cli_credentials_get_realm(machine_account));;
+ if (machine_username[strlen(machine_username)-1] == '$') {
+ machine_username[strlen(machine_username)-1] = '\0';
+ }
+ if (!lower_realm) {
+ ret = ENOMEM;
+ } else {
+ salt_body = talloc_asprintf(mem_ctx, "%s.%s", machine_username,
+ lower_realm);
+ if (!salt_body) {
+ ret = ENOMEM;
+ } else {
+ ret = krb5_make_principal(context, &salt_princ, cli_credentials_get_realm(machine_account),
+ "host", salt_body, NULL);
+ }
+ }
+ }
+ }
+
+ if (ret) {
+ DEBUG(1,("ads_verify_ticket: maksing salt principal failed (%s)\n",
+ error_message(ret)));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
/* This whole process is far more complex than I would
like. We have to go through all this to allow us to store
the secret internally, instead of using /etc/krb5.keytab */
@@ -346,7 +394,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
* JRA. We must set the rcache here. This will prevent replay attacks.
*/
- ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache);
+ ret = krb5_get_server_rcache(context, krb5_princ_component(context, salt_princ, 0), &rcache);
if (ret) {
DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret)));
goto out;
@@ -361,35 +409,9 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
ret = ads_keytab_verify_ticket(mem_ctx, context, auth_context,
service, ticket, &packet, &tkt, keyblock);
if (ret) {
- NTSTATUS creds_nt_status;
- struct cli_credentials *credentials;
- credentials = cli_credentials_init(mem_ctx);
- cli_credentials_set_conf(credentials);
- creds_nt_status = cli_credentials_set_machine_account(credentials);
-
- if (!NT_STATUS_IS_OK(creds_nt_status)) {
- DEBUG(3, ("Could not obtain machine account credentials from the local database\n"));
- } else {
-
- host_princ_s = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name());
- host_princ_s = strlower_talloc(mem_ctx, host_princ_s);
- if (!host_princ_s) {
- ret = ENOMEM;
- } else {
- ret = krb5_parse_name(context, host_princ_s, &host_princ);
- }
-
- if (ret) {
- DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
- host_princ_s, error_message(ret)));
- } else {
-
- DEBUG(10, ("ads_secrets_verify_ticket: using host principal: [%s]\n", host_princ_s));
- ret = ads_secrets_verify_ticket(mem_ctx, credentials, context, auth_context,
- host_princ, ticket,
- &packet, &tkt, keyblock);
- }
- }
+ ret = ads_secrets_verify_ticket(mem_ctx, machine_account, context, auth_context,
+ salt_princ, ticket,
+ &packet, &tkt, keyblock);
}
release_server_mutex();
@@ -458,15 +480,13 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
data_blob_free(ap_rep);
}
- if (host_princ) {
- krb5_free_principal(context, host_princ);
- }
-
if (tkt != NULL) {
krb5_free_ticket(context, tkt);
}
- SAFE_FREE(host_princ_s);
+ if (salt_princ != NULL) {
+ krb5_free_principal(context, salt_princ);
+ }
return sret;
}