xref: /onnv-gate/usr/src/cmd/ldap/common/ldaptool-sasl.c (revision 8097:4d57974af082)
10Sstevel@tonic-gate /*
2*8097SSreedhar.Chalamalasetti@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * File for ldaptool routines for SASL
80Sstevel@tonic-gate  */
90Sstevel@tonic-gate 
100Sstevel@tonic-gate #include <ldap.h>
110Sstevel@tonic-gate #include "ldaptool-sasl.h"
120Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
130Sstevel@tonic-gate #include <sasl/sasl.h>
140Sstevel@tonic-gate #include <locale.h>
150Sstevel@tonic-gate #include "ldaptool.h"
160Sstevel@tonic-gate #else
170Sstevel@tonic-gate #include <sasl.h>
180Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
190Sstevel@tonic-gate #include <stdio.h>
200Sstevel@tonic-gate 
210Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD
220Sstevel@tonic-gate #define gettext(s) s
230Sstevel@tonic-gate #endif
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #ifdef HAVE_SASL_OPTIONS
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #define SASL_PROMPT	"SASL"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate typedef struct {
300Sstevel@tonic-gate         char *mech;
310Sstevel@tonic-gate         char *authid;
320Sstevel@tonic-gate         char *username;
330Sstevel@tonic-gate         char *passwd;
340Sstevel@tonic-gate         char *realm;
350Sstevel@tonic-gate } ldaptoolSASLdefaults;
360Sstevel@tonic-gate 
370Sstevel@tonic-gate static int get_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact);
380Sstevel@tonic-gate static int get_new_value(sasl_interact_t *interact, unsigned flags);
390Sstevel@tonic-gate 
400Sstevel@tonic-gate void *
ldaptool_set_sasl_defaults(LDAP * ld,char * mech,char * authid,char * username,char * passwd,char * realm)410Sstevel@tonic-gate ldaptool_set_sasl_defaults ( LDAP *ld, char *mech, char *authid, char *username,
420Sstevel@tonic-gate 				 char *passwd, char *realm )
430Sstevel@tonic-gate {
440Sstevel@tonic-gate         ldaptoolSASLdefaults *defaults;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate         if ((defaults = calloc(sizeof(defaults[0]), 1)) == NULL)
470Sstevel@tonic-gate 		return NULL;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 	if (mech)
500Sstevel@tonic-gate 		defaults->mech = mech;
510Sstevel@tonic-gate 	else
520Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	if (authid)
550Sstevel@tonic-gate 		defaults->authid = authid;
560Sstevel@tonic-gate 	else
570Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authid);
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	if (username)
600Sstevel@tonic-gate 		defaults->username = username;
610Sstevel@tonic-gate 	else
620Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->username);
630Sstevel@tonic-gate 
640Sstevel@tonic-gate         defaults->passwd = passwd;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 	if (realm)
670Sstevel@tonic-gate 		defaults->realm = realm;
680Sstevel@tonic-gate 	else
690Sstevel@tonic-gate 		ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
700Sstevel@tonic-gate 
710Sstevel@tonic-gate         return defaults;
720Sstevel@tonic-gate }
730Sstevel@tonic-gate 
740Sstevel@tonic-gate int
ldaptool_sasl_interact(LDAP * ld,unsigned flags,void * defaults,void * prompts)750Sstevel@tonic-gate ldaptool_sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *prompts ) {
760Sstevel@tonic-gate 	sasl_interact_t		*interact;
770Sstevel@tonic-gate 	ldaptoolSASLdefaults	*sasldefaults = defaults;
780Sstevel@tonic-gate 	int			rc;
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 	if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
810Sstevel@tonic-gate 		return (LDAP_PARAM_ERROR);
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 	for (interact = prompts; interact->id != SASL_CB_LIST_END; interact++) {
840Sstevel@tonic-gate 		/* Obtain the default value */
850Sstevel@tonic-gate 		if ((rc = get_default(sasldefaults, interact)) != LDAP_SUCCESS)
860Sstevel@tonic-gate 			return (rc);
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 		/* If no default, get the new value from stdin */
890Sstevel@tonic-gate 		if (interact->result == NULL) {
900Sstevel@tonic-gate 			if ((rc = get_new_value(interact, flags)) != LDAP_SUCCESS)
910Sstevel@tonic-gate 				return (rc);
920Sstevel@tonic-gate 		}
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	}
950Sstevel@tonic-gate 	return (LDAP_SUCCESS);
960Sstevel@tonic-gate }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate static int
get_default(ldaptoolSASLdefaults * defaults,sasl_interact_t * interact)990Sstevel@tonic-gate get_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact) {
1000Sstevel@tonic-gate 	const char	*defvalue = interact->defresult;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	if (defaults != NULL) {
1030Sstevel@tonic-gate 		switch( interact->id ) {
1040Sstevel@tonic-gate         	case SASL_CB_AUTHNAME:
1050Sstevel@tonic-gate 			defvalue = defaults->authid;
1060Sstevel@tonic-gate 			break;
1070Sstevel@tonic-gate         	case SASL_CB_USER:
1080Sstevel@tonic-gate 			defvalue = defaults->username;
1090Sstevel@tonic-gate 			break;
1100Sstevel@tonic-gate         	case SASL_CB_PASS:
1110Sstevel@tonic-gate 			defvalue = defaults->passwd;
1120Sstevel@tonic-gate 			break;
1130Sstevel@tonic-gate         	case SASL_CB_GETREALM:
1140Sstevel@tonic-gate 			defvalue = defaults->realm;
1150Sstevel@tonic-gate 			break;
1160Sstevel@tonic-gate 		}
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	if (defvalue != NULL) {
1200Sstevel@tonic-gate 		interact->result = (char *)malloc(strlen(defvalue)+1);
1210Sstevel@tonic-gate 		if ((char *)interact->result != NULL) {
1220Sstevel@tonic-gate 			strcpy((char *)interact->result,defvalue);
1230Sstevel@tonic-gate 			interact->len = strlen((char *)(interact->result));
1240Sstevel@tonic-gate 		}
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 		/* Clear passwd */
1270Sstevel@tonic-gate 		if (interact->id == SASL_CB_PASS && defaults != NULL) {
1280Sstevel@tonic-gate 			/* At this point defaults->passwd is not NULL */
1290Sstevel@tonic-gate             		memset( defaults->passwd, '\0', strlen(defaults->passwd));
1300Sstevel@tonic-gate 		}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 		if ((char *)interact->result == NULL) {
1330Sstevel@tonic-gate 			return (LDAP_NO_MEMORY);
1340Sstevel@tonic-gate 		}
1350Sstevel@tonic-gate 	}
1360Sstevel@tonic-gate 	return (LDAP_SUCCESS);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate static int
get_new_value(sasl_interact_t * interact,unsigned flags)1400Sstevel@tonic-gate get_new_value(sasl_interact_t *interact, unsigned flags) {
1410Sstevel@tonic-gate 	char	*newvalue, str[1024];
1420Sstevel@tonic-gate 	int	len;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1450Sstevel@tonic-gate 	char	*tmpstr;
1460Sstevel@tonic-gate #endif
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	if (interact->id == SASL_CB_ECHOPROMPT || interact->id == SASL_CB_NOECHOPROMPT) {
1490Sstevel@tonic-gate 		if (interact->challenge)
1500Sstevel@tonic-gate 			fprintf(stderr, gettext("Challenge:%s\n"), interact->challenge);
1510Sstevel@tonic-gate 	}
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD
1540Sstevel@tonic-gate 	tmpstr = ldaptool_UTF82local(interact->prompt);
1550Sstevel@tonic-gate 	snprintf(str, sizeof(str), "%s:", tmpstr?tmpstr:SASL_PROMPT);
1560Sstevel@tonic-gate 	if (tmpstr != NULL)
1570Sstevel@tonic-gate 		free(tmpstr);
1580Sstevel@tonic-gate #else
1590Sstevel@tonic-gate #ifdef HAVE_SNPRINTF
1600Sstevel@tonic-gate 	snprintf(str, sizeof(str), "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
1610Sstevel@tonic-gate #else
1620Sstevel@tonic-gate 	sprintf(str, "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
1630Sstevel@tonic-gate #endif
1640Sstevel@tonic-gate #endif	/* SOLARIS_LDAP_CMD */
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	/* Get the new value */
1670Sstevel@tonic-gate 	if (interact->id == SASL_CB_PASS || interact->id == SASL_CB_NOECHOPROMPT) {
1680Sstevel@tonic-gate #if defined(_WIN32)
1690Sstevel@tonic-gate 		char pbuf[257];
1700Sstevel@tonic-gate 		fputs(str,stdout);
1710Sstevel@tonic-gate 		fflush(stdout);
1720Sstevel@tonic-gate 		if (fgets(pbuf,256,stdin) == NULL) {
1730Sstevel@tonic-gate 			newvalue = NULL;
1740Sstevel@tonic-gate 		} else {
1750Sstevel@tonic-gate 			char *tmp;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 			tmp = strchr(pbuf,'\n');
1780Sstevel@tonic-gate 			if (tmp) *tmp = '\0';
1790Sstevel@tonic-gate 			tmp = strchr(pbuf,'\r');
1800Sstevel@tonic-gate 			if (tmp) *tmp = '\0';
1810Sstevel@tonic-gate 			newvalue = strdup(pbuf);
1820Sstevel@tonic-gate 		}
1830Sstevel@tonic-gate 		if ( newvalue == NULL) {
1840Sstevel@tonic-gate #else
1850Sstevel@tonic-gate #if defined(SOLARIS)
1860Sstevel@tonic-gate 		if ((newvalue = (char *)getpassphrase(str)) == NULL) {
1870Sstevel@tonic-gate #else
1880Sstevel@tonic-gate 		if ((newvalue = (char *)getpass(str)) == NULL) {
1890Sstevel@tonic-gate #endif
1900Sstevel@tonic-gate #endif
1910Sstevel@tonic-gate 			return (LDAP_UNAVAILABLE);
1920Sstevel@tonic-gate 		}
1930Sstevel@tonic-gate 		len = strlen(newvalue);
1940Sstevel@tonic-gate 	} else {
1950Sstevel@tonic-gate 		fputs(str, stderr);
1960Sstevel@tonic-gate 		if ((newvalue = fgets(str, sizeof(str), stdin)) == NULL)
1970Sstevel@tonic-gate 			return (LDAP_UNAVAILABLE);
1980Sstevel@tonic-gate 		len = strlen(str);
1990Sstevel@tonic-gate 		if (len > 0 && str[len - 1] == '\n')
2000Sstevel@tonic-gate 			str[len - 1] = 0;
2010Sstevel@tonic-gate 	}
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	interact->result = (char *) strdup(newvalue);
2040Sstevel@tonic-gate 	memset(newvalue, '\0', len);
2050Sstevel@tonic-gate 	if (interact->result == NULL)
2060Sstevel@tonic-gate 		return (LDAP_NO_MEMORY);
2070Sstevel@tonic-gate 	interact->len = len;
2080Sstevel@tonic-gate 	return (LDAP_SUCCESS);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate #endif	/* HAVE_SASL_OPTIONS */
211