1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

r6701: Updates to our server-side ticket verification code, we now use the

client credentials code to read the secrets.ldb.

Also clean up error handling, and ensure to always set the
last_error_message stuff.

Andrew Bartlett
(This used to be commit 435d229e5d)
This commit is contained in:
Andrew Bartlett 2005-05-10 09:59:47 +00:00 committed by Gerald (Jerry) Carter
parent 69f3a934d7
commit a21b7de463

View File

@ -112,8 +112,9 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex
ret = krb5_kt_default(context, &keytab); ret = krb5_kt_default(context, &keytab);
if (ret) { if (ret) {
last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx);
DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n",
smb_get_krb5_error_message(context, ret, mem_ctx))); last_error_message));
goto out; goto out;
} }
@ -122,15 +123,13 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex
* try verifying the ticket using that principal. */ * try verifying the ticket using that principal. */
ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
if (ret) { if (ret == KRB5_KT_END || ret == ENOENT ) {
last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx);
} else if (ret) {
last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx); last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx);
DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n",
last_error_message)); last_error_message));
goto out; } else {
}
ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
if (ret != KRB5_KT_END && ret != ENOENT ) {
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; /* Pick an error... */ ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; /* Pick an error... */
while (ret && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { while (ret && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {
krb5_error_code upn_ret; krb5_error_code upn_ret;
@ -219,7 +218,9 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex
Try to verify a ticket using the secrets.tdb. Try to verify a ticket using the secrets.tdb.
***********************************************************************************/ ***********************************************************************************/
static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_context context, 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_auth_context auth_context,
krb5_principal host_princ, krb5_principal host_princ,
const DATA_BLOB *ticket, krb5_data *p_packet, const DATA_BLOB *ticket, krb5_data *p_packet,
@ -231,43 +232,16 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte
krb5_data password; krb5_data password;
krb5_enctype *enctypes = NULL; krb5_enctype *enctypes = NULL;
int i; int i;
const struct ldb_val *password_v; char *password_s = talloc_strdup(mem_ctx, cli_credentials_get_password(machine_account));
struct ldb_context *ldb; if (!password_s) {
int ldb_ret; DEBUG(1, ("ads_secrets_verify_ticket: Could not obtain password for our local machine account!\n"));
struct ldb_message **msgs; return ENOENT;
const char *base_dn = SECRETS_PRIMARY_DOMAIN_DN; }
const char *attrs[] = {
"secret",
NULL
};
ZERO_STRUCTP(keyblock); ZERO_STRUCTP(keyblock);
/* Local secrets are stored in secrets.ldb */ password.data = password_s;
ldb = secrets_db_connect(mem_ctx); password.length = strlen(password_s);
if (!ldb) {
return ENOENT;
}
/* search for the secret record */
ldb_ret = gendb_search(ldb,
mem_ctx, base_dn, &msgs, attrs,
SECRETS_PRIMARY_REALM_FILTER,
lp_realm());
if (ldb_ret == 0) {
DEBUG(1, ("Could not find domain join record for %s\n",
lp_realm()));
return ENOENT;
} else if (ldb_ret != 1) {
DEBUG(1, ("Found %d records matching cn=%s under DN %s\n", ldb_ret,
lp_realm(), base_dn));
return ENOENT;
}
password_v = ldb_msg_find_ldb_val(msgs[0], "secret");
password.data = password_v->data;
password.length = password_v->length;
/* CIFS doesn't use addresses in tickets. This would break NAT. JRA */ /* CIFS doesn't use addresses in tickets. This would break NAT. JRA */
@ -358,16 +332,6 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte
like. We have to go through all this to allow us to store like. We have to go through all this to allow us to store
the secret internally, instead of using /etc/krb5.keytab */ the secret internally, instead of using /etc/krb5.keytab */
asprintf(&host_princ_s, "%s$", lp_netbios_name());
strlower_m(host_princ_s);
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)));
goto out;
}
/* Lock a mutex surrounding the replay as there is no locking in the MIT krb5 /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5
* code surrounding the replay cache... */ * code surrounding the replay cache... */
@ -397,18 +361,41 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx, krb5_conte
ret = ads_keytab_verify_ticket(mem_ctx, context, auth_context, ret = ads_keytab_verify_ticket(mem_ctx, context, auth_context,
service, ticket, &packet, &tkt, keyblock); service, ticket, &packet, &tkt, keyblock);
if (ret) { if (ret) {
DEBUG(10, ("ads_secrets_verify_ticket: using host principal: [%s]\n", host_princ_s)); NTSTATUS creds_nt_status;
ret = ads_secrets_verify_ticket(mem_ctx, context, auth_context, struct cli_credentials *credentials;
host_princ, ticket, credentials = cli_credentials_init(mem_ctx);
&packet, &tkt, keyblock); 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 = talloc_strlower(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);
}
}
} }
release_server_mutex(); release_server_mutex();
got_replay_mutex = False; got_replay_mutex = False;
if (ret) { if (ret) {
DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
smb_get_krb5_error_message(context, ret, mem_ctx)));
goto out; goto out;
} }