1N/A/*
1N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
1N/A * Use is subject to license terms.
1N/A */
1N/A
1N/A/*
1N/A * File for ldaptool routines for SASL
1N/A */
1N/A
1N/A#include <ldap.h>
1N/A#include "ldaptool-sasl.h"
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A#include <sasl/sasl.h>
1N/A#include <locale.h>
1N/A#include "ldaptool.h"
1N/A#else
1N/A#include <sasl.h>
1N/A#endif /* SOLARIS_LDAP_CMD */
1N/A#include <stdio.h>
1N/A
1N/A#ifndef SOLARIS_LDAP_CMD
1N/A#define gettext(s) s
1N/A#endif
1N/A
1N/A#ifdef HAVE_SASL_OPTIONS
1N/A
1N/A#define SASL_PROMPT "SASL"
1N/A
1N/Atypedef struct {
1N/A char *mech;
1N/A char *authid;
1N/A char *username;
1N/A char *passwd;
1N/A char *realm;
1N/A} ldaptoolSASLdefaults;
1N/A
1N/Astatic int get_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact);
1N/Astatic int get_new_value(sasl_interact_t *interact, unsigned flags);
1N/A
1N/Avoid *
1N/Aldaptool_set_sasl_defaults ( LDAP *ld, char *mech, char *authid, char *username,
1N/A char *passwd, char *realm )
1N/A{
1N/A ldaptoolSASLdefaults *defaults;
1N/A
1N/A if ((defaults = calloc(sizeof(defaults[0]), 1)) == NULL)
1N/A return NULL;
1N/A
1N/A if (mech)
1N/A defaults->mech = mech;
1N/A else
1N/A ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &defaults->mech);
1N/A
1N/A if (authid)
1N/A defaults->authid = authid;
1N/A else
1N/A ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authid);
1N/A
1N/A if (username)
1N/A defaults->username = username;
1N/A else
1N/A ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->username);
1N/A
1N/A defaults->passwd = passwd;
1N/A
1N/A if (realm)
1N/A defaults->realm = realm;
1N/A else
1N/A ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &defaults->realm);
1N/A
1N/A return defaults;
1N/A}
1N/A
1N/Aint
1N/Aldaptool_sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *prompts ) {
1N/A sasl_interact_t *interact;
1N/A ldaptoolSASLdefaults *sasldefaults = defaults;
1N/A int rc;
1N/A
1N/A if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
1N/A return (LDAP_PARAM_ERROR);
1N/A
1N/A for (interact = prompts; interact->id != SASL_CB_LIST_END; interact++) {
1N/A /* Obtain the default value */
1N/A if ((rc = get_default(sasldefaults, interact)) != LDAP_SUCCESS)
1N/A return (rc);
1N/A
1N/A /* If no default, get the new value from stdin */
1N/A if (interact->result == NULL) {
1N/A if ((rc = get_new_value(interact, flags)) != LDAP_SUCCESS)
1N/A return (rc);
1N/A }
1N/A
1N/A }
1N/A return (LDAP_SUCCESS);
1N/A}
1N/A
1N/Astatic int
1N/Aget_default(ldaptoolSASLdefaults *defaults, sasl_interact_t *interact) {
1N/A const char *defvalue = interact->defresult;
1N/A
1N/A if (defaults != NULL) {
1N/A switch( interact->id ) {
1N/A case SASL_CB_AUTHNAME:
1N/A defvalue = defaults->authid;
1N/A break;
1N/A case SASL_CB_USER:
1N/A defvalue = defaults->username;
1N/A break;
1N/A case SASL_CB_PASS:
1N/A defvalue = defaults->passwd;
1N/A break;
1N/A case SASL_CB_GETREALM:
1N/A defvalue = defaults->realm;
1N/A break;
1N/A }
1N/A }
1N/A
1N/A if (defvalue != NULL) {
1N/A interact->result = (char *)malloc(strlen(defvalue)+1);
1N/A if ((char *)interact->result != NULL) {
1N/A strcpy((char *)interact->result,defvalue);
1N/A interact->len = strlen((char *)(interact->result));
1N/A }
1N/A
1N/A /* Clear passwd */
1N/A if (interact->id == SASL_CB_PASS && defaults != NULL) {
1N/A /* At this point defaults->passwd is not NULL */
1N/A memset( defaults->passwd, '\0', strlen(defaults->passwd));
1N/A }
1N/A
1N/A if ((char *)interact->result == NULL) {
1N/A return (LDAP_NO_MEMORY);
1N/A }
1N/A }
1N/A return (LDAP_SUCCESS);
1N/A}
1N/A
1N/Astatic int
1N/Aget_new_value(sasl_interact_t *interact, unsigned flags) {
1N/A char *newvalue, str[1024];
1N/A int len;
1N/A
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A char *tmpstr;
1N/A#endif
1N/A
1N/A if (interact->id == SASL_CB_ECHOPROMPT || interact->id == SASL_CB_NOECHOPROMPT) {
1N/A if (interact->challenge)
1N/A fprintf(stderr, gettext("Challenge:%s\n"), interact->challenge);
1N/A }
1N/A
1N/A#ifdef SOLARIS_LDAP_CMD
1N/A tmpstr = ldaptool_UTF82local(interact->prompt);
1N/A snprintf(str, sizeof(str), "%s:", tmpstr?tmpstr:SASL_PROMPT);
1N/A if (tmpstr != NULL)
1N/A free(tmpstr);
1N/A#else
1N/A#ifdef HAVE_SNPRINTF
1N/A snprintf(str, sizeof(str), "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
1N/A#else
1N/A sprintf(str, "%s:", interact->prompt?interact->prompt:SASL_PROMPT);
1N/A#endif
1N/A#endif /* SOLARIS_LDAP_CMD */
1N/A
1N/A /* Get the new value */
1N/A if (interact->id == SASL_CB_PASS || interact->id == SASL_CB_NOECHOPROMPT) {
1N/A#if defined(_WIN32)
1N/A char pbuf[257];
1N/A fputs(str,stdout);
1N/A fflush(stdout);
1N/A if (fgets(pbuf,256,stdin) == NULL) {
1N/A newvalue = NULL;
1N/A } else {
1N/A char *tmp;
1N/A
1N/A tmp = strchr(pbuf,'\n');
1N/A if (tmp) *tmp = '\0';
1N/A tmp = strchr(pbuf,'\r');
1N/A if (tmp) *tmp = '\0';
1N/A newvalue = strdup(pbuf);
1N/A }
1N/A if ( newvalue == NULL) {
1N/A#else
1N/A#if defined(SOLARIS)
1N/A if ((newvalue = (char *)getpassphrase(str)) == NULL) {
1N/A#else
1N/A if ((newvalue = (char *)getpass(str)) == NULL) {
1N/A#endif
1N/A#endif
1N/A return (LDAP_UNAVAILABLE);
1N/A }
1N/A len = strlen(newvalue);
1N/A } else {
1N/A fputs(str, stderr);
1N/A if ((newvalue = fgets(str, sizeof(str), stdin)) == NULL)
1N/A return (LDAP_UNAVAILABLE);
1N/A len = strlen(str);
1N/A if (len > 0 && str[len - 1] == '\n')
1N/A str[len - 1] = 0;
1N/A }
1N/A
1N/A interact->result = (char *) strdup(newvalue);
1N/A memset(newvalue, '\0', len);
1N/A if (interact->result == NULL)
1N/A return (LDAP_NO_MEMORY);
1N/A interact->len = len;
1N/A return (LDAP_SUCCESS);
1N/A}
1N/A#endif /* HAVE_SASL_OPTIONS */