summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorGlenn Barry <Glenn.Barry@Sun.COM>2009-09-21 16:47:51 -0700
committerGlenn Barry <Glenn.Barry@Sun.COM>2009-09-21 16:47:51 -0700
commitba7b222e36bac28710a7f43739283302b617e7f5 (patch)
treef864f6d889ae7a00f9b8c9577cc94f7dff53e1c2 /usr/src/uts
parent22edf370974e46eb43b66530dd2d862b0d0a9533 (diff)
downloadillumos-joyent-ba7b222e36bac28710a7f43739283302b617e7f5.tar.gz
PSARC 2009/418 Kerberos V5 PAC API
6283931 SPNEGO needs to follow latest RFC 6808598 krb5 APIs needed to create and parse PAC data 6817447 libgss and various mechs are hiding both the real minor_status and the error token
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/gssapi/gen_oids.c7
-rw-r--r--usr/src/uts/common/gssapi/gssapi_ext.h45
-rw-r--r--usr/src/uts/common/gssapi/gssd_clnt_stubs.c50
-rw-r--r--usr/src/uts/common/gssapi/include/mechglueP.h74
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h19
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h140
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h31
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h95
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h18
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h135
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c230
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c200
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c328
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c7
-rw-r--r--usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c81
15 files changed, 1173 insertions, 287 deletions
diff --git a/usr/src/uts/common/gssapi/gen_oids.c b/usr/src/uts/common/gssapi/gen_oids.c
index 6e2650eb81..3e2c0e9552 100644
--- a/usr/src/uts/common/gssapi/gen_oids.c
+++ b/usr/src/uts/common/gssapi/gen_oids.c
@@ -1,10 +1,8 @@
/*
- * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -66,6 +64,8 @@ static const gss_OID_desc oids[] = {
{6, "\053\006\001\005\006\002"},
{6, "\053\006\001\005\006\003"},
{6, "\053\006\001\005\006\004"},
+ {11, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"},
+
};
const gss_OID_desc * const gss_nt_user_name = oids+0;
@@ -93,3 +93,4 @@ const gss_OID GSS_C_NT_STRING_UID_NAME = (gss_OID)oids+2;
const gss_OID GSS_C_NT_HOSTBASED_SERVICE = (gss_OID)oids+4;
const gss_OID GSS_C_NT_ANONYMOUS = (gss_OID)oids+5;
const gss_OID GSS_C_NT_EXPORT_NAME = (gss_OID)oids+6;
+const gss_OID GSS_C_INQ_SSPI_SESSION_KEY = (gss_OID)oids+7;
diff --git a/usr/src/uts/common/gssapi/gssapi_ext.h b/usr/src/uts/common/gssapi/gssapi_ext.h
index 58f61c884e..341dbeddd4 100644
--- a/usr/src/uts/common/gssapi/gssapi_ext.h
+++ b/usr/src/uts/common/gssapi/gssapi_ext.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Private extensions and utilities to the GSS-API.
@@ -31,8 +30,6 @@
#ifndef _GSSAPI_EXT_H
#define _GSSAPI_EXT_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <gssapi/gssapi.h>
#ifdef _KERNEL
#include <sys/systm.h>
@@ -200,6 +197,13 @@ gss_add_cred_with_password(
OM_uint32 *initiator_time_rec,
OM_uint32 *acceptor_time_rec);
+/*
+ * Returns a buffer set with the first member containing the
+ * session key for SSPI compatibility. The optional second
+ * member contains an OID identifying the session key type.
+ */
+extern const gss_OID GSS_C_INQ_SSPI_SESSION_KEY;
+
#else /* _KERNEL */
OM_uint32
@@ -228,9 +232,36 @@ kgss_get_group_info(
gid_t *gids[],
int *gidsLen,
uid_t uid);
-
#endif
+/*
+ * GGF extensions
+ */
+typedef struct gss_buffer_set_desc_struct {
+ size_t count;
+ gss_buffer_desc *elements;
+} gss_buffer_set_desc, *gss_buffer_set_t;
+
+#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t)0)
+
+OM_uint32 gss_create_empty_buffer_set
+ (OM_uint32 *, /* minor_status */
+ gss_buffer_set_t *); /* buffer_set */
+
+OM_uint32 gss_add_buffer_set_member
+ (OM_uint32 *, /* minor_status */
+ const gss_buffer_t, /* member_buffer */
+ gss_buffer_set_t *); /* buffer_set */
+
+OM_uint32 gss_release_buffer_set
+ (OM_uint32 *, /* minor_status */
+ gss_buffer_set_t *); /* buffer_set */
+
+OM_uint32 gss_inquire_sec_context_by_oid
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_OID, /* desired_object */
+ gss_buffer_set_t *); /* data_set */
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/gssapi/gssd_clnt_stubs.c b/usr/src/uts/common/gssapi/gssd_clnt_stubs.c
index 774c2c5711..e21a21b72d 100644
--- a/usr/src/uts/common/gssapi/gssd_clnt_stubs.c
+++ b/usr/src/uts/common/gssapi/gssd_clnt_stubs.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* GSSAPI library stub module for gssd.
*/
@@ -766,6 +764,16 @@ kgss_init_sec_context_wrapped(
if (minor_status != NULL)
*minor_status = res.minor_status;
+ if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
+ output_token->length =
+ (size_t)res.output_token.GSS_BUFFER_T_len;
+ output_token->value =
+ (void *)MALLOC(output_token->length);
+ (void) memcpy(output_token->value,
+ res.output_token.GSS_BUFFER_T_val,
+ output_token->length);
+ }
+
/* if the call was successful, copy out the results */
if (res.status == (OM_uint32) GSS_S_COMPLETE ||
res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
@@ -779,16 +787,6 @@ kgss_init_sec_context_wrapped(
res.context_handle.GSS_CTX_ID_T_val);
*gssd_context_verifier = res.gssd_context_verifier;
- if (output_token != NULL) {
- output_token->length =
- (size_t)res.output_token.GSS_BUFFER_T_len;
- output_token->value =
- (void *)MALLOC(output_token->length);
- (void) memcpy(output_token->value,
- res.output_token.GSS_BUFFER_T_val,
- output_token->length);
- }
-
if (res.status == GSS_S_COMPLETE) {
if (actual_mech_type != NULL) {
*actual_mech_type =
@@ -1055,6 +1053,19 @@ kgss_accept_sec_context_wrapped(
return (GSS_S_FAILURE);
}
+ if (minor_status != NULL)
+ *minor_status = res.minor_status;
+
+ if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
+ output_token->length =
+ res.output_token.GSS_BUFFER_T_len;
+ output_token->value =
+ (void *) MALLOC(output_token->length);
+ (void) memcpy(output_token->value,
+ res.output_token.GSS_BUFFER_T_val,
+ output_token->length);
+ }
+
/* if the call was successful, copy out the results */
if (res.status == (OM_uint32) GSS_S_COMPLETE ||
@@ -1070,19 +1081,6 @@ kgss_accept_sec_context_wrapped(
res.context_handle.GSS_CTX_ID_T_val);
*gssd_context_verifier = res.gssd_context_verifier;
- if (output_token != NULL) {
- output_token->length =
- res.output_token.GSS_BUFFER_T_len;
- output_token->value =
- (void *) MALLOC(output_token->length);
- (void) memcpy(output_token->value,
- res.output_token.GSS_BUFFER_T_val,
- output_token->length);
- }
-
- if (minor_status != NULL)
- *minor_status = res.minor_status;
-
/* these other parameters are only ready upon GSS_S_COMPLETE */
if (res.status == (OM_uint32) GSS_S_COMPLETE) {
diff --git a/usr/src/uts/common/gssapi/include/mechglueP.h b/usr/src/uts/common/gssapi/include/mechglueP.h
index 19c7b34dc2..1fb3f59d17 100644
--- a/usr/src/uts/common/gssapi/include/mechglueP.h
+++ b/usr/src/uts/common/gssapi/include/mechglueP.h
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This header contains the private mechglue definitions.
*
@@ -72,7 +70,8 @@ typedef struct gss_union_ctx_id_t {
* Generic GSSAPI names. A name can either be a generic name, or a
* mechanism specific name....
*/
-typedef struct gss_union_name_t {
+typedef struct gss_name_struct {
+ struct gss_name_struct *loopback;
gss_OID name_type;
gss_buffer_t external_name;
/*
@@ -161,6 +160,7 @@ typedef struct gss_config {
OM_uint32 (*gss_acquire_cred)
(
void *, /* context */
+
OM_uint32 *, /* minor_status */
const gss_name_t, /* desired_name */
OM_uint32, /* time_req */
@@ -172,6 +172,7 @@ typedef struct gss_config {
/* */);
OM_uint32 (*gss_release_cred)
(
+
void *, /* context */
OM_uint32 *, /* minor_status */
gss_cred_id_t * /* cred_handle */
@@ -516,6 +517,17 @@ typedef struct gss_config {
gss_OID_set *, /* elements_stored */
gss_cred_usage_t * /* cred_usage_stored */
/* */);
+
+ /* GGF extensions */
+
+ OM_uint32 (*gss_inquire_sec_context_by_oid)
+ (
+ OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_OID, /* OID */
+ gss_buffer_set_t * /* data_set */
+ /* */);
+
#endif
} *gss_mechanism;
@@ -873,5 +885,59 @@ OM_uint32 generic_gss_str_to_oid
gss_OID * /* oid */
);
+OM_uint32
+generic_gss_oid_compose(
+ OM_uint32 *, /* minor_status */
+ const char *, /* prefix */
+ size_t, /* prefix_len */
+ int, /* suffix */
+ gss_OID_desc *); /* oid */
+
+OM_uint32
+generic_gss_oid_decompose(
+ OM_uint32 *, /* minor_status */
+ const char *, /*prefix */
+ size_t, /* prefix_len */
+ gss_OID_desc *, /* oid */
+ int *); /* suffix */
+
+OM_uint32 generic_gss_create_empty_buffer_set
+(OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 generic_gss_add_buffer_set_member
+(OM_uint32 * /*minor_status*/,
+ const gss_buffer_t /*member_buffer*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+OM_uint32 generic_gss_release_buffer_set
+(OM_uint32 * /*minor_status*/,
+ gss_buffer_set_t * /*buffer_set*/);
+
+/*
+ * SUNW17PACresync
+ * New map error API in MIT 1.7, at build time generates code for errors.
+ * Solaris does not gen the errors at build time so we just stub these
+ * for now, need to revisit.
+ * See mglueP.h and util_errmap.c in MIT 1.7.
+*/
+#ifdef _KERNEL
+
+#define map_error(MINORP, MECH)
+#define map_errcode(MINORP)
+
+#else /* _KERNEL */
+
+#include <syslog.h>
+
+#define map_error(MINORP, MECH) \
+ (void) syslog(LOG_AUTH|LOG_DEBUG, \
+ "map_error: minor status=%x", \
+ (MINORP) ? *(MINORP) : 0xffffffff)
+#define map_errcode(MINORP) \
+ (void) syslog(LOG_AUTH|LOG_DEBUG, \
+ "map_errcode: minor status=%x", \
+ (MINORP) ? *(MINORP) : 0xffffffff)
+#endif /* _KERNEL */
#endif /* _GSS_MECHGLUEP_H */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h
index 75d5d263b4..23a65a15b2 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_generic.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.
*/
@@ -282,6 +282,23 @@ OM_uint32 generic_gss_str_to_oid
gss_buffer_t, /* oid_str */
gss_OID * /* oid */
);
+
+OM_uint32
+generic_gss_oid_compose(
+ OM_uint32 *, /* minor_status */
+ const char *, /* prefix */
+ size_t, /* prefix_len */
+ int, /* suffix */
+ gss_OID_desc *); /* oid */
+
+OM_uint32
+generic_gss_oid_decompose(
+ OM_uint32 *, /* minor_status */
+ const char *, /*prefix */
+ size_t, /* prefix_len */
+ gss_OID_desc *, /* oid */
+ int *); /* suffix */
+
#endif /* 0 */
#endif /* _GSSAPIP_GENERIC_H_ */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h
index 95002d4c6b..62a0c9d947 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_krb5.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapiP_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.
*/
@@ -74,6 +74,7 @@
*/
#include "gssapi_krb5.h"
#include "gssapi_err_krb5.h"
+#include "gssapi_ext.h"
/* for debugging */
#undef CFX_EXERCISE
@@ -194,6 +195,7 @@ typedef struct _krb5_gss_ctx_id_rec {
krb5_keyblock *enc;
krb5_keyblock *seq;
krb5_timestamp endtime;
+ krb5_ticket_times krb_times;
krb5_flags krb_flags;
/* XXX these used to be signed. the old spec is inspecific, and
the new spec specifies unsigned. I don't believe that the change
@@ -213,6 +215,7 @@ typedef struct _krb5_gss_ctx_id_rec {
krb5_keyblock *acceptor_subkey; /* CFX only */
krb5_cksumtype acceptor_subkey_cksumtype;
int cred_rcache; /* did we get rcache from creds? */
+ krb5_authdata **authdata;
} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
extern g_set kg_vdb;
@@ -716,32 +719,159 @@ OM_uint32 krb5_gss_userok(
* These take unglued krb5-mech-specific contexts.
*/
-OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags
- (OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- krb5_flags *ticket_flags);
+#define GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH 11
+#define GSS_KRB5_GET_TKT_FLAGS_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x01"
+
+#ifndef _KERNEL
+OM_uint32 gss_krb5int_get_tkt_flags
+(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set);
+
OM_uint32 KRB5_CALLCONV gss_krb5int_copy_ccache
(OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
krb5_ccache out_ccache);
+#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH 11
+#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x04"
+
+struct krb5_gss_set_allowable_enctypes_req {
+ OM_uint32 num_ktypes;
+ krb5_enctype *ktypes;
+};
+
+#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11
+#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"
+
+OM_uint32
+gss_krb5int_inq_session_key(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *);
+
OM_uint32 KRB5_CALLCONV
gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status,
gss_cred_id_t cred,
OM_uint32 num_ktypes,
krb5_enctype *ktypes);
+#endif /* _KERNEL */
+
+#if 0
+/*
+ * SUNW17PACresync
+ * These two functions not needed yet, revisit for full 1.7 resync.
+ */
+OM_uint32 KRB5_CALLCONV
+gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ const gss_OID desired_oid,
+ const gss_buffer_t value);
+
OM_uint32 KRB5_CALLCONV
gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
OM_uint32 version,
void **kctx);
+#endif
+
+#ifndef _KERNEL
+#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH 11
+#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x06"
+
+OM_uint32
+gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set);
+
+#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH 11
+#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x07"
+
+OM_uint32
+gss_krb5int_free_lucid_sec_context(OM_uint32 *, const gss_OID,
+ const gss_OID, gss_buffer_t);
extern k5_mutex_t kg_kdc_flag_mutex;
krb5_error_code krb5_gss_init_context (krb5_context *ctxp);
+
+#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11
+#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"
+
+OM_uint32
+gss_krb5int_inq_session_key(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *);
+
+
+#define GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH 11
+#define GSS_KRB5_USE_KDC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x08"
+
+OM_uint32 krb5int_gss_use_kdc_context(OM_uint32 *, const gss_OID,
+ const gss_OID, gss_buffer_t);
+
krb5_error_code krb5_gss_use_kdc_context(void);
+#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH 11
+#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x09"
+
+OM_uint32
+gss_krb5int_register_acceptor_identity(OM_uint32 *, const gss_OID, const gss_OID, gss_buffer_t);
+
+#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH 11
+#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a"
+
+OM_uint32
+gss_krb5int_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *ad_data);
+
+#define GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH 11
+#define GSS_KRB5_SET_CRED_RCACHE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0b"
+
+OM_uint32
+gss_krb5int_set_cred_rcache(OM_uint32 *, gss_cred_id_t, const gss_OID, const gss_buffer_t);
+
+#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH 11
+#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0c"
+
+OM_uint32
+gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *,
+ const gss_ctx_id_t,
+ const gss_OID,
+ gss_buffer_set_t *);
+#endif /* _KERNEL */
+
+/* For error message handling. */
+/* Returns a shared string, not a private copy! */
+extern char *
+krb5_gss_get_error_message(OM_uint32 minor_code);
+extern void
+krb5_gss_save_error_string(OM_uint32 minor_code, char *msg);
+extern void
+krb5_gss_save_error_message(OM_uint32 minor_code, const char *format, ...)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+ __attribute__((__format__(__printf__, 2, 3)))
+#endif
+ ;
+ extern void
+ krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx);
+#define get_error_message krb5_gss_get_error_message
+#define save_error_string krb5_gss_save_error_string
+#define save_error_message krb5_gss_save_error_message
+
+
+#if 0 /* SUNW17PACresync - revisit for full MIT 1.7 resync */
+#define save_error_info krb5_gss_save_error_info
+#endif
+#define save_error_info(m, ctx)
+
+
+extern void krb5_gss_delete_error_info(void *p);
+
+/* Prefix concatenated with Kerberos encryption type */
+#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 10
+#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04"
+
#endif /* _GSSAPIP_KRB5_H_ */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h
index 71fe3985dd..8a1b871dbc 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/gssapi_krb5.h
@@ -1,10 +1,7 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -178,17 +175,6 @@ typedef struct gss_krb5_lucid_context_version {
OM_uint32 KRB5_CALLCONV krb5_gss_register_acceptor_identity(const char *);
- /*
- * SUNW15resync
- * The name has changed (_krb5_ to _krb5int_) in MIT's
- * get_tkt_flags.c but did not change here
- * ...a bug I assume so we change it here.
- */
-OM_uint32 KRB5_CALLCONV gss_krb5int_get_tkt_flags
- (OM_uint32 *minor_status,
- gss_ctx_id_t context_handle,
- krb5_flags *ticket_flags);
-
OM_uint32 KRB5_CALLCONV gss_krb5_copy_ccache
(OM_uint32 *minor_status,
gss_cred_id_t cred_handle,
@@ -290,6 +276,21 @@ gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status,
void *kctx);
+OM_uint32 KRB5_CALLCONV
+gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ int ad_type,
+ gss_buffer_t ad_data);
+
+OM_uint32 KRB5_CALLCONV
+gss_krb5_set_cred_rcache(OM_uint32 *minor_status,
+ gss_cred_id_t cred,
+ krb5_rcache rcache);
+
+OM_uint32 KRB5_CALLCONV
+gsskrb5_extract_authtime_from_sec_context(OM_uint32 *, gss_ctx_id_t, krb5_timestamp *);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
index 449115b131..a85b86e2aa 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.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.
*/
@@ -412,6 +412,12 @@ typedef struct _krb5_etype_info_entry {
typedef krb5_etype_info_entry ** krb5_etype_info;
+/* RFC 4537 */
+typedef struct _krb5_etype_list {
+ int length;
+ krb5_enctype *etypes;
+} krb5_etype_list;
+
/*
* a sam_challenge is returned for alternate preauth
*/
@@ -689,6 +695,14 @@ krb5_error_code krb5int_sendto (krb5_context context, const krb5_data *message,
void *msg_handler_data);
krb5_error_code krb5int_get_fq_local_hostname (char *, size_t);
+
+krb5_error_code krb5_set_debugging_time
+ (krb5_context, krb5_timestamp, krb5_int32);
+krb5_error_code krb5_use_natural_time
+ (krb5_context);
+krb5_error_code krb5_set_time_offsets
+ (krb5_context, krb5_timestamp, krb5_int32);
+krb5_error_code krb5int_check_clockskew(krb5_context, krb5_timestamp);
#endif
/*
@@ -1140,6 +1154,54 @@ typedef struct _krb5_pa_enc_ts {
krb5_int32 pausec;
} krb5_pa_enc_ts;
+typedef struct _krb5_pa_for_user {
+ krb5_principal user;
+ krb5_checksum cksum;
+ krb5_data auth_package;
+} krb5_pa_for_user;
+
+enum {
+ KRB5_FAST_ARMOR_AP_REQUEST = 0x1
+};
+
+typedef struct _krb5_fast_armor {
+ krb5_int32 armor_type;
+ krb5_data armor_value;
+} krb5_fast_armor;
+typedef struct _krb5_fast_armored_req {
+ krb5_magic magic;
+ krb5_fast_armor *armor;
+ krb5_checksum req_checksum;
+ krb5_enc_data enc_part;
+} krb5_fast_armored_req;
+
+typedef struct _krb5_fast_req {
+ krb5_magic magic;
+ krb5_flags fast_options;
+ /* padata from req_body is used*/
+ krb5_kdc_req *req_body;
+} krb5_fast_req;
+
+
+/* Bits 0-15 are critical in fast options.*/
+#define UNSUPPORTED_CRITICAL_FAST_OPTIONS 0x00ff
+#define KRB5_FAST_OPTION_HIDE_CLIENT_NAMES 0x01
+
+typedef struct _krb5_fast_finished {
+ krb5_timestamp timestamp;
+ krb5_int32 usec;
+ krb5_principal client;
+ krb5_checksum ticket_checksum;
+} krb5_fast_finished;
+
+typedef struct _krb5_fast_response {
+ krb5_magic magic;
+ krb5_pa_data **padata;
+ krb5_keyblock *strengthen_key;
+ krb5_fast_finished *finished;
+ krb5_int32 nonce;
+} krb5_fast_response;
+
typedef krb5_error_code (*krb5_preauth_obtain_proc)
(krb5_context,
krb5_pa_data *,
@@ -1809,8 +1871,13 @@ krb5_error_code encode_krb5_kdc_req_body
krb5_error_code encode_krb5_safe
(const krb5_safe *rep, krb5_data **code);
+struct krb5_safe_with_body {
+ krb5_safe *safe;
+ krb5_data *body;
+};
+
krb5_error_code encode_krb5_safe_with_body
- (const krb5_safe *rep, const krb5_data *body, krb5_data **code);
+ (const struct krb5_safe_with_body *rep, krb5_data **code);
krb5_error_code encode_krb5_priv
(const krb5_priv *rep, krb5_data **code);
@@ -1828,7 +1895,7 @@ krb5_error_code encode_krb5_error
(const krb5_error *rep, krb5_data **code);
krb5_error_code encode_krb5_authdata
- (const krb5_authdata **rep, krb5_data **code);
+ (krb5_authdata *const *rep, krb5_data **code);
krb5_error_code encode_krb5_authdata_elt
(const krb5_authdata *rep, krb5_data **code);
@@ -1840,15 +1907,15 @@ krb5_error_code encode_krb5_pwd_data
(const krb5_pwd_data *rep, krb5_data **code);
krb5_error_code encode_krb5_padata_sequence
- (const krb5_pa_data ** rep, krb5_data **code);
+ (krb5_pa_data *const *rep, krb5_data **code);
krb5_error_code encode_krb5_alt_method
(const krb5_alt_method *, krb5_data **code);
krb5_error_code encode_krb5_etype_info
- (const krb5_etype_info_entry **, krb5_data **code);
+ (krb5_etype_info_entry *const *, krb5_data **code);
krb5_error_code encode_krb5_etype_info2
- (const krb5_etype_info_entry **, krb5_data **code);
+ (krb5_etype_info_entry *const *, krb5_data **code);
krb5_error_code encode_krb5_enc_data
(const krb5_enc_data *, krb5_data **);
@@ -1883,8 +1950,12 @@ krb5_error_code encode_krb5_sam_response_2
krb5_error_code encode_krb5_predicted_sam_response
(const krb5_predicted_sam_response * , krb5_data **);
+struct krb5_setpw_req {
+ krb5_principal target;
+ krb5_data password;
+};
krb5_error_code encode_krb5_setpw_req
-(const krb5_principal target, char *password, krb5_data **code);
+ (const struct krb5_setpw_req *rep, krb5_data **code);
/*************************************************************************
* End of prototypes for krb5_encode.c
@@ -2291,6 +2362,7 @@ typedef struct _krb5int_access {
struct srv_dns_entry **answers);
void (*free_srv_dns_data)(struct srv_dns_entry *);
int (*use_dns_kdc)(krb5_context);
+ krb5_error_code (*clean_hostname)(krb5_context, const char *, char *, size_t);
/* krb4 compatibility stuff -- may be null if not enabled */
krb5_int32 (*krb_life_to_time)(krb5_int32, int);
@@ -2505,6 +2577,7 @@ typedef struct _krb5_donot_replay {
krb5_ui_4 hash;
char *server; /* null-terminated */
char *client; /* null-terminated */
+ char *msghash; /* null-terminated */
krb5_int32 cusec;
krb5_timestamp ctime;
} krb5_donot_replay;
@@ -2647,4 +2720,12 @@ krb5_error_code KRB5_CALLCONV krb5int_clean_hostname
char *,
size_t);
+/*
+ * Solaris Kerberos
+ * Kernel & user space realloc.
+ */
+void *krb5int_realloc
+ (void *oldp,
+ size_t new_size,
+ size_t old_size);
#endif /* _KRB5_INT_H */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h
index 8fe696a6ad..3252e0cfdd 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/k5-platform.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.
*/
@@ -527,6 +527,20 @@ load_64_le (unsigned char *p)
#define k5_getpwuid_r(UID, REC, BUF, BUFSIZE, OUT) \
(*(OUT) = getpwuid_r(UID,REC,BUF,BUFSIZE), *(OUT) == NULL ? -1 : 0)
+/* Return true if the snprintf return value RESULT reflects a buffer
+ overflow for the buffer size SIZE.
+
+ We cast the result to unsigned int for two reasons. First, old
+ implementations of snprintf (such as the one in Solaris 9 and
+ prior) return -1 on a buffer overflow. Casting the result to -1
+ will convert that value to UINT_MAX, which should compare larger
+ than any reasonable buffer size. Second, comparing signed and
+ unsigned integers will generate warnings with some compilers, and
+ can have unpredictable results, particularly when the relative
+ widths of the types is not known (size_t may be the same width as
+ int or larger).
+*/
+#define SNPRINTF_OVERFLOW(result, size) \
+ ((unsigned int)(result) >= (size_t)(size))
#endif /* K5_PLATFORM_H */
-
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 5e9c22a8d3..fea8316e03 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h
+++ b/usr/src/uts/common/gssapi/mechs/krb5/include/krb5.h
@@ -315,6 +315,18 @@ typedef krb5_principal_data * krb5_principal;
#define KRB5_NT_SRV_XHST 4
/* Unique ID */
#define KRB5_NT_UID 5
+/* PKINIT */
+#define KRB5_NT_X500_PRINCIPAL 6
+/* Name in form of SMTP email name */
+#define KRB5_NT_SMTP_NAME 7
+/* Windows 2000 UPN */
+#define KRB5_NT_ENTERPRISE_PRINCIPAL 10
+/* Windows 2000 UPN and SID */
+#define KRB5_NT_MS_PRINCIPAL -128
+/* NT 4 style name */
+#define KRB5_NT_MS_PRINCIPAL_AND_ID -129
+/* NT 4 style name and SID */
+#define KRB5_NT_ENT_PRINCIPAL_AND_ID -130
/* constant version thereof: */
typedef const krb5_principal_data *krb5_const_principal;
@@ -1010,6 +1022,9 @@ krb5_error_code krb5_decrypt_data
#define KRB5_AUTHDATA_INITIAL_VERIFIED_CAS 9
#define KRB5_AUTHDATA_OSF_DCE 64
#define KRB5_AUTHDATA_SESAME 65
+#define KRB5_AUTHDATA_WIN2K_PAC 128
+#define KRB5_AUTHDATA_ETYPE_NEGOTIATION 129 /* RFC 4537 */
+#define KRB5_AUTHDATA_FX_ARMOR 71
/* password change constants */
@@ -1162,6 +1177,7 @@ typedef struct _krb5_enc_kdc_rep_part {
krb5_principal server; /* server's principal identifier */
krb5_address **caddrs; /* array of ptrs to addresses,
optional */
+ krb5_pa_data **enc_padata; /* Windows 2000 compat */
} krb5_enc_kdc_rep_part;
typedef struct _krb5_kdc_rep {
@@ -1264,6 +1280,24 @@ typedef struct _krb5_pwd_data {
/* these need to be here so the typedefs are available for the prototypes */
+typedef struct _krb5_pa_svr_referral_data {
+ /* Referred name, only realm is required */
+ krb5_principal principal;
+} krb5_pa_svr_referral_data;
+
+typedef struct _krb5_pa_server_referral_data {
+ krb5_data *referred_realm;
+ krb5_principal true_principal_name;
+ krb5_principal requested_principal_name;
+ krb5_timestamp referral_valid_until;
+ krb5_checksum rep_cksum;
+} krb5_pa_server_referral_data;
+
+typedef struct _krb5_pa_pac_req {
+ /* TRUE if a PAC should be included in TGS-REP */
+ krb5_boolean include_pac;
+} krb5_pa_pac_req;
+
/*
* begin "safepriv.h"
*/
@@ -1646,6 +1680,14 @@ krb5_error_code KRB5_CALLCONV krb5_parse_name
(krb5_context,
const char *,
krb5_principal * );
+#define KRB5_PRINCIPAL_PARSE_NO_REALM 0x1
+#define KRB5_PRINCIPAL_PARSE_REQUIRE_REALM 0x2
+#define KRB5_PRINCIPAL_PARSE_ENTERPRISE 0x4
+krb5_error_code KRB5_CALLCONV krb5_parse_name_flags
+ (krb5_context,
+ const char *,
+ int,
+ krb5_principal * );
krb5_error_code KRB5_CALLCONV krb5_unparse_name
(krb5_context,
krb5_const_principal,
@@ -1655,6 +1697,20 @@ krb5_error_code KRB5_CALLCONV krb5_unparse_name_ext
krb5_const_principal,
char **,
unsigned int *);
+#define KRB5_PRINCIPAL_UNPARSE_SHORT 0x1
+#define KRB5_PRINCIPAL_UNPARSE_NO_REALM 0x2
+#define KRB5_PRINCIPAL_UNPARSE_DISPLAY 0x4
+krb5_error_code KRB5_CALLCONV krb5_unparse_name_flags
+ (krb5_context,
+ krb5_const_principal,
+ int,
+ char **);
+krb5_error_code KRB5_CALLCONV krb5_unparse_name_flags_ext
+ (krb5_context,
+ krb5_const_principal,
+ int,
+ char **,
+ unsigned int *);
krb5_error_code KRB5_CALLCONV krb5_set_principal_realm
(krb5_context, krb5_principal, const char *);
@@ -1766,6 +1822,14 @@ krb5_error_code KRB5_CALLCONV krb5_copy_authdata
(krb5_context,
krb5_authdata * const *,
krb5_authdata ***);
+krb5_error_code KRB5_CALLCONV krb5_merge_authdata
+ (krb5_context,
+ krb5_authdata * const *,
+ krb5_authdata *const *,
+ krb5_authdata ***);
+/* Merge two authdata arrays, such as the array from a ticket
+ * and authenticator */
+
krb5_error_code KRB5_CALLCONV krb5_copy_authenticator
(krb5_context,
const krb5_authenticator *,
@@ -2824,6 +2888,70 @@ krb5_free_error_message (krb5_context, const char *);
void KRB5_CALLCONV
krb5_clear_error_message (krb5_context);
+krb5_error_code KRB5_CALLCONV
+krb5_decode_authdata_container(krb5_context context,
+ krb5_authdatatype type,
+ const krb5_authdata *container,
+ krb5_authdata ***authdata);
+krb5_error_code KRB5_CALLCONV
+krb5_encode_authdata_container(krb5_context context,
+ krb5_authdatatype type,
+ krb5_authdata * const*authdata,
+ krb5_authdata ***container);
+
+/*
+ * Windows PAC
+ */
+struct krb5_pac_data;
+typedef struct krb5_pac_data *krb5_pac;
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_add_buffer
+(krb5_context context,
+ krb5_pac pac,
+ krb5_ui_4 type,
+ const krb5_data *data);
+
+void KRB5_CALLCONV
+krb5_pac_free
+(krb5_context context,
+ krb5_pac pac);
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_get_buffer
+(krb5_context context,
+ krb5_pac pac,
+ krb5_ui_4 type,
+ krb5_data *data);
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_get_types
+(krb5_context context,
+ krb5_pac pac,
+ size_t *len,
+ krb5_ui_4 **types);
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_init
+(krb5_context context,
+ krb5_pac *pac);
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_parse
+(krb5_context context,
+ const void *ptr,
+ size_t len,
+ krb5_pac *pac);
+
+krb5_error_code KRB5_CALLCONV
+krb5_pac_verify
+(krb5_context context,
+ const krb5_pac pac,
+ krb5_timestamp authtime,
+ krb5_const_principal principal,
+ const krb5_keyblock *server,
+ const krb5_keyblock *privsvr);
+
#if TARGET_OS_MAC
# pragma pack(pop)
@@ -3112,6 +3240,13 @@ KRB5INT_END_DECLS
#define KRB5_PLUGIN_NO_HANDLE (-1765328132L)
#define KRB5_PLUGIN_OP_NOTSUPP (-1765328131L)
+/* SUNW17PACresync */
+#define KRB5_ERR_INVALID_UTF8 (-1765328130L)
+#define KRB5_ERR_FAST_REQUIRED (-1765328129L)
+#define KRB5_LOCAL_ADDR_REQUIRED (-1765328128L)
+#define KRB5_REMOTE_ADDR_REQUIRED (-1765328127L)
+
+
#define ERROR_TABLE_BASE_krb5 (-1765328384L)
/* for compatibility with older versions... */
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
index 1225f53386..bd2dea7a77 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_auth.c
@@ -1,9 +1,4 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
* lib/krb5/krb/copy_auth.c
*
* Copyright 1990 by the Massachusetts Institute of Technology.
@@ -31,20 +26,46 @@
*
* krb5_copy_authdata()
*/
+/*
+ * Copyright (c) 2006-2008, Novell, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The copyright holder's name is not used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#include "k5-int.h"
-/*ARGSUSED*/
static krb5_error_code
krb5_copy_authdatum(krb5_context context, const krb5_authdata *inad, krb5_authdata **outad)
{
krb5_authdata *tmpad;
- if (!(tmpad = (krb5_authdata *)MALLOC(sizeof(*tmpad))))
+ if (!(tmpad = (krb5_authdata *)malloc(sizeof(*tmpad))))
return ENOMEM;
*tmpad = *inad;
- if (!(tmpad->contents = (krb5_octet *)MALLOC(inad->length))) {
- krb5_xfree_wrap(tmpad, inad->length);
+ if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) {
+ free(tmpad);
return ENOMEM;
}
(void) memcpy((char *)tmpad->contents, (char *)inad->contents, inad->length);
@@ -56,33 +77,202 @@ krb5_copy_authdatum(krb5_context context, const krb5_authdata *inad, krb5_authda
* Copy an authdata array, with fresh allocation.
*/
krb5_error_code KRB5_CALLCONV
-krb5_copy_authdata(krb5_context context, krb5_authdata *const *inauthdat, krb5_authdata ***outauthdat)
+krb5_merge_authdata(krb5_context context, krb5_authdata *const *inauthdat1, krb5_authdata * const *inauthdat2,
+ krb5_authdata ***outauthdat)
{
krb5_error_code retval;
krb5_authdata ** tempauthdat;
- register unsigned int nelems = 0;
+ register unsigned int nelems = 0, nelems2 = 0;
- if (!inauthdat) {
+ *outauthdat = NULL;
+ if (!inauthdat1 && !inauthdat2) {
*outauthdat = 0;
return 0;
}
- while (inauthdat[nelems]) nelems++;
+ if (inauthdat1)
+ while (inauthdat1[nelems]) nelems++;
+ if (inauthdat2)
+ while (inauthdat2[nelems2]) nelems2++;
/* one more for a null terminated list */
- if (!(tempauthdat = (krb5_authdata **) CALLOC(nelems+1,
+ if (!(tempauthdat = (krb5_authdata **) calloc(nelems+nelems2+1,
sizeof(*tempauthdat))))
return ENOMEM;
- for (nelems = 0; inauthdat[nelems]; nelems++) {
- retval = krb5_copy_authdatum(context, inauthdat[nelems],
- &tempauthdat[nelems]);
- if (retval) {
- krb5_free_authdata(context, tempauthdat);
- return retval;
+ if (inauthdat1) {
+ for (nelems = 0; inauthdat1[nelems]; nelems++) {
+ retval = krb5_copy_authdatum(context, inauthdat1[nelems],
+ &tempauthdat[nelems]);
+ if (retval) {
+ krb5_free_authdata(context, tempauthdat);
+ return retval;
+ }
+ }
+ }
+
+ if (inauthdat2) {
+ for (nelems2 = 0; inauthdat2[nelems2]; nelems2++) {
+ retval = krb5_copy_authdatum(context, inauthdat2[nelems2],
+ &tempauthdat[nelems++]);
+ if (retval) {
+ krb5_free_authdata(context, tempauthdat);
+ return retval;
+ }
}
}
*outauthdat = tempauthdat;
return 0;
}
+
+krb5_error_code KRB5_CALLCONV
+krb5_copy_authdata(krb5_context context,
+ krb5_authdata *const *in_authdat, krb5_authdata ***out)
+{
+ return krb5_merge_authdata(context, in_authdat, NULL, out);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_decode_authdata_container(krb5_context context,
+ krb5_authdatatype type,
+ const krb5_authdata *container,
+ krb5_authdata ***authdata)
+{
+ krb5_error_code code;
+ krb5_data data;
+
+ *authdata = NULL;
+
+ if ((container->ad_type & AD_TYPE_FIELD_TYPE_MASK) != type)
+ return EINVAL;
+
+ data.length = container->length;
+ data.data = (char *)container->contents;
+
+ code = decode_krb5_authdata(&data, authdata);
+ if (code)
+ return code;
+
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_encode_authdata_container(krb5_context context,
+ krb5_authdatatype type,
+ krb5_authdata *const*authdata,
+ krb5_authdata ***container)
+{
+ krb5_error_code code;
+ krb5_data *data;
+ krb5_authdata ad_datum;
+ krb5_authdata *ad_data[2];
+
+ *container = NULL;
+
+ code = encode_krb5_authdata((krb5_authdata * const *)authdata, &data);
+ if (code)
+ return code;
+
+ ad_datum.ad_type = type & AD_TYPE_FIELD_TYPE_MASK;
+ ad_datum.length = data->length;
+ ad_datum.contents = (unsigned char *)data->data;
+
+ ad_data[0] = &ad_datum;
+ ad_data[1] = NULL;
+
+ code = krb5_copy_authdata(context, ad_data, container);
+
+ krb5_free_data(context, data);
+
+ return code;
+}
+
+struct find_authdata_context {
+ krb5_authdata **out;
+ size_t space;
+ size_t length;
+};
+
+static krb5_error_code grow_find_authdata
+(krb5_context context, struct find_authdata_context *fctx,
+ krb5_authdata *elem)
+{
+ krb5_error_code retval = 0;
+ if (fctx->length == fctx->space) {
+ krb5_authdata **new;
+ if (fctx->space >= 256) {
+ krb5_set_error_message(context, ERANGE, "More than 256 authdata matched a query");
+ return ERANGE;
+ }
+ new = realloc(fctx->out,
+ sizeof (krb5_authdata *)*(2*fctx->space+1));
+ if (new == NULL)
+ return ENOMEM;
+ fctx->out = new;
+ fctx->space *=2;
+ }
+ fctx->out[fctx->length+1] = NULL;
+ retval = krb5_copy_authdatum(context, elem,
+ &fctx->out[fctx->length]);
+ if (retval == 0)
+ fctx->length++;
+ return retval;
+}
+
+
+
+
+static krb5_error_code find_authdata_1
+(krb5_context context, krb5_authdata *const *in_authdat, krb5_authdatatype ad_type,
+ struct find_authdata_context *fctx)
+{
+ int i = 0;
+ krb5_error_code retval=0;
+
+ for (i = 0; in_authdat[i]; i++) {
+ krb5_authdata *ad = in_authdat[i];
+ if (ad->ad_type == ad_type && retval ==0)
+ retval = grow_find_authdata(context, fctx, ad);
+ else switch (ad->ad_type) {
+ krb5_authdata **decoded_container;
+ case KRB5_AUTHDATA_IF_RELEVANT:
+ if (retval == 0)
+ retval = krb5_decode_authdata_container( context, ad->ad_type, ad, &decoded_container);
+ if (retval == 0) {
+ retval = find_authdata_1(context,
+ decoded_container, ad_type, fctx);
+ krb5_free_authdata(context, decoded_container);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return retval;
+}
+
+
+krb5_error_code krb5int_find_authdata
+(krb5_context context, krb5_authdata *const * ticket_authdata,
+ krb5_authdata * const *ap_req_authdata,
+ krb5_authdatatype ad_type,
+ krb5_authdata ***results)
+{
+ krb5_error_code retval = 0;
+ struct find_authdata_context fctx;
+ fctx.length = 0;
+ fctx.space = 2;
+ fctx.out = calloc(fctx.space+1, sizeof (krb5_authdata *));
+ *results = NULL;
+ if (fctx.out == NULL)
+ return ENOMEM;
+ if (ticket_authdata)
+ retval = find_authdata_1( context, ticket_authdata, ad_type, &fctx);
+ if ((retval==0) && ap_req_authdata)
+ retval = find_authdata_1( context, ap_req_authdata, ad_type, &fctx);
+ if ((retval== 0) && fctx.length)
+ *results = fctx.out;
+ else krb5_free_authdata(context, fctx.out);
+ return retval;
+}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
index 1fc4c570ce..b87c37b55a 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/parse.c
@@ -1,12 +1,12 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* lib/krb5/krb/parse.c
*
- * Copyright 1990,1991 by the Massachusetts Institute of Technology.
+ * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -38,12 +38,6 @@
#include "k5-int.h"
-#ifndef _KERNEL
-#include <assert.h>
-#include <stdarg.h>
-#define ASSERT assert
-#endif
-
/*
* converts a single-string representation of the name to the
* multi-part principal format used in the protocols.
@@ -70,18 +64,18 @@
#define FCOMPNUM 10
-
/*
* May the fleas of a thousand camels infest the ISO, they who think
* that arbitrarily large multi-component names are a Good Thing.....
*/
-/*ARGSUSED*/
-krb5_error_code KRB5_CALLCONV
-krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincipal)
+static krb5_error_code
+/*LINTED*/
+k5_parse_name(krb5_context context, const char *name,
+ int flags, krb5_principal *nprincipal)
{
register const char *cp;
register char *q;
- register int i,c,size;
+ register int i,c,size;
int components = 0;
const char *parsed_realm = NULL;
int fcompsize[FCOMPNUM];
@@ -93,26 +87,32 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
#endif
char *tmpdata;
krb5_principal principal;
+ unsigned int enterprise = (flags & KRB5_PRINCIPAL_PARSE_ENTERPRISE);
+ int first_at;
+
+ *nprincipal = NULL;
/*
* Pass 1. Find out how many components there are to the name,
- * and get string sizes for the first FCOMPNUM components.
+ * and get string sizes for the first FCOMPNUM components. For
+ * enterprise principal names (UPNs), there is only a single
+ * component.
*/
size = 0;
/*LINTED*/
- for (i = 0, cp = name; (c = *cp); cp++) {
+ for (i=0,cp = name, first_at = 1; (c = *cp); cp++) {
if (c == QUOTECHAR) {
cp++;
/*LINTED*/
if (!(c = *cp))
/*
- * QUOTECHAR can't be at the last
- * character of the name!
- */
+ * QUOTECHAR can't be at the last
+ * character of the name!
+ */
return(KRB5_PARSE_MALFORMED);
size++;
continue;
- } else if (c == COMPONENT_SEP) {
+ } else if (c == COMPONENT_SEP && !enterprise) {
if (parsed_realm)
/*
* Shouldn't see a component separator
@@ -124,22 +124,26 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
}
size = 0;
i++;
- } else if (c == REALM_SEP) {
+ } else if (c == REALM_SEP && (!enterprise || !first_at)) {
if (parsed_realm)
/*
* Multiple realm separaters
* not allowed; zero-length realms are.
*/
return(KRB5_PARSE_MALFORMED);
- parsed_realm = cp+1;
+ parsed_realm = cp + 1;
if (i < FCOMPNUM) {
fcompsize[i] = size;
}
size = 0;
- } else
+ } else {
+ if (c == REALM_SEP && enterprise && first_at)
+ first_at = 0;
+
size++;
+ }
}
- if (parsed_realm)
+ if (parsed_realm != NULL)
realmsize = size;
else if (i < FCOMPNUM)
fcompsize[i] = size;
@@ -149,39 +153,49 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
* component pieces
*/
principal = (krb5_principal)MALLOC(sizeof(krb5_principal_data));
- if (!principal) {
- return(ENOMEM);
+ if (principal == NULL) {
+ return(ENOMEM);
}
principal->data = (krb5_data *)MALLOC(sizeof(krb5_data) * components);
- if (!principal->data) {
- krb5_xfree_wrap((char *)principal, sizeof(krb5_principal_data));
+ if (principal->data == NULL) {
+ krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
return ENOMEM;
}
principal->length = components;
+
/*
- * If a realm was not found, then use the defualt realm....
- */
- /*
- * In the kernel we import the ctx and it always contains the
- * default realm
+ * If a realm was not found, then use the default realm, unless
+ * KRB5_PRINCIPAL_PARSE_NO_REALM was specified in which case the
+ * realm will be empty.
*/
-
#ifndef _KERNEL
if (!parsed_realm) {
- if (!default_realm) {
+ if (flags & KRB5_PRINCIPAL_PARSE_REQUIRE_REALM) {
+ krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
+ "Principal %s is missing required realm", name);
+ krb5_xfree_wrap(principal->data, principal->length);
+ krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
+ return KRB5_PARSE_MALFORMED;
+ }
+ if (!default_realm && (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) == 0) {
retval = krb5_get_default_realm(context, &default_realm);
if (retval) {
- krb5_xfree_wrap(principal->data,
- sizeof (krb5_data) * components);
- krb5_xfree_wrap((char *)principal,
- sizeof (krb5_principal_data));
+ krb5_xfree_wrap(principal->data, principal->length);
+ krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
return(retval);
}
default_realm_size = strlen(default_realm);
}
realmsize = default_realm_size;
+ } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) {
+ krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
+ "Principal %s has realm present", name);
+ krb5_xfree_wrap(principal->data, principal->length);
+ krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
+ return KRB5_PARSE_MALFORMED;
}
#endif
+
/*
* Pass 2. Happens only if there were more than FCOMPNUM
* component; if this happens, someone should be shot
@@ -217,14 +231,15 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
if (i + 1 != components) {
#ifndef _KERNEL
#if !defined(_WIN32)
- fprintf(stderr,
+ fprintf(stderr,
"Programming error in krb5_parse_name!");
#endif
- ASSERT(i + 1 == components);
- abort();
+ ASSERT(i + 1 == components);
+ abort();
#else
- ASSERT(i + 1 == components);
+ ASSERT(i + 1 == components);
#endif /* !_KERNEL */
+
}
} else {
/*
@@ -238,47 +253,37 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
/*
* Now, we need to allocate the space for the strings themselves.....
*/
- tmpdata = MALLOC(realmsize+1);
+ tmpdata = MALLOC(realmsize + 1);
if (tmpdata == 0) {
- krb5_xfree_wrap(principal->data,
- sizeof (krb5_data) * components);
- krb5_xfree_wrap((char *)principal,
- sizeof (krb5_principal_data));
+ krb5_xfree_wrap(principal->data, principal->length);
+ krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
#ifndef _KERNEL
- if (default_realm)
- krb5_xfree_wrap(default_realm, strlen(default_realm));
+ krb5_xfree_wrap(default_realm, strlen(default_realm));
#endif
- return (ENOMEM);
+ return ENOMEM;
}
krb5_princ_set_realm_length(context, principal, realmsize);
krb5_princ_set_realm_data(context, principal, tmpdata);
for (i=0; i < components; i++) {
char *tmpdata2 =
MALLOC(krb5_princ_component(context, principal, i)->length + 1);
- if (!tmpdata2) {
- /*
- * Release the principle and realm strings remembering
- * that we allocated one additional byte beyond the
- * 'length' to hold the string terminating zero byte.
- * It's critical that the free size match the malloc
- * size.
- */
+ if (tmpdata2 == NULL) {
for (i--; i >= 0; i--)
- krb5_xfree_wrap(krb5_princ_component(context,
+ krb5_xfree_wrap(krb5_princ_component(context,
principal, i)->data,
- krb5_princ_component(context,
- principal, i)->length + 1);
- krb5_xfree_wrap(krb5_princ_realm(context,
- principal)->data, krb5_princ_realm(context,
- principal)->length + 1);
+ krb5_princ_component(context,
+ principal, i)->length + 1);
+
+ krb5_xfree_wrap(krb5_princ_realm(context,
+ principal)->data, krb5_princ_realm(context,
+ principal)->length + 1);
+
krb5_xfree_wrap(principal->data, principal->length);
krb5_xfree_wrap(principal, sizeof(krb5_principal_data));
#ifndef _KERNEL
- if (default_realm)
- krb5_xfree_wrap(default_realm,
- strlen(default_realm));
+ krb5_xfree_wrap(default_realm, strlen(default_realm));
#endif
- return (ENOMEM);
+ return(ENOMEM);
}
krb5_princ_component(context, principal, i)->data = tmpdata2;
krb5_princ_component(context, principal, i)->magic = KV5M_DATA;
@@ -291,7 +296,7 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
*/
q = krb5_princ_component(context, principal, 0)->data;
/*LINTED*/
- for (i=0,cp = name; (c = *cp); cp++) {
+ for (i=0,cp = name, first_at = 1; (c = *cp); cp++) {
if (c == QUOTECHAR) {
cp++;
switch (c = *cp) {
@@ -308,35 +313,64 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincip
*q++ = '\0';
break;
default:
- *q++ = (char) c;
+ *q++ = c;
+ break;
}
- } else if ((c == COMPONENT_SEP) || (c == REALM_SEP)) {
+ } else if (c == COMPONENT_SEP && !enterprise) {
+ i++;
+ *q++ = '\0';
+ q = krb5_princ_component(context, principal, i)->data;
+ } else if (c == REALM_SEP && (!enterprise || !first_at)) {
i++;
*q++ = '\0';
- if (c == COMPONENT_SEP)
- q = krb5_princ_component(context, principal, i)->data;
- else
- q = krb5_princ_realm(context, principal)->data;
- } else
- *q++ = (char) c;
+ q = krb5_princ_realm(context, principal)->data;
+ } else {
+ if (c == REALM_SEP && enterprise && first_at)
+ first_at = 0;
+
+ *q++ = c;
+ }
}
*q++ = '\0';
- if (!parsed_realm)
+ /*LINTED*/
+ if (!parsed_realm) {
#ifndef _KERNEL
- (void) strcpy(krb5_princ_realm(context, principal)->data,
- default_realm);
+
+ if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM)
+ (krb5_princ_realm(context, principal)->data)[0] = '\0';
+ else
+ strlcpy(krb5_princ_realm(context, principal)->data, default_realm, realmsize+1);
#endif
+ }
/*
* Alright, we're done. Now stuff a pointer to this monstrosity
* into the return variable, and let's get out of here.
*/
- krb5_princ_type(context, principal) = KRB5_NT_PRINCIPAL;
+ if (enterprise)
+ krb5_princ_type(context, principal) = KRB5_NT_ENTERPRISE_PRINCIPAL;
+ else
+ krb5_princ_type(context, principal) = KRB5_NT_PRINCIPAL;
principal->magic = KV5M_PRINCIPAL;
principal->realm.magic = KV5M_DATA;
*nprincipal = principal;
+
#ifndef _KERNEL
- if (default_realm)
- krb5_xfree_wrap(default_realm, strlen(default_realm));
+ if (default_realm != NULL)
+ krb5_xfree_wrap(default_realm, strlen(default_realm));
#endif
+
return(0);
}
+
+krb5_error_code KRB5_CALLCONV
+krb5_parse_name(krb5_context context, const char *name, krb5_principal *nprincipal)
+{
+ return k5_parse_name(context, name, 0, nprincipal);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_parse_name_flags(krb5_context context, const char *name,
+ int flags, krb5_principal *nprincipal)
+{
+ return k5_parse_name(context, name, flags, nprincipal);
+}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
index 84d2a67ca1..edec335118 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/unparse.c
@@ -1,12 +1,12 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* lib/krb5/krb/unparse.c
*
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright 1990, 2008 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -21,7 +21,10 @@
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
- * permission. M.I.T. makes no representations about the suitability of
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
@@ -35,11 +38,33 @@
#include "k5-int.h"
-#ifndef _KERNEL
+#ifndef _KERNEL
#include <stdio.h>
#endif
/*
+ * SUNW17PACresync / Solaris Kerberos
+ * This realloc works for both Solaris kernel and user space.
+ */
+void *
+krb5int_realloc(
+ void *oldp,
+ size_t new_size,
+ size_t old_size)
+{
+#ifdef _KERNEL
+ char *newp = MALLOC(new_size);
+
+ bcopy(oldp, newp, old_size < new_size ? old_size : new_size);
+ FREE(oldp, old_size);
+
+ return (newp);
+#else
+ return (realloc(oldp, new_size));
+#endif
+}
+
+/*
* converts the multi-part principal format used in the protocols to a
* single-string representation of the name.
*
@@ -61,39 +86,142 @@
#define REALM_SEP '@'
#define COMPONENT_SEP '/'
-/*ARGSUSED*/
-krb5_error_code KRB5_CALLCONV
-krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, register char **name, unsigned int *size)
+static int
+component_length_quoted(const krb5_data *src, int flags)
{
- register char *cp, *q;
- register int i,j;
- int length;
+ const char *cp = src->data;
+ int length = src->length;
+ int j;
+ int size = length;
+
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) == 0) {
+ int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) &&
+ !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT);
+
+ for (j = 0; j < length; j++,cp++)
+ if ((!no_realm && *cp == REALM_SEP) ||
+ *cp == COMPONENT_SEP ||
+ *cp == '\0' || *cp == '\\' || *cp == '\t' ||
+ *cp == '\n' || *cp == '\b')
+ size++;
+ }
+
+ return size;
+}
+
+static int
+copy_component_quoting(char *dest, const krb5_data *src, int flags)
+{
+ int j;
+ const char *cp = src->data;
+ char *q = dest;
+ int length = src->length;
+
+ if (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) {
+ (void) memcpy(dest, src->data, src->length);
+ return src->length;
+ }
+
+ for (j=0; j < length; j++,cp++) {
+ int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) &&
+ !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT);
+
+ switch (*cp) {
+ case REALM_SEP:
+ if (no_realm) {
+ *q++ = *cp;
+ break;
+ }
+ /*LINTED*/
+ case COMPONENT_SEP:
+ case '\\':
+ *q++ = '\\';
+ *q++ = *cp;
+ break;
+ case '\t':
+ *q++ = '\\';
+ *q++ = 't';
+ break;
+ case '\n':
+ *q++ = '\\';
+ *q++ = 'n';
+ break;
+ case '\b':
+ *q++ = '\\';
+ *q++ = 'b';
+ break;
+#if 0
+ /* Heimdal escapes spaces in principal names upon unparsing */
+ case ' ':
+ *q++ = '\\';
+ *q++ = ' ';
+ break;
+#endif
+ case '\0':
+ *q++ = '\\';
+ *q++ = '0';
+ break;
+ default:
+ *q++ = *cp;
+ }
+ }
+ /*LINTED*/
+ return q - dest;
+}
+
+static krb5_error_code
+/*LINTED*/
+k5_unparse_name(krb5_context context, krb5_const_principal principal,
+ int flags, char **name, unsigned int *size)
+{
+#if 0
+ /* SUNW17PACresync - lint - cp/length not used */
+ char *cp;
+ int length;
+#endif
+ char *q;
+ int i;
krb5_int32 nelem;
- register unsigned int totalsize = 0;
+ unsigned int totalsize = 0;
+#ifndef _KERNEL
+ /* SUNW17PACresync - princ in kernel will always have realm */
+ char *default_realm = NULL;
+#endif
+ krb5_error_code ret = 0;
if (!principal || !name)
return KRB5_PARSE_MALFORMED;
- cp = krb5_princ_realm(context, principal)->data;
- length = krb5_princ_realm(context, principal)->length;
- totalsize += length;
- for (j = 0; j < length; j++,cp++)
- if (*cp == REALM_SEP || *cp == COMPONENT_SEP ||
- *cp == '\0' || *cp == '\\' || *cp == '\t' ||
- *cp == '\n' || *cp == '\b')
- totalsize++;
- totalsize++; /* This is for the separator */
+#ifndef _KERNEL
+ if (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) {
+ /* omit realm if local realm */
+ krb5_principal_data p;
+
+ ret = krb5_get_default_realm(context, &default_realm);
+ if (ret != 0)
+ goto cleanup;
+
+ krb5_princ_realm(context, &p)->length = strlen(default_realm);
+ krb5_princ_realm(context, &p)->data = default_realm;
+
+ if (krb5_realm_compare(context, &p, principal))
+ flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM;
+ }
+#endif
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) {
+ totalsize += component_length_quoted(krb5_princ_realm(context,
+ principal),
+ flags);
+ totalsize++; /* This is for the separator */
+ }
nelem = krb5_princ_size(context, principal);
for (i = 0; i < (int) nelem; i++) {
+#if 0
+ /* SUNW17PACresync - lint - cp not used */
cp = krb5_princ_component(context, principal, i)->data;
- length = krb5_princ_component(context, principal, i)->length;
- totalsize += length;
- for (j=0; j < length; j++,cp++)
- if (*cp == REALM_SEP || *cp == COMPONENT_SEP ||
- *cp == '\0' || *cp == '\\' || *cp == '\t' ||
- *cp == '\n' || *cp == '\b')
- totalsize++;
+#endif
+ totalsize += component_length_quoted(krb5_princ_component(context, principal, i), flags);
totalsize++; /* This is for the separator */
}
if (nelem == 0)
@@ -104,107 +232,87 @@ krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal, regi
* provided, use it, realloc'ing it if necessary.
*
* We need only n-1 seperators for n components, but we need
- * an extra byte for the NULL at the end.
+ * an extra byte for the NUL at the end.
*/
- /*The realloc case seems to be bogus
- * We never pass non-null name
- */
-
- /* if (*name) {
- if (*size < (totalsize)) {
- *size = totalsize;
- *name = realloc(*name, totalsize);
- }
- } else {
- */
-
- *name = MALLOC(totalsize);
- if (size)
- *size = totalsize;
-
- if (!*name)
- return ENOMEM;
+
+ if (size) {
+ if (*name && (*size < totalsize)) {
+ /* SUNW17PACresync - works for both kernel&user */
+ *name = krb5int_realloc(*name, totalsize, *size);
+ } else {
+ *name = MALLOC(totalsize);
+ }
+ *size = totalsize;
+ } else {
+ *name = MALLOC(totalsize);
+ }
+
+ if (!*name) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
q = *name;
for (i = 0; i < (int) nelem; i++) {
+#if 0
+ /* SUNW17PACresync - lint - cp/length not used */
cp = krb5_princ_component(context, principal, i)->data;
length = krb5_princ_component(context, principal, i)->length;
- for (j=0; j < length; j++,cp++) {
- switch (*cp) {
- case COMPONENT_SEP:
- case REALM_SEP:
- case '\\':
- *q++ = '\\';
- *q++ = *cp;
- break;
- case '\t':
- *q++ = '\\';
- *q++ = 't';
- break;
- case '\n':
- *q++ = '\\';
- *q++ = 'n';
- break;
- case '\b':
- *q++ = '\\';
- *q++ = 'b';
- break;
- case '\0':
- *q++ = '\\';
- *q++ = '0';
- break;
- default:
- *q++ = *cp;
- }
- }
+#endif
+ q += copy_component_quoting(q,
+ krb5_princ_component(context,
+ principal,
+ i),
+ flags);
*q++ = COMPONENT_SEP;
}
if (i > 0)
q--; /* Back up last component separator */
- *q++ = REALM_SEP;
-
- cp = krb5_princ_realm(context, principal)->data;
- length = krb5_princ_realm(context, principal)->length;
- for (j=0; j < length; j++,cp++) {
- switch (*cp) {
- case COMPONENT_SEP:
- case REALM_SEP:
- case '\\':
- *q++ = '\\';
- *q++ = *cp;
- break;
- case '\t':
- *q++ = '\\';
- *q++ = 't';
- break;
- case '\n':
- *q++ = '\\';
- *q++ = 'n';
- break;
- case '\b':
- *q++ = '\\';
- *q++ = 'b';
- break;
- case '\0':
- *q++ = '\\';
- *q++ = '0';
- break;
- default:
- *q++ = *cp;
- }
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) {
+ *q++ = REALM_SEP;
+ q += copy_component_quoting(q, krb5_princ_realm(context, principal), flags);
}
*q++ = '\0';
-
- return 0;
+
+cleanup:
+#ifndef _KERNEL
+ if (default_realm != NULL)
+ krb5_free_default_realm(context, default_realm);
+#endif
+ return ret;
}
krb5_error_code KRB5_CALLCONV
krb5_unparse_name(krb5_context context, krb5_const_principal principal, register char **name)
{
- if (name) /* name == NULL will return error from _ext */
- *name = NULL;
- return(krb5_unparse_name_ext(context, principal, name, NULL));
+ if (name != NULL) /* name == NULL will return error from _ext */
+ *name = NULL;
+
+ return k5_unparse_name(context, principal, 0, name, NULL);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_unparse_name_ext(krb5_context context, krb5_const_principal principal,
+ char **name, unsigned int *size)
+{
+ return k5_unparse_name(context, principal, 0, name, size);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal,
+ int flags, char **name)
+{
+ if (name != NULL)
+ *name = NULL;
+ return k5_unparse_name(context, principal, flags, name, NULL);
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_unparse_name_flags_ext(krb5_context context, krb5_const_principal principal,
+ int flags, char **name, unsigned int *size)
+{
+ return k5_unparse_name(context, principal, flags, name, size);
}
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
index 736fd44a71..e4a6314ce7 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/delete_sec_context.c
@@ -1,9 +1,7 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-
-
/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
@@ -196,6 +194,9 @@ krb5_gss_delete_sec_context(minor_status,
if (ctx->mech_used)
(void) KGSS_RELEASE_OID(minor_status, &ctx->mech_used);
+ if (ctx->authdata)
+ krb5_free_authdata(context, ctx->authdata);
+
if (ctx->k5_context)
krb5_free_context(ctx->k5_context);
diff --git a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c
index d28386c35c..2cc5455d29 100644
--- a/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c
+++ b/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.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.
*/
@@ -296,4 +296,83 @@ kg_set_ccache_name (OM_uint32 *minor_status, const char *name)
*minor_status = 0;
return GSS_S_COMPLETE;
}
+
+#define g_OID_prefix_equal(o1, o2) \
+ (((o1)->length >= (o2)->length) && \
+ (memcmp((o1)->elements, (o2)->elements, (o2)->length) == 0))
+
+/*
+ * gss_inquire_sec_context_by_oid() methods
+ */
+static struct {
+ gss_OID_desc oid;
+ OM_uint32 (*func)(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *);
+} krb5_gss_inquire_sec_context_by_oid_ops[] = {
+ {
+ {GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH, GSS_KRB5_GET_TKT_FLAGS_OID},
+ gss_krb5int_get_tkt_flags
+ },
+ {
+ {GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID},
+ gss_krb5int_extract_authz_data_from_sec_context
+ },
+ {
+ {GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, GSS_KRB5_INQ_SSPI_SESSION_KEY_OID},
+ gss_krb5int_inq_session_key
+ },
+ {
+ {GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID},
+ gss_krb5int_export_lucid_sec_context
+ },
+ {
+ {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID},
+ gss_krb5int_extract_authtime_from_sec_context
+ }
+};
+
+OM_uint32
+krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ krb5_gss_ctx_id_rec *ctx;
+ size_t i;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *minor_status = 0;
+
+ if (desired_object == GSS_C_NO_OID)
+ return GSS_S_CALL_INACCESSIBLE_READ;
+
+ if (data_set == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ if (!kg_validate_ctx_id(context_handle))
+ return GSS_S_NO_CONTEXT;
+
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
+
+ if (!ctx->established)
+ return GSS_S_NO_CONTEXT;
+
+ for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/
+ sizeof(krb5_gss_inquire_sec_context_by_oid_ops[0]); i++) {
+ if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_sec_context_by_oid_ops[i].oid)) {
+ return (*krb5_gss_inquire_sec_context_by_oid_ops[i].func)(minor_status,
+ context_handle,
+ desired_object,
+ data_set);
+ }
+ }
+
+ *minor_status = EINVAL;
+
+ return GSS_S_UNAVAILABLE;
+}
+
#endif