diff options
author | <Mark.Phalan@Sun.COM> | 2009-02-11 10:16:20 -0800 |
---|---|---|
committer | <Mark.Phalan@Sun.COM> | 2009-02-11 10:16:20 -0800 |
commit | db02be5754449d8a49e2d5a695ba0237d964b5dc (patch) | |
tree | a983e59c1b7a4ed9693f4e485caf79fa78fdb091 /usr/src | |
parent | 8c067cfd3aea0c49a166f9fb38114b56a9160ac6 (diff) | |
download | illumos-joyent-db02be5754449d8a49e2d5a695ba0237d964b5dc.tar.gz |
6777148 idmap fails to auto-discover AD due to ldap_sasl_bind failure
Diffstat (limited to 'usr/src')
7 files changed, 177 insertions, 10 deletions
diff --git a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com index 4b3e8cfac8..e5fcb20aac 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/Makefile.com +++ b/usr/src/lib/gss_mechs/mech_krb5/Makefile.com @@ -122,7 +122,7 @@ K5_CC= cc_file.o cc_memory.o ccbase.o ccfns.o ccdefault.o ccdefops.o ser_cc.o cc # krb5/keytab K5_KT= ktadd.o ktbase.o ktdefault.o ktfr_entry.o \ - ktremove.o read_servi.o kt_file.o kt_srvtab.o ktfns.o + ktremove.o read_servi.o kt_file.o kt_srvtab.o ktfns.o kt_findrealm.o K5_KRB= addr_comp.o addr_order.o addr_srch.o \ auth_con.o bld_pr_ext.o bld_princ.o chk_trans.o \ diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_findrealm.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_findrealm.c new file mode 100644 index 0000000000..02962a5c67 --- /dev/null +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_findrealm.c @@ -0,0 +1,87 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Solaris Kerberos: + * Iterate through a keytab (keytab) looking for an entry which matches + * the components of a principal (princ) but match on any realm. When a + * suitable entry is found return the entry's realm. + */ + +#include "k5-int.h" + +krb5_error_code krb5_kt_find_realm(krb5_context context, krb5_keytab keytab, + krb5_principal princ, krb5_data *realm) { + + krb5_kt_cursor cur; + krb5_keytab_entry ent; + krb5_boolean match; + krb5_data tmp_realm; + krb5_error_code ret, ret2; + + ret = krb5_kt_start_seq_get(context, keytab, &cur); + if (ret != 0) { + return (ret); + } + + while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cur)) == 0) { + /* For the comparison the realms should be the same. */ + memcpy(&tmp_realm, &ent.principal->realm, sizeof (krb5_data)); + memcpy(&ent.principal->realm, &princ->realm, + sizeof (krb5_data)); + + match = krb5_principal_compare(context, ent.principal, princ); + + /* Copy the realm back */ + memcpy(&ent.principal->realm, &tmp_realm, sizeof (krb5_data)); + + if (match) { + /* + * A suitable entry was found in the keytab. + * Copy its realm + */ + ret = krb5int_copy_data_contents(context, + &ent.principal->realm, realm); + if (ret) { + krb5_kt_free_entry(context, &ent); + krb5_kt_end_seq_get(context, keytab, &cur); + return (ret); + } + + krb5_kt_free_entry(context, &ent); + break; + } + + krb5_kt_free_entry(context, &ent); + } + + ret2 = krb5_kt_end_seq_get(context, keytab, &cur); + + if (ret == KRB5_KT_END) { + return (KRB5_KT_NOTFOUND); + } + + return (ret ? ret : ret2); +} diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c index 351d5917ae..24af0d668f 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +30,10 @@ * or implied warranty. */ +/* Solaris Kerberos */ +#include <libintl.h> +#include <locale.h> + #include "k5-int.h" /*ARGSUSED*/ @@ -109,6 +113,39 @@ krb5_get_init_creds_keytab(krb5_context context, if (ret) return ret; + /* + * Solaris Kerberos: + * If "client" was constructed from krb5_sname_to_princ() it may + * have a referral realm. This happens when there is no applicable + * domain-to-realm mapping in the Kerberos configuration file. + * If that is the case then the realm of the first principal found + * in the keytab which matches the client can be used for the client's + * realm. + */ + if (krb5_is_referral_realm(&client->realm)) { + krb5_data realm; + ret = krb5_kt_find_realm(context, keytab, client, &realm); + if (ret == 0) { + krb5_free_data_contents(context, &client->realm); + client->realm.length = realm.length; + client->realm.data = realm.data; + } else { + /* Try to set a useful error message */ + char *princ = NULL; + krb5_unparse_name(context, client, &princ); + + krb5_set_error_message(context, ret, + gettext("Failed to find realm for %s in keytab"), + princ ? princ : "<unknown>"); + if (princ) + krb5_free_unparsed_name(context, princ); + } + } + + if (ret != 0) + goto cleanup; + + use_master = 0; /* first try: get the requested tkt from any kdc */ diff --git a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c index 0d127d4eea..b4017aa0bc 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c +++ b/usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -797,7 +797,13 @@ krb5int_locate_server (krb5_context context, const krb5_data *realm, code = prof_locate_server(context, realm, &al, svc, socktype, family); #ifdef KRB5_DNS_LOOKUP - if (code) { /* Try DNS for all profile errors? */ + /* + * Solaris Kerberos: + * There is no point in trying to locate the KDC in DNS if "realm" + * is empty. + */ + /* Try DNS for all profile errors? */ + if (code && !krb5_is_referral_realm(realm)) { krb5_error_code code2; code2 = dns_locate_server(context, realm, &al, svc, socktype, family); diff --git a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers index 9d920f65af..a65dffdc99 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers +++ b/usr/src/lib/gss_mechs/mech_krb5/mapfile-vers @@ -552,6 +552,7 @@ SUNWprivate_1.1 { krb5_kt_default_name; krb5_kt_dfl_ops; krb5_kt_end_seq_get; + krb5_kt_find_realm; krb5_kt_free_entry; krb5_kt_get_entry; krb5_kt_get_name; diff --git a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c index 811de69cf4..012e710c6a 100644 --- a/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c +++ b/usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -76,6 +76,10 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* Solaris Kerberos */ +#include <libintl.h> +#include <locale.h> + #include "k5-int.h" #include "gss_libinit.h" #include "gssapiP_krb5.h" @@ -1064,8 +1068,11 @@ principal_ignore_inst_compare(context, princ1, princ2) if (nelem != krb5_princ_size(context, princ2)) return FALSE; - if (! krb5_realm_compare(context, princ1, princ2)) - return FALSE; + /* + * Solaris Kerberos: + * Don't bother to compare the realms as princ1 will always have a + * referral realm set. + */ /* * Solaris Kerberos @@ -1288,12 +1295,15 @@ get_instance_keytab( register const krb5_data *p; char *realm=NULL, *s=NULL; krb5_principal client=NULL, princ=NULL; + size_t realm_size = strlen(KRB5_REFERRAL_REALM) + 1; if (!keytab) return EINVAL; - if (ret = krb5_get_default_realm(context, &realm)) - return ret; + realm = malloc(realm_size); + if (realm == NULL) + return (ENOMEM); + strlcpy(realm, KRB5_REFERRAL_REALM, realm_size); ret = krb5_build_principal(context, &client, strlen(realm), realm, sname, "*", @@ -1387,6 +1397,28 @@ load_root_cred_using_keytab( code = krb5_sname_to_principal(context, NULL, sname, KRB5_NT_SRV_HST, &me); } + + /* Solaris Kerberos */ + if (krb5_is_referral_realm(&me->realm)) { + krb5_data realm; + code = krb5_kt_find_realm(context, keytab, me, &realm); + if (code == 0) { + krb5_free_data_contents(context, &me->realm); + me->realm.length = realm.length; + me->realm.data = realm.data; + } else { + /* Try to set a useful error message */ + char *princ = NULL; + krb5_unparse_name(context, me, &princ); + + krb5_set_error_message(context, code, + gettext("Failed to find realm for %s in keytab"), + princ ? princ : "<unknown>"); + if (princ) + krb5_free_unparsed_name(context, princ); + } + } + if (code) { (void) krb5_kt_close(context, keytab); *minor_status = code; diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h b/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h index 3147259a7c..d587f0f557 100644 --- a/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h +++ b/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1452,6 +1452,10 @@ krb5_kt_next_entry(krb5_context context, krb5_keytab keytab, krb5_error_code KRB5_CALLCONV krb5_kt_end_seq_get(krb5_context context, krb5_keytab keytab, krb5_kt_cursor *cursor); +/* Solaris Kerberos */ +krb5_error_code +krb5_kt_find_realm(krb5_context context, krb5_keytab keytab, + krb5_principal princ, krb5_data *realm); /* * end "keytab.h" |