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