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