4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1996-1997,2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/systm.h>
30 #include <sys/errno.h>
31 #include <sys/cmn_err.h>
32 #include <gssapi/gssapi.h>
34 #include <rpc/rpcsec_defs.h>
38 * Kernel rpcsec_gss module debugging aid. The global variable "rpcgss_log"
39 * is a bit mask which allows various types of debugging messages to be printed
42 * rpcgss_log & 1 will cause actual failures to be printed.
43 * rpcgss_log & 2 will cause informational messages to be
44 * printed on the client side of rpcsec_gss.
45 * rpcgss_log & 4 will cause informational messages to be
46 * printed on the server side of rpcsec_gss.
47 * rpcgss_log & 8 will cause informational messages to be
48 * printed on both client and server side of rpcsec_gss.
51 uint_t rpcgss_log
= 0;
53 #endif /* RPCGSS_DEBUG */
56 * Internal utility routines.
60 * Duplicate a gss_OID value.
63 __rpc_gss_dup_oid(gss_OID oid
, gss_OID
*ret
)
67 if (oid
== GSS_C_NULL_OID
|| oid
->length
== 0) {
72 tmp
= (gss_OID
) kmem_alloc(sizeof (gss_OID_desc
), KM_SLEEP
);
74 tmp
->elements
= kmem_alloc((oid
->length
), KM_SLEEP
);
75 bcopy((char *)oid
->elements
, (char *)tmp
->elements
, oid
->length
);
76 tmp
->length
= oid
->length
;
84 * Check if 2 gss_OID are the same.
87 __rpc_gss_oids_equal(oid1
, oid2
)
90 if ((oid1
->length
== 0) && (oid2
->length
== 0))
93 if (oid1
->length
!= oid2
->length
)
96 return (bcmp(oid1
->elements
, oid2
->elements
, oid1
->length
) == 0);
100 __rpc_gss_convert_name(principal
, name
, name_type
)
101 rpc_gss_principal_t principal
;
102 gss_buffer_desc
*name
;
107 cp
= principal
->name
;
109 *name_type
= GSS_C_NULL_OID
;
111 (*name_type
)->length
= *(int *)cp
;
112 (*name_type
)->elements
= (void *)(cp
+ sizeof (int));
114 cp
+= RNDUP(*(int *)cp
) + sizeof (int);
115 if ((name
->length
= *(int *)cp
) == 0)
118 name
->value
= cp
+ sizeof (int);
122 * Make a client principal name from a flat exported gss name.
125 __rpc_gss_make_principal(principal
, name
)
126 rpc_gss_principal_t
*principal
;
127 gss_buffer_desc
*name
;
132 RPCGSS_LOG(8, "name-length = %lu\n", name
->length
);
133 RPCGSS_LOG(8, "name-value = 0x%p\n", (void *)name
->value
);
135 plen
= RNDUP(name
->length
) + sizeof (int);
136 (*principal
) = (rpc_gss_principal_t
)kmem_alloc(plen
, KM_SLEEP
);
137 if ((*principal
) == NULL
)
139 bzero((caddr_t
)(*principal
), plen
);
140 (*principal
)->len
= RNDUP(name
->length
);
141 s
= (*principal
)->name
;
142 bcopy(name
->value
, s
, name
->length
);
148 * Make a copy of a principal name.
151 __rpc_gss_dup_principal(principal
)
152 rpc_gss_principal_t principal
;
154 rpc_gss_principal_t pdup
;
157 if (principal
== NULL
)
159 len
= principal
->len
+ sizeof (int);
160 if ((pdup
= (rpc_gss_principal_t
)mem_alloc(len
)) == NULL
)
163 bcopy(principal
->name
, pdup
->name
, len
);
168 * Returns highest and lowest versions of RPCSEC_GSS flavor supported.
171 rpc_gss_get_versions(vers_hi
, vers_lo
)
175 *vers_hi
= RPCSEC_GSS_VERSION
;
176 *vers_lo
= RPCSEC_GSS_VERSION
;
181 rpc_gss_display_status(major
, minor
, mech_type
,
182 uid
, gss_function_name
)
183 OM_uint32 major
, minor
;
186 char *gss_function_name
;
192 gss_buffer_desc status_string
;
195 * Before we return let us see
196 * whether we can log more meaningful error
197 * string using kgss_display_status
198 * If we can not just log the gssstat in hex
204 * First get the status string out of gss_major_code
208 major_stat
= kgss_display_status(&minor_stat
, major
,
209 GSS_C_GSS_CODE
, mech_type
,
210 &message_context
, &status_string
, uid
);
212 * If we failed just log the original error codes
214 if (major_stat
!= GSS_S_COMPLETE
&&
215 major
!= GSS_S_CONTINUE_NEEDED
) {
217 RPCGSS_LOG1(1, "%s GSS major error 0x%x\n",
218 gss_function_name
, major
);
219 RPCGSS_LOG1(1, "%s GSS minor error 0x%x\n",
220 gss_function_name
, minor
);
224 RPCGSS_LOG1(1, "%s GSS Error %s\n",
225 (char *)gss_function_name
,
226 (char *)status_string
.value
);
227 (void) gss_release_buffer(&minor_stat
, &status_string
);
229 } while (message_context
!= 0);
231 * Now get the status string out of gss_minor_code
232 * This is mechanism specific error which is most
237 major_stat
= kgss_display_status(&minor_stat
, minor
,
238 GSS_C_MECH_CODE
, mech_type
,
239 &message_context
, &status_string
, uid
);
240 if (major_stat
!= GSS_S_COMPLETE
&&
241 major_stat
!= GSS_S_CONTINUE_NEEDED
) {
242 RPCGSS_LOG1(1, "%s GSS minor error 0x%x\n",
243 gss_function_name
, minor
);
247 "%s GSS Minor Error %s\n",
248 (char *)gss_function_name
, (char *)status_string
.value
);
249 (void) gss_release_buffer(&minor_stat
,
252 } while (message_context
!= 0);