xref: /titanic_50/usr/src/cmd/ldap/common/ldaptool-sasl.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /*
9*7c478bd9Sstevel@tonic-gate  * File for ldaptool routines for SASL
10*7c478bd9Sstevel@tonic-gate  */
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate #include <ldap.h>
13*7c478bd9Sstevel@tonic-gate #include "ldaptool-sasl.h"
14*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
15*7c478bd9Sstevel@tonic-gate #include <sasl/sasl.h>
16*7c478bd9Sstevel@tonic-gate #include <locale.h>
17*7c478bd9Sstevel@tonic-gate #include "ldaptool.h"
18*7c478bd9Sstevel@tonic-gate #else
19*7c478bd9Sstevel@tonic-gate #include <sasl.h>
20*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
21*7c478bd9Sstevel@tonic-gate #include <stdio.h>
22*7c478bd9Sstevel@tonic-gate 
23*7c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
24*7c478bd9Sstevel@tonic-gate #define gettext(s) s
25*7c478bd9Sstevel@tonic-gate #endif
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #define SASL_PROMPT	"SASL"
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate typedef struct {
32*7c478bd9Sstevel@tonic-gate         char *mech;
33*7c478bd9Sstevel@tonic-gate         char *authid;
34*7c478bd9Sstevel@tonic-gate         char *username;
35*7c478bd9Sstevel@tonic-gate         char *passwd;
36*7c478bd9Sstevel@tonic-gate         char *realm;
37*7c478bd9Sstevel@tonic-gate } ldaptoolSASLdefaults;
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate static int get_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact);
40*7c478bd9Sstevel@tonic-gate static int get_new_value(sasl_interact_t *interact, unsigned flags);
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate void *
43*7c478bd9Sstevel@tonic-gate ldaptool_set_sasl_defaults ( LDAP *ld, char *mech, char *authid, char *username,
44*7c478bd9Sstevel@tonic-gate 				 char *passwd, char *realm )
45*7c478bd9Sstevel@tonic-gate {
46*7c478bd9Sstevel@tonic-gate         ldaptoolSASLdefaults *defaults;
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate         if ((defaults = calloc(sizeof(defaults[0]), 1)) == NULL)
49*7c478bd9Sstevel@tonic-gate 		return NULL;
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate 	if (mech)
52*7c478bd9Sstevel@tonic-gate 		defaults->mech = mech;
53*7c478bd9Sstevel@tonic-gate 	else
54*7c478bd9Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 	if (authid)
57*7c478bd9Sstevel@tonic-gate 		defaults->authid = authid;
58*7c478bd9Sstevel@tonic-gate 	else
59*7c478bd9Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authid);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 	if (username)
62*7c478bd9Sstevel@tonic-gate 		defaults->username = username;
63*7c478bd9Sstevel@tonic-gate 	else
64*7c478bd9Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->username);
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate         defaults->passwd = passwd;
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate 	if (realm)
69*7c478bd9Sstevel@tonic-gate 		defaults->realm = realm;
70*7c478bd9Sstevel@tonic-gate 	else
71*7c478bd9Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate         return defaults;
74*7c478bd9Sstevel@tonic-gate }
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate int
77*7c478bd9Sstevel@tonic-gate ldaptool_sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *prompts ) {
78*7c478bd9Sstevel@tonic-gate 	sasl_interact_t		*interact;
79*7c478bd9Sstevel@tonic-gate 	ldaptoolSASLdefaults	*sasldefaults = defaults;
80*7c478bd9Sstevel@tonic-gate 	int			rc;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate 	if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
83*7c478bd9Sstevel@tonic-gate 		return (LDAP_PARAM_ERROR);
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate 	for (interact = prompts; interact->id != SASL_CB_LIST_END; interact++) {
86*7c478bd9Sstevel@tonic-gate 		/* Obtain the default value */
87*7c478bd9Sstevel@tonic-gate 		if ((rc = get_default(sasldefaults, interact)) != LDAP_SUCCESS)
88*7c478bd9Sstevel@tonic-gate 			return (rc);
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate 		/* If no default, get the new value from stdin */
91*7c478bd9Sstevel@tonic-gate 		if (interact->result == NULL) {
92*7c478bd9Sstevel@tonic-gate 			if ((rc = get_new_value(interact, flags)) != LDAP_SUCCESS)
93*7c478bd9Sstevel@tonic-gate 				return (rc);
94*7c478bd9Sstevel@tonic-gate 		}
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	}
97*7c478bd9Sstevel@tonic-gate 	return (LDAP_SUCCESS);
98*7c478bd9Sstevel@tonic-gate }
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate static int
101*7c478bd9Sstevel@tonic-gate get_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact) {
102*7c478bd9Sstevel@tonic-gate 	const char	*defvalue = interact->defresult;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	if (defaults != NULL) {
105*7c478bd9Sstevel@tonic-gate 		switch( interact->id ) {
106*7c478bd9Sstevel@tonic-gate         	case SASL_CB_AUTHNAME:
107*7c478bd9Sstevel@tonic-gate 			defvalue = defaults->authid;
108*7c478bd9Sstevel@tonic-gate 			break;
109*7c478bd9Sstevel@tonic-gate         	case SASL_CB_USER:
110*7c478bd9Sstevel@tonic-gate 			defvalue = defaults->username;
111*7c478bd9Sstevel@tonic-gate 			break;
112*7c478bd9Sstevel@tonic-gate         	case SASL_CB_PASS:
113*7c478bd9Sstevel@tonic-gate 			defvalue = defaults->passwd;
114*7c478bd9Sstevel@tonic-gate 			break;
115*7c478bd9Sstevel@tonic-gate         	case SASL_CB_GETREALM:
116*7c478bd9Sstevel@tonic-gate 			defvalue = defaults->realm;
117*7c478bd9Sstevel@tonic-gate 			break;
118*7c478bd9Sstevel@tonic-gate 		}
119*7c478bd9Sstevel@tonic-gate 	}
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	if (defvalue != NULL) {
122*7c478bd9Sstevel@tonic-gate 		interact->result = (char *)malloc(strlen(defvalue)+1);
123*7c478bd9Sstevel@tonic-gate 		if ((char *)interact->result != NULL) {
124*7c478bd9Sstevel@tonic-gate 			strcpy((char *)interact->result,defvalue);
125*7c478bd9Sstevel@tonic-gate 			interact->len = strlen((char *)(interact->result));
126*7c478bd9Sstevel@tonic-gate 		}
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 		/* Clear passwd */
129*7c478bd9Sstevel@tonic-gate 		if (interact->id == SASL_CB_PASS && defaults != NULL) {
130*7c478bd9Sstevel@tonic-gate 			/* At this point defaults->passwd is not NULL */
131*7c478bd9Sstevel@tonic-gate             		memset( defaults->passwd, '\0', strlen(defaults->passwd));
132*7c478bd9Sstevel@tonic-gate 		}
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 		if ((char *)interact->result == NULL) {
135*7c478bd9Sstevel@tonic-gate 			return (LDAP_NO_MEMORY);
136*7c478bd9Sstevel@tonic-gate 		}
137*7c478bd9Sstevel@tonic-gate 	}
138*7c478bd9Sstevel@tonic-gate 	return (LDAP_SUCCESS);
139*7c478bd9Sstevel@tonic-gate }
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate static int
142*7c478bd9Sstevel@tonic-gate get_new_value(sasl_interact_t *interact, unsigned flags) {
143*7c478bd9Sstevel@tonic-gate 	char	*newvalue, str[1024];
144*7c478bd9Sstevel@tonic-gate 	int	len;
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
147*7c478bd9Sstevel@tonic-gate 	char	*tmpstr;
148*7c478bd9Sstevel@tonic-gate #endif
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	if (interact->id == SASL_CB_ECHOPROMPT || interact->id == SASL_CB_NOECHOPROMPT) {
151*7c478bd9Sstevel@tonic-gate 		if (interact->challenge)
152*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, gettext("Challenge:%s\n"), interact->challenge);
153*7c478bd9Sstevel@tonic-gate 	}
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
156*7c478bd9Sstevel@tonic-gate 	tmpstr = ldaptool_UTF82local(interact->prompt);
157*7c478bd9Sstevel@tonic-gate 	snprintf(str, sizeof(str), "%s:", tmpstr?tmpstr:SASL_PROMPT);
158*7c478bd9Sstevel@tonic-gate 	if (tmpstr != NULL)
159*7c478bd9Sstevel@tonic-gate 		free(tmpstr);
160*7c478bd9Sstevel@tonic-gate #else
161*7c478bd9Sstevel@tonic-gate #ifdef HAVE_SNPRINTF
162*7c478bd9Sstevel@tonic-gate 	snprintf(str, sizeof(str), "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
163*7c478bd9Sstevel@tonic-gate #else
164*7c478bd9Sstevel@tonic-gate 	sprintf(str, "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
165*7c478bd9Sstevel@tonic-gate #endif
166*7c478bd9Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	/* Get the new value */
169*7c478bd9Sstevel@tonic-gate 	if (interact->id == SASL_CB_PASS || interact->id == SASL_CB_NOECHOPROMPT) {
170*7c478bd9Sstevel@tonic-gate #if defined(_WIN32)
171*7c478bd9Sstevel@tonic-gate 		char pbuf[257];
172*7c478bd9Sstevel@tonic-gate 		fputs(str,stdout);
173*7c478bd9Sstevel@tonic-gate 		fflush(stdout);
174*7c478bd9Sstevel@tonic-gate 		if (fgets(pbuf,256,stdin) == NULL) {
175*7c478bd9Sstevel@tonic-gate 			newvalue = NULL;
176*7c478bd9Sstevel@tonic-gate 		} else {
177*7c478bd9Sstevel@tonic-gate 			char *tmp;
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 			tmp = strchr(pbuf,'\n');
180*7c478bd9Sstevel@tonic-gate 			if (tmp) *tmp = '\0';
181*7c478bd9Sstevel@tonic-gate 			tmp = strchr(pbuf,'\r');
182*7c478bd9Sstevel@tonic-gate 			if (tmp) *tmp = '\0';
183*7c478bd9Sstevel@tonic-gate 			newvalue = strdup(pbuf);
184*7c478bd9Sstevel@tonic-gate 		}
185*7c478bd9Sstevel@tonic-gate 		if ( newvalue == NULL) {
186*7c478bd9Sstevel@tonic-gate #else
187*7c478bd9Sstevel@tonic-gate #if defined(SOLARIS)
188*7c478bd9Sstevel@tonic-gate 		if ((newvalue = (char *)getpassphrase(str)) == NULL) {
189*7c478bd9Sstevel@tonic-gate #else
190*7c478bd9Sstevel@tonic-gate 		if ((newvalue = (char *)getpass(str)) == NULL) {
191*7c478bd9Sstevel@tonic-gate #endif
192*7c478bd9Sstevel@tonic-gate #endif
193*7c478bd9Sstevel@tonic-gate 			return (LDAP_UNAVAILABLE);
194*7c478bd9Sstevel@tonic-gate 		}
195*7c478bd9Sstevel@tonic-gate 		len = strlen(newvalue);
196*7c478bd9Sstevel@tonic-gate 	} else {
197*7c478bd9Sstevel@tonic-gate 		fputs(str, stderr);
198*7c478bd9Sstevel@tonic-gate 		if ((newvalue = fgets(str, sizeof(str), stdin)) == NULL)
199*7c478bd9Sstevel@tonic-gate 			return (LDAP_UNAVAILABLE);
200*7c478bd9Sstevel@tonic-gate 		len = strlen(str);
201*7c478bd9Sstevel@tonic-gate 		if (len > 0 && str[len - 1] == '\n')
202*7c478bd9Sstevel@tonic-gate 			str[len - 1] = 0;
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 	interact->result = (char *) strdup(newvalue);
206*7c478bd9Sstevel@tonic-gate 	memset(newvalue, '\0', len);
207*7c478bd9Sstevel@tonic-gate 	if (interact->result == NULL)
208*7c478bd9Sstevel@tonic-gate 		return (LDAP_NO_MEMORY);
209*7c478bd9Sstevel@tonic-gate 	interact->len = len;
210*7c478bd9Sstevel@tonic-gate 	return (LDAP_SUCCESS);
211*7c478bd9Sstevel@tonic-gate }
212*7c478bd9Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
213