xref: /onnv-gate/usr/src/lib/gss_mechs/mech_krb5/mech/disp_status.c (revision 13132:9615cdbf7b70)
1*13132SGlenn.Barry@oracle.com /* -*- mode: c; indent-tabs-mode: nil -*- */
2*13132SGlenn.Barry@oracle.com /*
3*13132SGlenn.Barry@oracle.com  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
4*13132SGlenn.Barry@oracle.com  */
50Sstevel@tonic-gate /*
60Sstevel@tonic-gate  * Copyright 1993 by OpenVision Technologies, Inc.
7*13132SGlenn.Barry@oracle.com  *
80Sstevel@tonic-gate  * Permission to use, copy, modify, distribute, and sell this software
90Sstevel@tonic-gate  * and its documentation for any purpose is hereby granted without fee,
100Sstevel@tonic-gate  * provided that the above copyright notice appears in all copies and
110Sstevel@tonic-gate  * that both that copyright notice and this permission notice appear in
120Sstevel@tonic-gate  * supporting documentation, and that the name of OpenVision not be used
130Sstevel@tonic-gate  * in advertising or publicity pertaining to distribution of the software
140Sstevel@tonic-gate  * without specific, written prior permission. OpenVision makes no
150Sstevel@tonic-gate  * representations about the suitability of this software for any
160Sstevel@tonic-gate  * purpose.  It is provided "as is" without express or implied warranty.
17*13132SGlenn.Barry@oracle.com  *
180Sstevel@tonic-gate  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
190Sstevel@tonic-gate  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
200Sstevel@tonic-gate  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
210Sstevel@tonic-gate  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
220Sstevel@tonic-gate  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
230Sstevel@tonic-gate  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
240Sstevel@tonic-gate  * PERFORMANCE OF THIS SOFTWARE.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
27*13132SGlenn.Barry@oracle.com #include "gssapiP_krb5.h"
28*13132SGlenn.Barry@oracle.com #include "com_err.h"
29*13132SGlenn.Barry@oracle.com #include <syslog.h>
30*13132SGlenn.Barry@oracle.com /* XXXX internationalization!! */
31*13132SGlenn.Barry@oracle.com 
32*13132SGlenn.Barry@oracle.com static inline int
compare_OM_uint32(OM_uint32 a,OM_uint32 b)33*13132SGlenn.Barry@oracle.com compare_OM_uint32 (OM_uint32 a, OM_uint32 b)
34*13132SGlenn.Barry@oracle.com {
35*13132SGlenn.Barry@oracle.com     if (a < b)
36*13132SGlenn.Barry@oracle.com         return -1;
37*13132SGlenn.Barry@oracle.com     else if (a == b)
38*13132SGlenn.Barry@oracle.com         return 0;
39*13132SGlenn.Barry@oracle.com     else
40*13132SGlenn.Barry@oracle.com         return 1;
41*13132SGlenn.Barry@oracle.com }
42*13132SGlenn.Barry@oracle.com static inline void
free_string(char * s)43*13132SGlenn.Barry@oracle.com free_string (char *s)
44*13132SGlenn.Barry@oracle.com {
45*13132SGlenn.Barry@oracle.com     free(s);
46*13132SGlenn.Barry@oracle.com }
47*13132SGlenn.Barry@oracle.com #include "error_map.h"
48*13132SGlenn.Barry@oracle.com #include <stdio.h>
49*13132SGlenn.Barry@oracle.com /*
50*13132SGlenn.Barry@oracle.com  * AKA krb5_gss_get_error_message.  See #define in gssapiP_krb5.h.
51*13132SGlenn.Barry@oracle.com  */
get_error_message(OM_uint32 minor_code)52*13132SGlenn.Barry@oracle.com char *get_error_message(OM_uint32 minor_code)
53*13132SGlenn.Barry@oracle.com {
54*13132SGlenn.Barry@oracle.com     gsserrmap *p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
55*13132SGlenn.Barry@oracle.com     char *msg = NULL;
56*13132SGlenn.Barry@oracle.com 
57*13132SGlenn.Barry@oracle.com #ifdef DEBUG
58*13132SGlenn.Barry@oracle.com     fprintf(stderr, "%s(%lu, p=%p)", __func__, (unsigned long) minor_code,
59*13132SGlenn.Barry@oracle.com             (void *) p);
60*13132SGlenn.Barry@oracle.com #endif
61*13132SGlenn.Barry@oracle.com     if (p) {
62*13132SGlenn.Barry@oracle.com         char **v = gsserrmap_find(p, minor_code);
63*13132SGlenn.Barry@oracle.com         if (v) {
64*13132SGlenn.Barry@oracle.com             msg = *v;
65*13132SGlenn.Barry@oracle.com #ifdef DEBUG
66*13132SGlenn.Barry@oracle.com             fprintf(stderr, " FOUND!");
67*13132SGlenn.Barry@oracle.com #endif
68*13132SGlenn.Barry@oracle.com         }
69*13132SGlenn.Barry@oracle.com     }
70*13132SGlenn.Barry@oracle.com     if (msg == NULL)
71*13132SGlenn.Barry@oracle.com         msg = (char *)error_message((krb5_error_code)minor_code);
72*13132SGlenn.Barry@oracle.com #ifdef DEBUG
73*13132SGlenn.Barry@oracle.com     fprintf(stderr, " -> %p/%s\n", (void *) msg, msg);
74*13132SGlenn.Barry@oracle.com #endif
75*13132SGlenn.Barry@oracle.com 
76*13132SGlenn.Barry@oracle.com     return msg;
77*13132SGlenn.Barry@oracle.com }
78*13132SGlenn.Barry@oracle.com #define save_error_string_nocopy gss_krb5_save_error_string_nocopy
save_error_string_nocopy(OM_uint32 minor_code,char * msg)79*13132SGlenn.Barry@oracle.com static int save_error_string_nocopy(OM_uint32 minor_code, char *msg)
80*13132SGlenn.Barry@oracle.com {
81*13132SGlenn.Barry@oracle.com     gsserrmap *p;
82*13132SGlenn.Barry@oracle.com     int ret;
835053Sgtb 
84*13132SGlenn.Barry@oracle.com #ifdef DEBUG
85*13132SGlenn.Barry@oracle.com     fprintf(stderr, "%s(%lu, %s)", __func__, (unsigned long) minor_code, msg);
86*13132SGlenn.Barry@oracle.com #endif
87*13132SGlenn.Barry@oracle.com     p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
88*13132SGlenn.Barry@oracle.com     if (!p) {
89*13132SGlenn.Barry@oracle.com         p = malloc(sizeof(*p));
90*13132SGlenn.Barry@oracle.com         if (p == NULL) {
91*13132SGlenn.Barry@oracle.com             ret = 1;
92*13132SGlenn.Barry@oracle.com             goto fail;
93*13132SGlenn.Barry@oracle.com         }
94*13132SGlenn.Barry@oracle.com         if (gsserrmap_init(p) != 0) {
95*13132SGlenn.Barry@oracle.com             free(p);
96*13132SGlenn.Barry@oracle.com             p = NULL;
97*13132SGlenn.Barry@oracle.com             ret = 1;
98*13132SGlenn.Barry@oracle.com             goto fail;
99*13132SGlenn.Barry@oracle.com         }
100*13132SGlenn.Barry@oracle.com         if (k5_setspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE, p) != 0) {
101*13132SGlenn.Barry@oracle.com             gsserrmap_destroy(p);
102*13132SGlenn.Barry@oracle.com             free(p);
103*13132SGlenn.Barry@oracle.com             p = NULL;
104*13132SGlenn.Barry@oracle.com             ret = 1;
105*13132SGlenn.Barry@oracle.com             goto fail;
106*13132SGlenn.Barry@oracle.com         }
107*13132SGlenn.Barry@oracle.com     }
108*13132SGlenn.Barry@oracle.com     ret = gsserrmap_replace_or_insert(p, minor_code, msg);
109*13132SGlenn.Barry@oracle.com     /* Solaris Kerberos */
110*13132SGlenn.Barry@oracle.com     if (ret) {
111*13132SGlenn.Barry@oracle.com             gsserrmap_destroy(p);
112*13132SGlenn.Barry@oracle.com             free(p);
113*13132SGlenn.Barry@oracle.com             p = NULL;
114*13132SGlenn.Barry@oracle.com     }
1150Sstevel@tonic-gate 
116*13132SGlenn.Barry@oracle.com fail:
117*13132SGlenn.Barry@oracle.com #ifdef DEBUG
118*13132SGlenn.Barry@oracle.com     fprintf(stderr, " p=%p %s\n", (void *)p, ret ? "FAIL" : "SUCCESS");
119*13132SGlenn.Barry@oracle.com #endif
120*13132SGlenn.Barry@oracle.com     return ret;
121*13132SGlenn.Barry@oracle.com }
save_error_string(OM_uint32 minor_code,char * msg)122*13132SGlenn.Barry@oracle.com void save_error_string(OM_uint32 minor_code, char *msg)
123*13132SGlenn.Barry@oracle.com {
124*13132SGlenn.Barry@oracle.com     char *s = strdup(msg);
125*13132SGlenn.Barry@oracle.com     if (s) {
126*13132SGlenn.Barry@oracle.com         if (save_error_string_nocopy(minor_code, s) != 0)
127*13132SGlenn.Barry@oracle.com             free(s);
128*13132SGlenn.Barry@oracle.com     }
129*13132SGlenn.Barry@oracle.com }
save_error_message(OM_uint32 minor_code,const char * format,...)130*13132SGlenn.Barry@oracle.com void save_error_message(OM_uint32 minor_code, const char *format, ...)
131*13132SGlenn.Barry@oracle.com {
132*13132SGlenn.Barry@oracle.com     char *s;
133*13132SGlenn.Barry@oracle.com     int n;
134*13132SGlenn.Barry@oracle.com     va_list ap;
135*13132SGlenn.Barry@oracle.com 
136*13132SGlenn.Barry@oracle.com     va_start(ap, format);
137*13132SGlenn.Barry@oracle.com     n = vasprintf(&s, format, ap);
138*13132SGlenn.Barry@oracle.com     va_end(ap);
139*13132SGlenn.Barry@oracle.com     if (n >= 0) {
140*13132SGlenn.Barry@oracle.com         if (save_error_string_nocopy(minor_code, s) != 0)
141*13132SGlenn.Barry@oracle.com             free(s);
142*13132SGlenn.Barry@oracle.com     }
143*13132SGlenn.Barry@oracle.com }
krb5_gss_save_error_info(OM_uint32 minor_code,krb5_context ctx)144*13132SGlenn.Barry@oracle.com void krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx)
145*13132SGlenn.Barry@oracle.com {
146*13132SGlenn.Barry@oracle.com     char *s;
147*13132SGlenn.Barry@oracle.com 
148*13132SGlenn.Barry@oracle.com #ifdef DEBUG
149*13132SGlenn.Barry@oracle.com     fprintf(stderr, "%s(%lu, ctx=%p)\n", __func__,
150*13132SGlenn.Barry@oracle.com             (unsigned long) minor_code, (void *)ctx);
151*13132SGlenn.Barry@oracle.com #endif
152*13132SGlenn.Barry@oracle.com     s = (char *)krb5_get_error_message(ctx, (krb5_error_code)minor_code);
153*13132SGlenn.Barry@oracle.com #ifdef DEBUG
154*13132SGlenn.Barry@oracle.com     fprintf(stderr, "%s(%lu, ctx=%p) saving: %s\n", __func__,
155*13132SGlenn.Barry@oracle.com             (unsigned long) minor_code, (void *)ctx, s);
156*13132SGlenn.Barry@oracle.com #endif
157*13132SGlenn.Barry@oracle.com     save_error_string(minor_code, s);
158*13132SGlenn.Barry@oracle.com     /* The get_error_message call above resets the error message in
159*13132SGlenn.Barry@oracle.com        ctx.  Put it back, in case we make this call again *sigh*.  */
160*13132SGlenn.Barry@oracle.com     krb5_set_error_message(ctx, (krb5_error_code)minor_code, "%s", s);
161*13132SGlenn.Barry@oracle.com     krb5_free_error_message(ctx, s);
162*13132SGlenn.Barry@oracle.com }
krb5_gss_delete_error_info(void * p)163*13132SGlenn.Barry@oracle.com void krb5_gss_delete_error_info(void *p)
164*13132SGlenn.Barry@oracle.com {
165*13132SGlenn.Barry@oracle.com     gsserrmap_destroy(p);
166*13132SGlenn.Barry@oracle.com }
1670Sstevel@tonic-gate 
1685053Sgtb /**/
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate OM_uint32
krb5_gss_display_status(minor_status,status_value,status_type,mech_type,message_context,status_string)1715053Sgtb krb5_gss_display_status(minor_status, status_value, status_type,
172*13132SGlenn.Barry@oracle.com                         mech_type, message_context, status_string)
173*13132SGlenn.Barry@oracle.com     OM_uint32 *minor_status;
174*13132SGlenn.Barry@oracle.com     OM_uint32 status_value;
175*13132SGlenn.Barry@oracle.com     int status_type;
176*13132SGlenn.Barry@oracle.com     gss_OID mech_type;
177*13132SGlenn.Barry@oracle.com     OM_uint32 *message_context;
178*13132SGlenn.Barry@oracle.com     gss_buffer_t status_string;
1790Sstevel@tonic-gate {
180*13132SGlenn.Barry@oracle.com     status_string->length = 0;
181*13132SGlenn.Barry@oracle.com     status_string->value = NULL;
1820Sstevel@tonic-gate 
183*13132SGlenn.Barry@oracle.com     if ((mech_type != GSS_C_NULL_OID) &&
184*13132SGlenn.Barry@oracle.com         !g_OID_equal(gss_mech_krb5, mech_type) &&
185*13132SGlenn.Barry@oracle.com         !g_OID_equal(gss_mech_krb5_old, mech_type)) {
186*13132SGlenn.Barry@oracle.com         *minor_status = 0;
187*13132SGlenn.Barry@oracle.com         return(GSS_S_BAD_MECH);
1880Sstevel@tonic-gate     }
1890Sstevel@tonic-gate 
190*13132SGlenn.Barry@oracle.com     if (status_type == GSS_C_GSS_CODE) {
191*13132SGlenn.Barry@oracle.com         return(g_display_major_status(minor_status, status_value,
192*13132SGlenn.Barry@oracle.com                                       message_context, status_string));
193*13132SGlenn.Barry@oracle.com     } else if (status_type == GSS_C_MECH_CODE) {
194*13132SGlenn.Barry@oracle.com         (void) gss_krb5int_initialize_library();
195*13132SGlenn.Barry@oracle.com 
196*13132SGlenn.Barry@oracle.com         if (*message_context) {
197*13132SGlenn.Barry@oracle.com             *minor_status = (OM_uint32) G_BAD_MSG_CTX;
198*13132SGlenn.Barry@oracle.com             return(GSS_S_FAILURE);
199*13132SGlenn.Barry@oracle.com         }
2000Sstevel@tonic-gate 
201*13132SGlenn.Barry@oracle.com         /* If this fails, there's not much we can do...  */
202*13132SGlenn.Barry@oracle.com         /* Solaris Kerberos - cleaned-up/fixed the return checks/values here */
203*13132SGlenn.Barry@oracle.com         if (!g_make_string_buffer(krb5_gss_get_error_message(status_value),
204*13132SGlenn.Barry@oracle.com                                  status_string)) {
205*13132SGlenn.Barry@oracle.com             *minor_status = ENOMEM;
206*13132SGlenn.Barry@oracle.com             return(GSS_S_FAILURE);
207*13132SGlenn.Barry@oracle.com         }
208*13132SGlenn.Barry@oracle.com         *minor_status = 0;
209*13132SGlenn.Barry@oracle.com         return(GSS_S_COMPLETE);
210*13132SGlenn.Barry@oracle.com     } else {
211*13132SGlenn.Barry@oracle.com         *minor_status = 0;
212*13132SGlenn.Barry@oracle.com         return(GSS_S_BAD_STATUS);
213*13132SGlenn.Barry@oracle.com     }
214*13132SGlenn.Barry@oracle.com }
2150Sstevel@tonic-gate 
216*13132SGlenn.Barry@oracle.com /*
217*13132SGlenn.Barry@oracle.com  * Solaris Kerberos
218*13132SGlenn.Barry@oracle.com  * Hack alert: workaround obfusicated func name issues for mech_spnego.so.
219*13132SGlenn.Barry@oracle.com  */
220*13132SGlenn.Barry@oracle.com OM_uint32
krb5_gss_display_status2(minor_status,status_value,status_type,mech_type,message_context,status_string)221*13132SGlenn.Barry@oracle.com krb5_gss_display_status2(minor_status, status_value, status_type,
222*13132SGlenn.Barry@oracle.com                         mech_type, message_context, status_string)
223*13132SGlenn.Barry@oracle.com     OM_uint32 *minor_status;
224*13132SGlenn.Barry@oracle.com     OM_uint32 status_value;
225*13132SGlenn.Barry@oracle.com     int status_type;
226*13132SGlenn.Barry@oracle.com     gss_OID mech_type;
227*13132SGlenn.Barry@oracle.com     OM_uint32 *message_context;
228*13132SGlenn.Barry@oracle.com     gss_buffer_t status_string;
229*13132SGlenn.Barry@oracle.com {
230*13132SGlenn.Barry@oracle.com         return(krb5_gss_display_status(minor_status, status_value,
231*13132SGlenn.Barry@oracle.com  				  status_type, mech_type, message_context,
232*13132SGlenn.Barry@oracle.com  				  status_string));
2330Sstevel@tonic-gate }
234