1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate */
5*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
6*7c478bd9Sstevel@tonic-gate
7*7c478bd9Sstevel@tonic-gate /* SASL server API implementation
8*7c478bd9Sstevel@tonic-gate * Rob Siemborski
9*7c478bd9Sstevel@tonic-gate * Tim Martin
10*7c478bd9Sstevel@tonic-gate * $Id: external.c,v 1.19 2003/04/08 17:30:54 rjs3 Exp $
11*7c478bd9Sstevel@tonic-gate */
12*7c478bd9Sstevel@tonic-gate /*
13*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
14*7c478bd9Sstevel@tonic-gate *
15*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
16*7c478bd9Sstevel@tonic-gate * modification, are permitted provided that the following conditions
17*7c478bd9Sstevel@tonic-gate * are met:
18*7c478bd9Sstevel@tonic-gate *
19*7c478bd9Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
20*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
21*7c478bd9Sstevel@tonic-gate *
22*7c478bd9Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
23*7c478bd9Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
24*7c478bd9Sstevel@tonic-gate * the documentation and/or other materials provided with the
25*7c478bd9Sstevel@tonic-gate * distribution.
26*7c478bd9Sstevel@tonic-gate *
27*7c478bd9Sstevel@tonic-gate * 3. The name "Carnegie Mellon University" must not be used to
28*7c478bd9Sstevel@tonic-gate * endorse or promote products derived from this software without
29*7c478bd9Sstevel@tonic-gate * prior written permission. For permission or any other legal
30*7c478bd9Sstevel@tonic-gate * details, please contact
31*7c478bd9Sstevel@tonic-gate * Office of Technology Transfer
32*7c478bd9Sstevel@tonic-gate * Carnegie Mellon University
33*7c478bd9Sstevel@tonic-gate * 5000 Forbes Avenue
34*7c478bd9Sstevel@tonic-gate * Pittsburgh, PA 15213-3890
35*7c478bd9Sstevel@tonic-gate * (412) 268-4387, fax: (412) 268-7395
36*7c478bd9Sstevel@tonic-gate * tech-transfer@andrew.cmu.edu
37*7c478bd9Sstevel@tonic-gate *
38*7c478bd9Sstevel@tonic-gate * 4. Redistributions of any form whatsoever must retain the following
39*7c478bd9Sstevel@tonic-gate * acknowledgment:
40*7c478bd9Sstevel@tonic-gate * "This product includes software developed by Computing Services
41*7c478bd9Sstevel@tonic-gate * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
42*7c478bd9Sstevel@tonic-gate *
43*7c478bd9Sstevel@tonic-gate * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
44*7c478bd9Sstevel@tonic-gate * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
45*7c478bd9Sstevel@tonic-gate * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
46*7c478bd9Sstevel@tonic-gate * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47*7c478bd9Sstevel@tonic-gate * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
48*7c478bd9Sstevel@tonic-gate * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
49*7c478bd9Sstevel@tonic-gate * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
50*7c478bd9Sstevel@tonic-gate */
51*7c478bd9Sstevel@tonic-gate
52*7c478bd9Sstevel@tonic-gate #include <config.h>
53*7c478bd9Sstevel@tonic-gate #include <stdio.h>
54*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
55*7c478bd9Sstevel@tonic-gate #include <limits.h>
56*7c478bd9Sstevel@tonic-gate #include <ctype.h>
57*7c478bd9Sstevel@tonic-gate #include <string.h>
58*7c478bd9Sstevel@tonic-gate #include <sasl.h>
59*7c478bd9Sstevel@tonic-gate #include <saslplug.h>
60*7c478bd9Sstevel@tonic-gate #include "saslint.h"
61*7c478bd9Sstevel@tonic-gate
62*7c478bd9Sstevel@tonic-gate #include <plugin_common.h>
63*7c478bd9Sstevel@tonic-gate
64*7c478bd9Sstevel@tonic-gate /***************************** Common Section *****************************/
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate #ifndef _SUN_SDK_
67*7c478bd9Sstevel@tonic-gate static const char plugin_id[] = "$Id: external.c,v 1.19 2003/04/08 17:30:54 rjs3 Exp $";
68*7c478bd9Sstevel@tonic-gate #endif /* !_SUN_SDK_ */
69*7c478bd9Sstevel@tonic-gate
70*7c478bd9Sstevel@tonic-gate /***************************** Server Section *****************************/
71*7c478bd9Sstevel@tonic-gate
72*7c478bd9Sstevel@tonic-gate static int
external_server_mech_new(void * glob_context,sasl_server_params_t * sparams,const char * challenge,unsigned challen,void ** conn_context)73*7c478bd9Sstevel@tonic-gate external_server_mech_new(void *glob_context __attribute__((unused)),
74*7c478bd9Sstevel@tonic-gate sasl_server_params_t *sparams,
75*7c478bd9Sstevel@tonic-gate const char *challenge __attribute__((unused)),
76*7c478bd9Sstevel@tonic-gate unsigned challen __attribute__((unused)),
77*7c478bd9Sstevel@tonic-gate void **conn_context)
78*7c478bd9Sstevel@tonic-gate {
79*7c478bd9Sstevel@tonic-gate if (!conn_context
80*7c478bd9Sstevel@tonic-gate || !sparams
81*7c478bd9Sstevel@tonic-gate || !sparams->utils
82*7c478bd9Sstevel@tonic-gate || !sparams->utils->conn)
83*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
84*7c478bd9Sstevel@tonic-gate
85*7c478bd9Sstevel@tonic-gate if (!sparams->utils->conn->external.auth_id)
86*7c478bd9Sstevel@tonic-gate return SASL_NOMECH;
87*7c478bd9Sstevel@tonic-gate
88*7c478bd9Sstevel@tonic-gate *conn_context = NULL;
89*7c478bd9Sstevel@tonic-gate
90*7c478bd9Sstevel@tonic-gate return SASL_OK;
91*7c478bd9Sstevel@tonic-gate }
92*7c478bd9Sstevel@tonic-gate
93*7c478bd9Sstevel@tonic-gate static int
external_server_mech_step(void * conn_context,sasl_server_params_t * sparams,const char * clientin,unsigned clientinlen,const char ** serverout,unsigned * serveroutlen,sasl_out_params_t * oparams)94*7c478bd9Sstevel@tonic-gate external_server_mech_step(void *conn_context __attribute__((unused)),
95*7c478bd9Sstevel@tonic-gate sasl_server_params_t *sparams,
96*7c478bd9Sstevel@tonic-gate const char *clientin,
97*7c478bd9Sstevel@tonic-gate unsigned clientinlen,
98*7c478bd9Sstevel@tonic-gate const char **serverout,
99*7c478bd9Sstevel@tonic-gate unsigned *serveroutlen,
100*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams)
101*7c478bd9Sstevel@tonic-gate {
102*7c478bd9Sstevel@tonic-gate int result;
103*7c478bd9Sstevel@tonic-gate
104*7c478bd9Sstevel@tonic-gate if (!sparams
105*7c478bd9Sstevel@tonic-gate || !sparams->utils
106*7c478bd9Sstevel@tonic-gate || !sparams->utils->conn
107*7c478bd9Sstevel@tonic-gate || !sparams->utils->getcallback
108*7c478bd9Sstevel@tonic-gate || !serverout
109*7c478bd9Sstevel@tonic-gate || !serveroutlen
110*7c478bd9Sstevel@tonic-gate || !oparams)
111*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
112*7c478bd9Sstevel@tonic-gate
113*7c478bd9Sstevel@tonic-gate if (!sparams->utils->conn->external.auth_id)
114*7c478bd9Sstevel@tonic-gate return SASL_BADPROT;
115*7c478bd9Sstevel@tonic-gate
116*7c478bd9Sstevel@tonic-gate if ((sparams->props.security_flags & SASL_SEC_NOANONYMOUS) &&
117*7c478bd9Sstevel@tonic-gate (!strcmp(sparams->utils->conn->external.auth_id, "anonymous"))) {
118*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
119*7c478bd9Sstevel@tonic-gate sasl_seterror(sparams->utils->conn,0,
120*7c478bd9Sstevel@tonic-gate gettext("anonymous login not allowed"));
121*7c478bd9Sstevel@tonic-gate #else
122*7c478bd9Sstevel@tonic-gate sasl_seterror(sparams->utils->conn,0,"anonymous login not allowed");
123*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
124*7c478bd9Sstevel@tonic-gate return SASL_NOAUTHZ;
125*7c478bd9Sstevel@tonic-gate }
126*7c478bd9Sstevel@tonic-gate
127*7c478bd9Sstevel@tonic-gate *serverout = NULL;
128*7c478bd9Sstevel@tonic-gate *serveroutlen = 0;
129*7c478bd9Sstevel@tonic-gate
130*7c478bd9Sstevel@tonic-gate if (!clientin) {
131*7c478bd9Sstevel@tonic-gate /* No initial data; we're in a protocol which doesn't support it.
132*7c478bd9Sstevel@tonic-gate * So we let the server app know that we need some... */
133*7c478bd9Sstevel@tonic-gate return SASL_CONTINUE;
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate
136*7c478bd9Sstevel@tonic-gate if (clientinlen) { /* if we have a non-zero authorization id */
137*7c478bd9Sstevel@tonic-gate /* The user's trying to authorize as someone they didn't
138*7c478bd9Sstevel@tonic-gate * authenticate as */
139*7c478bd9Sstevel@tonic-gate result = sparams->canon_user(sparams->utils->conn,
140*7c478bd9Sstevel@tonic-gate clientin, 0, SASL_CU_AUTHZID, oparams);
141*7c478bd9Sstevel@tonic-gate if(result != SASL_OK) return result;
142*7c478bd9Sstevel@tonic-gate
143*7c478bd9Sstevel@tonic-gate result = sparams->canon_user(sparams->utils->conn,
144*7c478bd9Sstevel@tonic-gate sparams->utils->conn->external.auth_id, 0,
145*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID, oparams);
146*7c478bd9Sstevel@tonic-gate } else {
147*7c478bd9Sstevel@tonic-gate result = sparams->canon_user(sparams->utils->conn,
148*7c478bd9Sstevel@tonic-gate sparams->utils->conn->external.auth_id, 0,
149*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
150*7c478bd9Sstevel@tonic-gate }
151*7c478bd9Sstevel@tonic-gate
152*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
153*7c478bd9Sstevel@tonic-gate
154*7c478bd9Sstevel@tonic-gate /* set oparams */
155*7c478bd9Sstevel@tonic-gate oparams->doneflag = 1;
156*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0;
157*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0;
158*7c478bd9Sstevel@tonic-gate oparams->encode_context = NULL;
159*7c478bd9Sstevel@tonic-gate oparams->encode = NULL;
160*7c478bd9Sstevel@tonic-gate oparams->decode_context = NULL;
161*7c478bd9Sstevel@tonic-gate oparams->decode = NULL;
162*7c478bd9Sstevel@tonic-gate oparams->param_version = 0;
163*7c478bd9Sstevel@tonic-gate
164*7c478bd9Sstevel@tonic-gate return SASL_OK;
165*7c478bd9Sstevel@tonic-gate }
166*7c478bd9Sstevel@tonic-gate
167*7c478bd9Sstevel@tonic-gate static int
external_server_mech_avail(void * glob_context,sasl_server_params_t * sparams,void ** conn_context)168*7c478bd9Sstevel@tonic-gate external_server_mech_avail(void *glob_context __attribute__((unused)),
169*7c478bd9Sstevel@tonic-gate sasl_server_params_t *sparams,
170*7c478bd9Sstevel@tonic-gate void **conn_context __attribute__((unused)))
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate if (!sparams->utils->conn->external.auth_id)
173*7c478bd9Sstevel@tonic-gate return SASL_NOMECH;
174*7c478bd9Sstevel@tonic-gate return SASL_OK;
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate
177*7c478bd9Sstevel@tonic-gate static sasl_server_plug_t external_server_plugins[] =
178*7c478bd9Sstevel@tonic-gate {
179*7c478bd9Sstevel@tonic-gate {
180*7c478bd9Sstevel@tonic-gate "EXTERNAL", /* mech_name */
181*7c478bd9Sstevel@tonic-gate 0, /* max_ssf */
182*7c478bd9Sstevel@tonic-gate SASL_SEC_NOPLAINTEXT
183*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOANONYMOUS
184*7c478bd9Sstevel@tonic-gate | SASL_SEC_NODICTIONARY, /* security_flags */
185*7c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST
186*7c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */
187*7c478bd9Sstevel@tonic-gate NULL, /* glob_context */
188*7c478bd9Sstevel@tonic-gate &external_server_mech_new, /* mech_new */
189*7c478bd9Sstevel@tonic-gate &external_server_mech_step, /* mech_step */
190*7c478bd9Sstevel@tonic-gate NULL, /* mech_dispose */
191*7c478bd9Sstevel@tonic-gate NULL, /* mech_free */
192*7c478bd9Sstevel@tonic-gate NULL, /* setpass */
193*7c478bd9Sstevel@tonic-gate NULL, /* user_query */
194*7c478bd9Sstevel@tonic-gate NULL, /* idle */
195*7c478bd9Sstevel@tonic-gate &external_server_mech_avail, /* mech_avail */
196*7c478bd9Sstevel@tonic-gate NULL /* spare */
197*7c478bd9Sstevel@tonic-gate }
198*7c478bd9Sstevel@tonic-gate };
199*7c478bd9Sstevel@tonic-gate
external_server_plug_init(const sasl_utils_t * utils,int max_version,int * out_version,sasl_server_plug_t ** pluglist,int * plugcount)200*7c478bd9Sstevel@tonic-gate int external_server_plug_init(const sasl_utils_t *utils,
201*7c478bd9Sstevel@tonic-gate int max_version,
202*7c478bd9Sstevel@tonic-gate int *out_version,
203*7c478bd9Sstevel@tonic-gate sasl_server_plug_t **pluglist,
204*7c478bd9Sstevel@tonic-gate int *plugcount)
205*7c478bd9Sstevel@tonic-gate {
206*7c478bd9Sstevel@tonic-gate if (!out_version || !pluglist || !plugcount)
207*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
208*7c478bd9Sstevel@tonic-gate
209*7c478bd9Sstevel@tonic-gate if (max_version != SASL_SERVER_PLUG_VERSION) {
210*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
211*7c478bd9Sstevel@tonic-gate utils->log(utils->conn, SASL_LOG_ERR, "EXTERNAL version mismatch");
212*7c478bd9Sstevel@tonic-gate #else
213*7c478bd9Sstevel@tonic-gate SETERROR( utils, "EXTERNAL version mismatch" );
214*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
215*7c478bd9Sstevel@tonic-gate return SASL_BADVERS;
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate
218*7c478bd9Sstevel@tonic-gate *out_version = SASL_SERVER_PLUG_VERSION;
219*7c478bd9Sstevel@tonic-gate *pluglist = external_server_plugins;
220*7c478bd9Sstevel@tonic-gate *plugcount = 1;
221*7c478bd9Sstevel@tonic-gate return SASL_OK;
222*7c478bd9Sstevel@tonic-gate }
223*7c478bd9Sstevel@tonic-gate
224*7c478bd9Sstevel@tonic-gate /***************************** Client Section *****************************/
225*7c478bd9Sstevel@tonic-gate
226*7c478bd9Sstevel@tonic-gate typedef struct client_context
227*7c478bd9Sstevel@tonic-gate {
228*7c478bd9Sstevel@tonic-gate char *out_buf;
229*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
230*7c478bd9Sstevel@tonic-gate unsigned out_buf_len;
231*7c478bd9Sstevel@tonic-gate #else
232*7c478bd9Sstevel@tonic-gate size_t out_buf_len;
233*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
234*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
235*7c478bd9Sstevel@tonic-gate void *h;
236*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
237*7c478bd9Sstevel@tonic-gate } client_context_t;
238*7c478bd9Sstevel@tonic-gate
external_client_mech_new(void * glob_context,sasl_client_params_t * params,void ** conn_context)239*7c478bd9Sstevel@tonic-gate static int external_client_mech_new(void *glob_context __attribute__((unused)),
240*7c478bd9Sstevel@tonic-gate sasl_client_params_t *params,
241*7c478bd9Sstevel@tonic-gate void **conn_context)
242*7c478bd9Sstevel@tonic-gate {
243*7c478bd9Sstevel@tonic-gate client_context_t *text;
244*7c478bd9Sstevel@tonic-gate
245*7c478bd9Sstevel@tonic-gate if (!params
246*7c478bd9Sstevel@tonic-gate || !params->utils
247*7c478bd9Sstevel@tonic-gate || !params->utils->conn
248*7c478bd9Sstevel@tonic-gate || !conn_context)
249*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
250*7c478bd9Sstevel@tonic-gate
251*7c478bd9Sstevel@tonic-gate if (!params->utils->conn->external.auth_id)
252*7c478bd9Sstevel@tonic-gate return SASL_NOMECH;
253*7c478bd9Sstevel@tonic-gate
254*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
255*7c478bd9Sstevel@tonic-gate text = params->utils->malloc(sizeof(client_context_t));
256*7c478bd9Sstevel@tonic-gate #else
257*7c478bd9Sstevel@tonic-gate text = sasl_ALLOC(sizeof(client_context_t));
258*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
259*7c478bd9Sstevel@tonic-gate if(!text) return SASL_NOMEM;
260*7c478bd9Sstevel@tonic-gate
261*7c478bd9Sstevel@tonic-gate memset(text, 0, sizeof(client_context_t));
262*7c478bd9Sstevel@tonic-gate
263*7c478bd9Sstevel@tonic-gate *conn_context = text;
264*7c478bd9Sstevel@tonic-gate
265*7c478bd9Sstevel@tonic-gate return SASL_OK;
266*7c478bd9Sstevel@tonic-gate }
267*7c478bd9Sstevel@tonic-gate
268*7c478bd9Sstevel@tonic-gate static int
external_client_mech_step(void * conn_context,sasl_client_params_t * params,const char * serverin,unsigned serverinlen,sasl_interact_t ** prompt_need,const char ** clientout,unsigned * clientoutlen,sasl_out_params_t * oparams)269*7c478bd9Sstevel@tonic-gate external_client_mech_step(void *conn_context,
270*7c478bd9Sstevel@tonic-gate sasl_client_params_t *params,
271*7c478bd9Sstevel@tonic-gate const char *serverin __attribute__((unused)),
272*7c478bd9Sstevel@tonic-gate unsigned serverinlen,
273*7c478bd9Sstevel@tonic-gate sasl_interact_t **prompt_need,
274*7c478bd9Sstevel@tonic-gate const char **clientout,
275*7c478bd9Sstevel@tonic-gate unsigned *clientoutlen,
276*7c478bd9Sstevel@tonic-gate sasl_out_params_t *oparams)
277*7c478bd9Sstevel@tonic-gate {
278*7c478bd9Sstevel@tonic-gate client_context_t *text = (client_context_t *)conn_context;
279*7c478bd9Sstevel@tonic-gate const char *user = NULL;
280*7c478bd9Sstevel@tonic-gate int user_result = SASL_OK;
281*7c478bd9Sstevel@tonic-gate int result;
282*7c478bd9Sstevel@tonic-gate
283*7c478bd9Sstevel@tonic-gate if (!params
284*7c478bd9Sstevel@tonic-gate || !params->utils
285*7c478bd9Sstevel@tonic-gate || !params->utils->conn
286*7c478bd9Sstevel@tonic-gate || !params->utils->getcallback
287*7c478bd9Sstevel@tonic-gate || !clientout
288*7c478bd9Sstevel@tonic-gate || !clientoutlen
289*7c478bd9Sstevel@tonic-gate || !oparams)
290*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
291*7c478bd9Sstevel@tonic-gate
292*7c478bd9Sstevel@tonic-gate if (!params->utils->conn->external.auth_id)
293*7c478bd9Sstevel@tonic-gate return SASL_BADPROT;
294*7c478bd9Sstevel@tonic-gate
295*7c478bd9Sstevel@tonic-gate if (serverinlen != 0)
296*7c478bd9Sstevel@tonic-gate return SASL_BADPROT;
297*7c478bd9Sstevel@tonic-gate
298*7c478bd9Sstevel@tonic-gate *clientout = NULL;
299*7c478bd9Sstevel@tonic-gate *clientoutlen = 0;
300*7c478bd9Sstevel@tonic-gate
301*7c478bd9Sstevel@tonic-gate /* try to get the userid */
302*7c478bd9Sstevel@tonic-gate if (user == NULL) {
303*7c478bd9Sstevel@tonic-gate user_result = _plug_get_userid(params->utils, &user, prompt_need);
304*7c478bd9Sstevel@tonic-gate
305*7c478bd9Sstevel@tonic-gate if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
306*7c478bd9Sstevel@tonic-gate return user_result;
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate
309*7c478bd9Sstevel@tonic-gate /* free prompts we got */
310*7c478bd9Sstevel@tonic-gate if (prompt_need && *prompt_need) {
311*7c478bd9Sstevel@tonic-gate params->utils->free(*prompt_need);
312*7c478bd9Sstevel@tonic-gate *prompt_need = NULL;
313*7c478bd9Sstevel@tonic-gate }
314*7c478bd9Sstevel@tonic-gate
315*7c478bd9Sstevel@tonic-gate /* if there are prompts not filled in */
316*7c478bd9Sstevel@tonic-gate if (user_result == SASL_INTERACT) {
317*7c478bd9Sstevel@tonic-gate /* make the prompt list */
318*7c478bd9Sstevel@tonic-gate int result =
319*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
320*7c478bd9Sstevel@tonic-gate _plug_make_prompts(params->utils, &text->h, prompt_need,
321*7c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ?
322*7c478bd9Sstevel@tonic-gate convert_prompt(params->utils, &text->h,
323*7c478bd9Sstevel@tonic-gate gettext("Please enter your authorization name"))
324*7c478bd9Sstevel@tonic-gate : NULL,
325*7c478bd9Sstevel@tonic-gate #else
326*7c478bd9Sstevel@tonic-gate _plug_make_prompts(params->utils, prompt_need,
327*7c478bd9Sstevel@tonic-gate user_result == SASL_INTERACT ?
328*7c478bd9Sstevel@tonic-gate "Please enter your authorization name" : NULL,
329*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
330*7c478bd9Sstevel@tonic-gate "",
331*7c478bd9Sstevel@tonic-gate NULL, NULL,
332*7c478bd9Sstevel@tonic-gate NULL, NULL,
333*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL,
334*7c478bd9Sstevel@tonic-gate NULL, NULL, NULL);
335*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate return SASL_INTERACT;
338*7c478bd9Sstevel@tonic-gate }
339*7c478bd9Sstevel@tonic-gate
340*7c478bd9Sstevel@tonic-gate *clientoutlen = user ? strlen(user) : 0;
341*7c478bd9Sstevel@tonic-gate
342*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
343*7c478bd9Sstevel@tonic-gate result = _plug_buf_alloc(params->utils, &text->out_buf,
344*7c478bd9Sstevel@tonic-gate &text->out_buf_len, *clientoutlen + 1);
345*7c478bd9Sstevel@tonic-gate #else
346*7c478bd9Sstevel@tonic-gate result = _buf_alloc(&text->out_buf, &text->out_buf_len, *clientoutlen + 1);
347*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
348*7c478bd9Sstevel@tonic-gate
349*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
350*7c478bd9Sstevel@tonic-gate
351*7c478bd9Sstevel@tonic-gate if (user && *user) {
352*7c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn,
353*7c478bd9Sstevel@tonic-gate user, 0, SASL_CU_AUTHZID, oparams);
354*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
355*7c478bd9Sstevel@tonic-gate
356*7c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn,
357*7c478bd9Sstevel@tonic-gate params->utils->conn->external.auth_id, 0,
358*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID, oparams);
359*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
360*7c478bd9Sstevel@tonic-gate
361*7c478bd9Sstevel@tonic-gate memcpy(text->out_buf, user, *clientoutlen);
362*7c478bd9Sstevel@tonic-gate } else {
363*7c478bd9Sstevel@tonic-gate result = params->canon_user(params->utils->conn,
364*7c478bd9Sstevel@tonic-gate params->utils->conn->external.auth_id, 0,
365*7c478bd9Sstevel@tonic-gate SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
366*7c478bd9Sstevel@tonic-gate if (result != SASL_OK) return result;
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate
369*7c478bd9Sstevel@tonic-gate text->out_buf[*clientoutlen] = '\0';
370*7c478bd9Sstevel@tonic-gate
371*7c478bd9Sstevel@tonic-gate *clientout = text->out_buf;
372*7c478bd9Sstevel@tonic-gate
373*7c478bd9Sstevel@tonic-gate /* set oparams */
374*7c478bd9Sstevel@tonic-gate oparams->doneflag = 1;
375*7c478bd9Sstevel@tonic-gate oparams->mech_ssf = 0;
376*7c478bd9Sstevel@tonic-gate oparams->maxoutbuf = 0;
377*7c478bd9Sstevel@tonic-gate oparams->encode_context = NULL;
378*7c478bd9Sstevel@tonic-gate oparams->encode = NULL;
379*7c478bd9Sstevel@tonic-gate oparams->decode_context = NULL;
380*7c478bd9Sstevel@tonic-gate oparams->decode = NULL;
381*7c478bd9Sstevel@tonic-gate oparams->param_version = 0;
382*7c478bd9Sstevel@tonic-gate
383*7c478bd9Sstevel@tonic-gate return SASL_OK;
384*7c478bd9Sstevel@tonic-gate }
385*7c478bd9Sstevel@tonic-gate
386*7c478bd9Sstevel@tonic-gate static void
external_client_mech_dispose(void * conn_context,const sasl_utils_t * utils)387*7c478bd9Sstevel@tonic-gate external_client_mech_dispose(void *conn_context,
388*7c478bd9Sstevel@tonic-gate const sasl_utils_t *utils __attribute__((unused)))
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate client_context_t *text = (client_context_t *) conn_context;
391*7c478bd9Sstevel@tonic-gate
392*7c478bd9Sstevel@tonic-gate if (!text) return;
393*7c478bd9Sstevel@tonic-gate
394*7c478bd9Sstevel@tonic-gate #ifdef _INTEGRATED_SOLARIS_
395*7c478bd9Sstevel@tonic-gate convert_prompt(utils, &text->h, NULL);
396*7c478bd9Sstevel@tonic-gate #endif /* _INTEGRATED_SOLARIS_ */
397*7c478bd9Sstevel@tonic-gate
398*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
399*7c478bd9Sstevel@tonic-gate if(text->out_buf) utils->free(text->out_buf);
400*7c478bd9Sstevel@tonic-gate
401*7c478bd9Sstevel@tonic-gate utils->free(text);
402*7c478bd9Sstevel@tonic-gate #else
403*7c478bd9Sstevel@tonic-gate if(text->out_buf) sasl_FREE(text->out_buf);
404*7c478bd9Sstevel@tonic-gate
405*7c478bd9Sstevel@tonic-gate sasl_FREE(text);
406*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
407*7c478bd9Sstevel@tonic-gate }
408*7c478bd9Sstevel@tonic-gate
409*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
410*7c478bd9Sstevel@tonic-gate static const unsigned long external_required_prompts[] = {
411*7c478bd9Sstevel@tonic-gate #else
412*7c478bd9Sstevel@tonic-gate static const long external_required_prompts[] = {
413*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
414*7c478bd9Sstevel@tonic-gate SASL_CB_LIST_END
415*7c478bd9Sstevel@tonic-gate };
416*7c478bd9Sstevel@tonic-gate
417*7c478bd9Sstevel@tonic-gate static sasl_client_plug_t external_client_plugins[] =
418*7c478bd9Sstevel@tonic-gate {
419*7c478bd9Sstevel@tonic-gate {
420*7c478bd9Sstevel@tonic-gate "EXTERNAL", /* mech_name */
421*7c478bd9Sstevel@tonic-gate 0, /* max_ssf */
422*7c478bd9Sstevel@tonic-gate SASL_SEC_NOPLAINTEXT
423*7c478bd9Sstevel@tonic-gate | SASL_SEC_NOANONYMOUS
424*7c478bd9Sstevel@tonic-gate | SASL_SEC_NODICTIONARY, /* security_flags */
425*7c478bd9Sstevel@tonic-gate SASL_FEAT_WANT_CLIENT_FIRST
426*7c478bd9Sstevel@tonic-gate | SASL_FEAT_ALLOWS_PROXY, /* features */
427*7c478bd9Sstevel@tonic-gate external_required_prompts, /* required_prompts */
428*7c478bd9Sstevel@tonic-gate NULL, /* glob_context */
429*7c478bd9Sstevel@tonic-gate &external_client_mech_new, /* mech_new */
430*7c478bd9Sstevel@tonic-gate &external_client_mech_step, /* mech_step */
431*7c478bd9Sstevel@tonic-gate &external_client_mech_dispose, /* mech_dispose */
432*7c478bd9Sstevel@tonic-gate NULL, /* mech_free */
433*7c478bd9Sstevel@tonic-gate NULL, /* idle */
434*7c478bd9Sstevel@tonic-gate NULL, /* spare */
435*7c478bd9Sstevel@tonic-gate NULL /* spare */
436*7c478bd9Sstevel@tonic-gate }
437*7c478bd9Sstevel@tonic-gate };
438*7c478bd9Sstevel@tonic-gate
external_client_plug_init(const sasl_utils_t * utils,int max_version,int * out_version,sasl_client_plug_t ** pluglist,int * plugcount)439*7c478bd9Sstevel@tonic-gate int external_client_plug_init(const sasl_utils_t *utils,
440*7c478bd9Sstevel@tonic-gate int max_version,
441*7c478bd9Sstevel@tonic-gate int *out_version,
442*7c478bd9Sstevel@tonic-gate sasl_client_plug_t **pluglist,
443*7c478bd9Sstevel@tonic-gate int *plugcount)
444*7c478bd9Sstevel@tonic-gate {
445*7c478bd9Sstevel@tonic-gate if (!utils || !out_version || !pluglist || !plugcount)
446*7c478bd9Sstevel@tonic-gate return SASL_BADPARAM;
447*7c478bd9Sstevel@tonic-gate
448*7c478bd9Sstevel@tonic-gate if (max_version != SASL_CLIENT_PLUG_VERSION) {
449*7c478bd9Sstevel@tonic-gate #ifdef _SUN_SDK_
450*7c478bd9Sstevel@tonic-gate utils->log(utils->conn, SASL_LOG_ERR, "EXTERNAL version mismatch");
451*7c478bd9Sstevel@tonic-gate #else
452*7c478bd9Sstevel@tonic-gate SETERROR( utils, "EXTERNAL version mismatch" );
453*7c478bd9Sstevel@tonic-gate #endif /* _SUN_SDK_ */
454*7c478bd9Sstevel@tonic-gate return SASL_BADVERS;
455*7c478bd9Sstevel@tonic-gate }
456*7c478bd9Sstevel@tonic-gate
457*7c478bd9Sstevel@tonic-gate *out_version = SASL_CLIENT_PLUG_VERSION;
458*7c478bd9Sstevel@tonic-gate *pluglist = external_client_plugins;
459*7c478bd9Sstevel@tonic-gate *plugcount = 1;
460*7c478bd9Sstevel@tonic-gate
461*7c478bd9Sstevel@tonic-gate return SASL_OK;
462*7c478bd9Sstevel@tonic-gate }
463