1*7f2fe78bSCy Schubert /* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
4*7f2fe78bSCy Schubert *
5*7f2fe78bSCy Schubert */
6*7f2fe78bSCy Schubert
7*7f2fe78bSCy Schubert #include <k5-int.h>
8*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
9*7f2fe78bSCy Schubert #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
10*7f2fe78bSCy Schubert #include <syslog.h>
11*7f2fe78bSCy Schubert #include <kadm5/kadm_rpc.h>
12*7f2fe78bSCy Schubert #include <krb5.h>
13*7f2fe78bSCy Schubert #include <kadm5/admin.h>
14*7f2fe78bSCy Schubert #include <adm_proto.h>
15*7f2fe78bSCy Schubert #include "misc.h"
16*7f2fe78bSCy Schubert #include "kadm5/server_internal.h"
17*7f2fe78bSCy Schubert
18*7f2fe78bSCy Schubert extern void *global_server_handle;
19*7f2fe78bSCy Schubert
20*7f2fe78bSCy Schubert static int check_rpcsec_auth(struct svc_req *);
21*7f2fe78bSCy Schubert
22*7f2fe78bSCy Schubert /*
23*7f2fe78bSCy Schubert * Function: kadm_1
24*7f2fe78bSCy Schubert *
25*7f2fe78bSCy Schubert * Purpose: RPC processing procedure.
26*7f2fe78bSCy Schubert * originally generated from rpcgen
27*7f2fe78bSCy Schubert *
28*7f2fe78bSCy Schubert * Arguments:
29*7f2fe78bSCy Schubert * rqstp (input) rpc request structure
30*7f2fe78bSCy Schubert * transp (input) rpc transport structure
31*7f2fe78bSCy Schubert * (input/output)
32*7f2fe78bSCy Schubert * <return value>
33*7f2fe78bSCy Schubert *
34*7f2fe78bSCy Schubert * Requires:
35*7f2fe78bSCy Schubert * Effects:
36*7f2fe78bSCy Schubert * Modifies:
37*7f2fe78bSCy Schubert */
38*7f2fe78bSCy Schubert
kadm_1(rqstp,transp)39*7f2fe78bSCy Schubert void kadm_1(rqstp, transp)
40*7f2fe78bSCy Schubert struct svc_req *rqstp;
41*7f2fe78bSCy Schubert SVCXPRT *transp;
42*7f2fe78bSCy Schubert {
43*7f2fe78bSCy Schubert union {
44*7f2fe78bSCy Schubert cprinc_arg create_principal_2_arg;
45*7f2fe78bSCy Schubert dprinc_arg delete_principal_2_arg;
46*7f2fe78bSCy Schubert mprinc_arg modify_principal_2_arg;
47*7f2fe78bSCy Schubert rprinc_arg rename_principal_2_arg;
48*7f2fe78bSCy Schubert gprinc_arg get_principal_2_arg;
49*7f2fe78bSCy Schubert chpass_arg chpass_principal_2_arg;
50*7f2fe78bSCy Schubert chrand_arg chrand_principal_2_arg;
51*7f2fe78bSCy Schubert cpol_arg create_policy_2_arg;
52*7f2fe78bSCy Schubert dpol_arg delete_policy_2_arg;
53*7f2fe78bSCy Schubert mpol_arg modify_policy_2_arg;
54*7f2fe78bSCy Schubert gpol_arg get_policy_2_arg;
55*7f2fe78bSCy Schubert setkey_arg setkey_principal_2_arg;
56*7f2fe78bSCy Schubert cprinc3_arg create_principal3_2_arg;
57*7f2fe78bSCy Schubert chpass3_arg chpass_principal3_2_arg;
58*7f2fe78bSCy Schubert chrand3_arg chrand_principal3_2_arg;
59*7f2fe78bSCy Schubert setkey3_arg setkey_principal3_2_arg;
60*7f2fe78bSCy Schubert setkey4_arg setkey_principal4_2_arg;
61*7f2fe78bSCy Schubert getpkeys_arg get_principal_keys_2_arg;
62*7f2fe78bSCy Schubert } argument;
63*7f2fe78bSCy Schubert union {
64*7f2fe78bSCy Schubert generic_ret gen_ret;
65*7f2fe78bSCy Schubert gprinc_ret get_principal_2_ret;
66*7f2fe78bSCy Schubert chrand_ret chrand_principal_2_ret;
67*7f2fe78bSCy Schubert gpol_ret get_policy_2_ret;
68*7f2fe78bSCy Schubert getprivs_ret get_privs_2_ret;
69*7f2fe78bSCy Schubert gprincs_ret get_princs_2_ret;
70*7f2fe78bSCy Schubert gpols_ret get_pols_2_ret;
71*7f2fe78bSCy Schubert chrand_ret chrand_principal3_2_ret;
72*7f2fe78bSCy Schubert gstrings_ret get_string_2_ret;
73*7f2fe78bSCy Schubert getpkeys_ret get_principal_keys_ret;
74*7f2fe78bSCy Schubert } result;
75*7f2fe78bSCy Schubert bool_t retval;
76*7f2fe78bSCy Schubert bool_t (*xdr_argument)(), (*xdr_result)();
77*7f2fe78bSCy Schubert bool_t (*local)();
78*7f2fe78bSCy Schubert
79*7f2fe78bSCy Schubert if (rqstp->rq_cred.oa_flavor != AUTH_GSSAPI &&
80*7f2fe78bSCy Schubert !check_rpcsec_auth(rqstp)) {
81*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, "Authentication attempt failed: %s, "
82*7f2fe78bSCy Schubert "RPC authentication flavor %d",
83*7f2fe78bSCy Schubert client_addr(rqstp->rq_xprt),
84*7f2fe78bSCy Schubert rqstp->rq_cred.oa_flavor);
85*7f2fe78bSCy Schubert svcerr_weakauth(transp);
86*7f2fe78bSCy Schubert return;
87*7f2fe78bSCy Schubert }
88*7f2fe78bSCy Schubert
89*7f2fe78bSCy Schubert switch (rqstp->rq_proc) {
90*7f2fe78bSCy Schubert case NULLPROC:
91*7f2fe78bSCy Schubert (void) svc_sendreply(transp, xdr_void, (char *)NULL);
92*7f2fe78bSCy Schubert return;
93*7f2fe78bSCy Schubert
94*7f2fe78bSCy Schubert case CREATE_PRINCIPAL:
95*7f2fe78bSCy Schubert xdr_argument = xdr_cprinc_arg;
96*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
97*7f2fe78bSCy Schubert local = (bool_t (*)()) create_principal_2_svc;
98*7f2fe78bSCy Schubert break;
99*7f2fe78bSCy Schubert
100*7f2fe78bSCy Schubert case DELETE_PRINCIPAL:
101*7f2fe78bSCy Schubert xdr_argument = xdr_dprinc_arg;
102*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
103*7f2fe78bSCy Schubert local = (bool_t (*)()) delete_principal_2_svc;
104*7f2fe78bSCy Schubert break;
105*7f2fe78bSCy Schubert
106*7f2fe78bSCy Schubert case MODIFY_PRINCIPAL:
107*7f2fe78bSCy Schubert xdr_argument = xdr_mprinc_arg;
108*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
109*7f2fe78bSCy Schubert local = (bool_t (*)()) modify_principal_2_svc;
110*7f2fe78bSCy Schubert break;
111*7f2fe78bSCy Schubert
112*7f2fe78bSCy Schubert case RENAME_PRINCIPAL:
113*7f2fe78bSCy Schubert xdr_argument = xdr_rprinc_arg;
114*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
115*7f2fe78bSCy Schubert local = (bool_t (*)()) rename_principal_2_svc;
116*7f2fe78bSCy Schubert break;
117*7f2fe78bSCy Schubert
118*7f2fe78bSCy Schubert case GET_PRINCIPAL:
119*7f2fe78bSCy Schubert xdr_argument = xdr_gprinc_arg;
120*7f2fe78bSCy Schubert xdr_result = xdr_gprinc_ret;
121*7f2fe78bSCy Schubert local = (bool_t (*)()) get_principal_2_svc;
122*7f2fe78bSCy Schubert break;
123*7f2fe78bSCy Schubert
124*7f2fe78bSCy Schubert case GET_PRINCS:
125*7f2fe78bSCy Schubert xdr_argument = xdr_gprincs_arg;
126*7f2fe78bSCy Schubert xdr_result = xdr_gprincs_ret;
127*7f2fe78bSCy Schubert local = (bool_t (*)()) get_princs_2_svc;
128*7f2fe78bSCy Schubert break;
129*7f2fe78bSCy Schubert
130*7f2fe78bSCy Schubert case CHPASS_PRINCIPAL:
131*7f2fe78bSCy Schubert xdr_argument = xdr_chpass_arg;
132*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
133*7f2fe78bSCy Schubert local = (bool_t (*)()) chpass_principal_2_svc;
134*7f2fe78bSCy Schubert break;
135*7f2fe78bSCy Schubert
136*7f2fe78bSCy Schubert case SETKEY_PRINCIPAL:
137*7f2fe78bSCy Schubert xdr_argument = xdr_setkey_arg;
138*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
139*7f2fe78bSCy Schubert local = (bool_t (*)()) setkey_principal_2_svc;
140*7f2fe78bSCy Schubert break;
141*7f2fe78bSCy Schubert
142*7f2fe78bSCy Schubert case CHRAND_PRINCIPAL:
143*7f2fe78bSCy Schubert xdr_argument = xdr_chrand_arg;
144*7f2fe78bSCy Schubert xdr_result = xdr_chrand_ret;
145*7f2fe78bSCy Schubert local = (bool_t (*)()) chrand_principal_2_svc;
146*7f2fe78bSCy Schubert break;
147*7f2fe78bSCy Schubert
148*7f2fe78bSCy Schubert case CREATE_POLICY:
149*7f2fe78bSCy Schubert xdr_argument = xdr_cpol_arg;
150*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
151*7f2fe78bSCy Schubert local = (bool_t (*)()) create_policy_2_svc;
152*7f2fe78bSCy Schubert break;
153*7f2fe78bSCy Schubert
154*7f2fe78bSCy Schubert case DELETE_POLICY:
155*7f2fe78bSCy Schubert xdr_argument = xdr_dpol_arg;
156*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
157*7f2fe78bSCy Schubert local = (bool_t (*)()) delete_policy_2_svc;
158*7f2fe78bSCy Schubert break;
159*7f2fe78bSCy Schubert
160*7f2fe78bSCy Schubert case MODIFY_POLICY:
161*7f2fe78bSCy Schubert xdr_argument = xdr_mpol_arg;
162*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
163*7f2fe78bSCy Schubert local = (bool_t (*)()) modify_policy_2_svc;
164*7f2fe78bSCy Schubert break;
165*7f2fe78bSCy Schubert
166*7f2fe78bSCy Schubert case GET_POLICY:
167*7f2fe78bSCy Schubert xdr_argument = xdr_gpol_arg;
168*7f2fe78bSCy Schubert xdr_result = xdr_gpol_ret;
169*7f2fe78bSCy Schubert local = (bool_t (*)()) get_policy_2_svc;
170*7f2fe78bSCy Schubert break;
171*7f2fe78bSCy Schubert
172*7f2fe78bSCy Schubert case GET_POLS:
173*7f2fe78bSCy Schubert xdr_argument = xdr_gpols_arg;
174*7f2fe78bSCy Schubert xdr_result = xdr_gpols_ret;
175*7f2fe78bSCy Schubert local = (bool_t (*)()) get_pols_2_svc;
176*7f2fe78bSCy Schubert break;
177*7f2fe78bSCy Schubert
178*7f2fe78bSCy Schubert case GET_PRIVS:
179*7f2fe78bSCy Schubert xdr_argument = xdr_u_int32;
180*7f2fe78bSCy Schubert xdr_result = xdr_getprivs_ret;
181*7f2fe78bSCy Schubert local = (bool_t (*)()) get_privs_2_svc;
182*7f2fe78bSCy Schubert break;
183*7f2fe78bSCy Schubert
184*7f2fe78bSCy Schubert case INIT:
185*7f2fe78bSCy Schubert xdr_argument = xdr_u_int32;
186*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
187*7f2fe78bSCy Schubert local = (bool_t (*)()) init_2_svc;
188*7f2fe78bSCy Schubert break;
189*7f2fe78bSCy Schubert
190*7f2fe78bSCy Schubert case CREATE_PRINCIPAL3:
191*7f2fe78bSCy Schubert xdr_argument = xdr_cprinc3_arg;
192*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
193*7f2fe78bSCy Schubert local = (bool_t (*)()) create_principal3_2_svc;
194*7f2fe78bSCy Schubert break;
195*7f2fe78bSCy Schubert
196*7f2fe78bSCy Schubert case CHPASS_PRINCIPAL3:
197*7f2fe78bSCy Schubert xdr_argument = xdr_chpass3_arg;
198*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
199*7f2fe78bSCy Schubert local = (bool_t (*)()) chpass_principal3_2_svc;
200*7f2fe78bSCy Schubert break;
201*7f2fe78bSCy Schubert
202*7f2fe78bSCy Schubert case CHRAND_PRINCIPAL3:
203*7f2fe78bSCy Schubert xdr_argument = xdr_chrand3_arg;
204*7f2fe78bSCy Schubert xdr_result = xdr_chrand_ret;
205*7f2fe78bSCy Schubert local = (bool_t (*)()) chrand_principal3_2_svc;
206*7f2fe78bSCy Schubert break;
207*7f2fe78bSCy Schubert
208*7f2fe78bSCy Schubert case SETKEY_PRINCIPAL3:
209*7f2fe78bSCy Schubert xdr_argument = xdr_setkey3_arg;
210*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
211*7f2fe78bSCy Schubert local = (bool_t (*)()) setkey_principal3_2_svc;
212*7f2fe78bSCy Schubert break;
213*7f2fe78bSCy Schubert
214*7f2fe78bSCy Schubert case PURGEKEYS:
215*7f2fe78bSCy Schubert xdr_argument = xdr_purgekeys_arg;
216*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
217*7f2fe78bSCy Schubert local = (bool_t (*)()) purgekeys_2_svc;
218*7f2fe78bSCy Schubert break;
219*7f2fe78bSCy Schubert
220*7f2fe78bSCy Schubert case GET_STRINGS:
221*7f2fe78bSCy Schubert xdr_argument = xdr_gstrings_arg;
222*7f2fe78bSCy Schubert xdr_result = xdr_gstrings_ret;
223*7f2fe78bSCy Schubert local = (bool_t (*)()) get_strings_2_svc;
224*7f2fe78bSCy Schubert break;
225*7f2fe78bSCy Schubert
226*7f2fe78bSCy Schubert case SET_STRING:
227*7f2fe78bSCy Schubert xdr_argument = xdr_sstring_arg;
228*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
229*7f2fe78bSCy Schubert local = (bool_t (*)()) set_string_2_svc;
230*7f2fe78bSCy Schubert break;
231*7f2fe78bSCy Schubert
232*7f2fe78bSCy Schubert case SETKEY_PRINCIPAL4:
233*7f2fe78bSCy Schubert xdr_argument = xdr_setkey4_arg;
234*7f2fe78bSCy Schubert xdr_result = xdr_generic_ret;
235*7f2fe78bSCy Schubert local = (bool_t (*)()) setkey_principal4_2_svc;
236*7f2fe78bSCy Schubert break;
237*7f2fe78bSCy Schubert
238*7f2fe78bSCy Schubert case EXTRACT_KEYS:
239*7f2fe78bSCy Schubert xdr_argument = xdr_getpkeys_arg;
240*7f2fe78bSCy Schubert xdr_result = xdr_getpkeys_ret;
241*7f2fe78bSCy Schubert local = (bool_t (*)()) get_principal_keys_2_svc;
242*7f2fe78bSCy Schubert break;
243*7f2fe78bSCy Schubert
244*7f2fe78bSCy Schubert default:
245*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, "Invalid KADM5 procedure number: %s, %d",
246*7f2fe78bSCy Schubert client_addr(rqstp->rq_xprt), rqstp->rq_proc);
247*7f2fe78bSCy Schubert svcerr_noproc(transp);
248*7f2fe78bSCy Schubert return;
249*7f2fe78bSCy Schubert }
250*7f2fe78bSCy Schubert memset(&argument, 0, sizeof(argument));
251*7f2fe78bSCy Schubert if (!svc_getargs(transp, xdr_argument, &argument)) {
252*7f2fe78bSCy Schubert svcerr_decode(transp);
253*7f2fe78bSCy Schubert return;
254*7f2fe78bSCy Schubert }
255*7f2fe78bSCy Schubert memset(&result, 0, sizeof(result));
256*7f2fe78bSCy Schubert retval = (*local)(&argument, &result, rqstp);
257*7f2fe78bSCy Schubert if (retval && !svc_sendreply(transp, xdr_result, (void *)&result)) {
258*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, "WARNING! Unable to send function results, "
259*7f2fe78bSCy Schubert "continuing.");
260*7f2fe78bSCy Schubert svcerr_systemerr(transp);
261*7f2fe78bSCy Schubert }
262*7f2fe78bSCy Schubert if (!svc_freeargs(transp, xdr_argument, &argument)) {
263*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, "WARNING! Unable to free arguments, "
264*7f2fe78bSCy Schubert "continuing.");
265*7f2fe78bSCy Schubert }
266*7f2fe78bSCy Schubert if (!svc_freeargs(transp, xdr_result, &result)) {
267*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, "WARNING! Unable to free results, "
268*7f2fe78bSCy Schubert "continuing.");
269*7f2fe78bSCy Schubert }
270*7f2fe78bSCy Schubert return;
271*7f2fe78bSCy Schubert }
272*7f2fe78bSCy Schubert
273*7f2fe78bSCy Schubert static int
check_rpcsec_auth(struct svc_req * rqstp)274*7f2fe78bSCy Schubert check_rpcsec_auth(struct svc_req *rqstp)
275*7f2fe78bSCy Schubert {
276*7f2fe78bSCy Schubert gss_ctx_id_t ctx;
277*7f2fe78bSCy Schubert krb5_context kctx;
278*7f2fe78bSCy Schubert OM_uint32 maj_stat, min_stat;
279*7f2fe78bSCy Schubert gss_name_t name;
280*7f2fe78bSCy Schubert krb5_principal princ;
281*7f2fe78bSCy Schubert int ret, success;
282*7f2fe78bSCy Schubert krb5_data *c1, *c2, *realm;
283*7f2fe78bSCy Schubert gss_buffer_desc gss_str;
284*7f2fe78bSCy Schubert kadm5_server_handle_t handle;
285*7f2fe78bSCy Schubert size_t slen;
286*7f2fe78bSCy Schubert char *sdots;
287*7f2fe78bSCy Schubert
288*7f2fe78bSCy Schubert success = 0;
289*7f2fe78bSCy Schubert handle = (kadm5_server_handle_t)global_server_handle;
290*7f2fe78bSCy Schubert
291*7f2fe78bSCy Schubert if (rqstp->rq_cred.oa_flavor != RPCSEC_GSS)
292*7f2fe78bSCy Schubert return 0;
293*7f2fe78bSCy Schubert
294*7f2fe78bSCy Schubert ctx = rqstp->rq_svccred;
295*7f2fe78bSCy Schubert
296*7f2fe78bSCy Schubert maj_stat = gss_inquire_context(&min_stat, ctx, NULL, &name,
297*7f2fe78bSCy Schubert NULL, NULL, NULL, NULL, NULL);
298*7f2fe78bSCy Schubert if (maj_stat != GSS_S_COMPLETE) {
299*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, _("check_rpcsec_auth: failed "
300*7f2fe78bSCy Schubert "inquire_context, stat=%u"), maj_stat);
301*7f2fe78bSCy Schubert log_badauth(maj_stat, min_stat, rqstp->rq_xprt, NULL);
302*7f2fe78bSCy Schubert goto fail_name;
303*7f2fe78bSCy Schubert }
304*7f2fe78bSCy Schubert
305*7f2fe78bSCy Schubert kctx = handle->context;
306*7f2fe78bSCy Schubert ret = gss_to_krb5_name_1(rqstp, kctx, name, &princ, &gss_str);
307*7f2fe78bSCy Schubert if (ret == 0)
308*7f2fe78bSCy Schubert goto fail_name;
309*7f2fe78bSCy Schubert
310*7f2fe78bSCy Schubert slen = gss_str.length;
311*7f2fe78bSCy Schubert trunc_name(&slen, &sdots);
312*7f2fe78bSCy Schubert /*
313*7f2fe78bSCy Schubert * Since we accept with GSS_C_NO_NAME, the client can authenticate
314*7f2fe78bSCy Schubert * against the entire kdb. Therefore, ensure that the service
315*7f2fe78bSCy Schubert * name is something reasonable.
316*7f2fe78bSCy Schubert */
317*7f2fe78bSCy Schubert if (krb5_princ_size(kctx, princ) != 2)
318*7f2fe78bSCy Schubert goto fail_princ;
319*7f2fe78bSCy Schubert
320*7f2fe78bSCy Schubert c1 = krb5_princ_component(kctx, princ, 0);
321*7f2fe78bSCy Schubert c2 = krb5_princ_component(kctx, princ, 1);
322*7f2fe78bSCy Schubert realm = krb5_princ_realm(kctx, princ);
323*7f2fe78bSCy Schubert success = data_eq_string(*realm, handle->params.realm) &&
324*7f2fe78bSCy Schubert data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history");
325*7f2fe78bSCy Schubert
326*7f2fe78bSCy Schubert fail_princ:
327*7f2fe78bSCy Schubert if (!success) {
328*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, _("bad service principal %.*s%s"),
329*7f2fe78bSCy Schubert (int) slen, (char *) gss_str.value, sdots);
330*7f2fe78bSCy Schubert }
331*7f2fe78bSCy Schubert gss_release_buffer(&min_stat, &gss_str);
332*7f2fe78bSCy Schubert krb5_free_principal(kctx, princ);
333*7f2fe78bSCy Schubert fail_name:
334*7f2fe78bSCy Schubert gss_release_name(&min_stat, &name);
335*7f2fe78bSCy Schubert return success;
336*7f2fe78bSCy Schubert }
337*7f2fe78bSCy Schubert
338*7f2fe78bSCy Schubert int
gss_to_krb5_name_1(struct svc_req * rqstp,krb5_context ctx,gss_name_t gss_name,krb5_principal * princ,gss_buffer_t gss_str)339*7f2fe78bSCy Schubert gss_to_krb5_name_1(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
340*7f2fe78bSCy Schubert krb5_principal *princ, gss_buffer_t gss_str)
341*7f2fe78bSCy Schubert {
342*7f2fe78bSCy Schubert OM_uint32 status, minor_stat;
343*7f2fe78bSCy Schubert gss_OID gss_type;
344*7f2fe78bSCy Schubert char *str;
345*7f2fe78bSCy Schubert int success;
346*7f2fe78bSCy Schubert
347*7f2fe78bSCy Schubert status = gss_display_name(&minor_stat, gss_name, gss_str, &gss_type);
348*7f2fe78bSCy Schubert if ((status != GSS_S_COMPLETE) || (gss_type != gss_nt_krb5_name)) {
349*7f2fe78bSCy Schubert krb5_klog_syslog(LOG_ERR, _("gss_to_krb5_name: failed display_name "
350*7f2fe78bSCy Schubert "status %d"), status);
351*7f2fe78bSCy Schubert log_badauth(status, minor_stat, rqstp->rq_xprt, NULL);
352*7f2fe78bSCy Schubert return 0;
353*7f2fe78bSCy Schubert }
354*7f2fe78bSCy Schubert str = malloc(gss_str->length +1);
355*7f2fe78bSCy Schubert if (str == NULL)
356*7f2fe78bSCy Schubert return 0;
357*7f2fe78bSCy Schubert *str = '\0';
358*7f2fe78bSCy Schubert
359*7f2fe78bSCy Schubert strncat(str, gss_str->value, gss_str->length);
360*7f2fe78bSCy Schubert success = (krb5_parse_name(ctx, str, princ) == 0);
361*7f2fe78bSCy Schubert free(str);
362*7f2fe78bSCy Schubert return success;
363*7f2fe78bSCy Schubert }
364