summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
author <Mark.Phalan@Sun.COM>2009-02-11 10:16:20 -0800
committer <Mark.Phalan@Sun.COM>2009-02-11 10:16:20 -0800
commitdb02be5754449d8a49e2d5a695ba0237d964b5dc (patch)
treea983e59c1b7a4ed9693f4e485caf79fa78fdb091 /usr/src
parent8c067cfd3aea0c49a166f9fb38114b56a9160ac6 (diff)
downloadillumos-joyent-db02be5754449d8a49e2d5a695ba0237d964b5dc.tar.gz
6777148 idmap fails to auto-discover AD due to ldap_sasl_bind failure
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/Makefile.com2
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/keytab/kt_findrealm.c87
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/krb/gic_keytab.c39
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/krb5/os/locate_kdc.c10
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mapfile-vers1
-rw-r--r--usr/src/lib/gss_mechs/mech_krb5/mech/init_sec_context.c42
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h6
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"