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