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 * 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 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 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 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