Net2/usr/src/contrib/isode/dsap/common/aetufn.c

Compare this file to the similar file:
Show the results in this format:

/* aetufn.c - UFN-based DSE */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/dsap/common/RCS/aetufn.c,v 7.4 91/02/22 09:18:09 mrose Interim $";
#endif

/* 
 * $Header: /f/osi/dsap/common/RCS/aetufn.c,v 7.4 91/02/22 09:18:09 mrose Interim $
 *
 *
 * $Log:	aetufn.c,v $
 * Revision 7.4  91/02/22  09:18:09  mrose
 * Interim 6.8
 * 
 * Revision 7.3  90/12/11  10:53:50  mrose
 * lock-and-load
 * 
 * Revision 7.2  90/10/17  11:40:51  mrose
 * sync
 * 
 * Revision 7.1  90/07/09  14:33:49  mrose
 * sync
 * 
 * Revision 7.0  90/07/06  23:18:10  mrose
 * *** empty log message ***
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include "quipu/ufn.h"
#include "quipu/util.h"
#include "quipu/read.h"
#include "quipu/dua.h"
#include "quipu/bind.h"
#include "tailor.h"

extern LLog * addr_log;

extern char * dn2str();
extern char * dn2ufn();
extern struct dn_seq *dn_seq_push ();


/* ARGSUSED */
static DNS ufn_interact (dns,dn,s)
DNS dns;
DN dn;
char * s;
{
char    buf[LINESIZE];
DNS result = NULLDNS;
DNS tmp;

	if (dns == NULLDNS)
		return NULLDNS;

	(void) printf ("Please select from the following (matching '%s'):\n",s);
	while (dns != NULLDNS) {
		(void) printf ("  %s [y/n] ? ",dn2ufn(dns->dns_dn,FALSE));
		(void) fflush (stdout);
again:;
		if (gets (buf) == NULL) {
			clearerr (stdin);
			(void) printf ("\n");
			return result;
		}

		if ((buf[0] == NULL) 
			|| (strlen(buf) != 1)
			|| ((buf[0] != 'y') && (buf[0] != 'n'))) {
				(void) printf ("Please type 'y' or 'n': ");
				(void) fflush (stdout);
				goto again;
			}

		if (buf[0] == 'y') {
		    tmp = dns -> dns_next;
		    dns -> dns_next = result;
		    result = dns;
		    dns = tmp;
		} else {
		    tmp = dns;
		    dns = dns -> dns_next;
		    tmp -> dns_next = NULL;
		    dn_seq_free (tmp);
		}
	}
	return result;
}

/* ARGSUSED */

static DNS just_say_no (dns,dn,s)
DNS dns;
DN dn;
char * s;
{
	/* we only want good hits ! */

	dn_seq_free (dns);
	SLOG (addr_log, LLOG_NOTICE, NULLCP,
	      ("UFN asked for interactive response -- auto reply of NO"));
	return NULLDNS;
}

static DN username = NULLDN;
static char password[DBA_MAX_PASSWD_LEN] = "";

static bind_to_dsa ()
{
  struct ds_bind_arg bindarg;
  struct ds_bind_arg bindresult;
  struct ds_bind_error binderr;

  bindarg.dba_version = DBA_VERSION_V1988;
  bindarg.dba_dn = username;
  if (bindarg.dba_passwd_len = strlen (password))
      (void) strcpy (bindarg.dba_passwd, password);

  if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK) {
	PY_advise (NULLCP, "unable to bind to directory (%s)",
		   binderr.dbe_type == DBE_TYPE_SECURITY ? "security error"
		   					 : "DSA unavailable");

    	return FALSE;
    }

    return TRUE;
}

static char bound = FALSE;

static PE name2psap (dn)
DN dn;
{
AttributeType at;
extern PE grab_pe();
PE res_pe;
static struct ds_read_arg read_arg = 
	{
		default_common_args,
		NULLDN,   /* read_arg DN */
		{       /* entry info selection */
			FALSE,
			NULLATTR,
			EIS_ATTRIBUTESANDVALUES
		}
	};
struct DSError  error;
struct ds_read_result result;


	if (! bound) {
	    if (! bind_to_dsa())
		goto out;

	    bound = TRUE;
	}

	if ( (at = AttrT_new (DSAADDRESS_OID)) == NULLAttrT) {
		PY_advise (NULLCP, "build of attribute failed: %s",
			   DSAADDRESS_OID);
out: ;
		SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
		return NULLPE;
	}

	read_arg.rda_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH;
	read_arg.rda_object = dn;
	read_arg.rda_eis.eis_select = as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO);

	if (ds_read (&read_arg,&error,&result) != DS_OK) {
		PY_advise (NULLCP, "DAP lookup failed: %s",dn2str(dn));
		log_ds_error (&error);
		ds_error_free (&error);
		AttrT_free (at);
		as_free (read_arg.rda_eis.eis_select);
		goto out;
	} else {
		if (result.rdr_entry.ent_attr == NULLATTR) {
			PY_advise (NULLCP, "No '%s' attribute in entry '%s'",
				   DSAADDRESS_OID,dn2str(dn));
			AttrT_free (at);
			as_free (read_arg.rda_eis.eis_select);
			goto out;
		}
		AttrT_free (at);
		as_free (read_arg.rda_eis.eis_select);
		res_pe = grab_pe(&result.rdr_entry.ent_attr->attr_value->avseq_av);
		as_free (result.rdr_entry.ent_attr);
		return (res_pe);
	}
}

static char unbind = FALSE;
static envlist el = NULLEL;

/* ARGSUSED */

static PE  name2value_ufn (name, context, ontty, userdn, passwd, real_name)
char   *name,
       *context,
       *userdn,
       *passwd;
int	ontty;
PE     *real_name;
{
int n;
char * v[20],buffer[LINESIZE];
DNS dns = NULLDNS;
DN *dn;
PE addr;

	*real_name = NULLPE;

	if (username)
	    dn_free (username), username = NULLDN;
	if (userdn) {
	    if ((username = str2dn (userdn)) == NULLDN) {
		PY_advise (NULLCP, "invalid DN for binding: \"%s\"", userdn);
		goto out;
	    }
	}
	password[0] = NULL;
	if (passwd)
	    (void) strcpy (password, passwd);

	(void) strcpy (buffer, name);
	if (*buffer == '@') {
	    static DN dnstat;

	    if ((dnstat = str2dn (buffer)) == NULLDN) {
		PY_advise (NULLCP, "invalid name");
		goto out;
	    }
	    addr = name2psap (*(dn = &dnstat));
	    goto all_done;
	}

	if (el == NULLEL)
	    set_el ();

	PY_pepy[0] = NULL;

	if ((n = sstr2arg (buffer,20,v,",")) == NOTOK) {
	    PY_advise (NULLCP, "invalid name");
out: ;
	    SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
	    return NULLPE;
	}

	if (! bound) {
	    if (! bind_to_dsa())
		goto out;

	    bound = TRUE;
	}

	if ( ! aet_match (n, v, ontty ? ufn_interact : just_say_no, &dns, el,
			  context)) {
	    if (PY_pepy[0] == NULL) {
		PY_advise (NULLCP, "unable to resolve name");
		goto out;
	    }
	    return NULLPE;
	}

	if (dns == NULLDNS) {
	    PY_advise (NULLCP, "search failed to find anything");
	    goto out;
	}
	dn = NULL;

	addr = NULLPE;
	if (dns->dns_next == NULLDNS) {
	        dn = &dns -> dns_dn;
		addr = name2psap (*dn);
	}
	else {
		/* Multiple hits */
		/* Continue until one works */
		if ( ontty ) 
			(void) dnSelect (name,&dns,ufn_interact,el->Dns);

		for (; dns!= NULLDNS; dns=dns->dns_next) {
		        dn = &dns -> dns_dn;
			if (addr = name2psap (*dn))
				break;
		}
	}

all_done: ;
	if (dn) {
	    PS	    ps = NULLPS;

	    (void) encode_IF_DistinguishedName (real_name, 1, 0, NULLCP, *dn);

	    if (ontty
		    && (ps = ps_alloc (str_open))
		    && str_setup (ps, NULLCP, 0, 0) != NOTOK) {
		(void) ufn_dn_print_aux (ps, *dn, NULLDN, 0);
		ps_print (ps, " ");
		*--ps -> ps_ptr = NULL, ps -> ps_cnt++;

		(void) printf ("[ using %s ]\n", ps -> ps_base);
		(void) fflush (stdout);

		ps -> ps_ptr = ps -> ps_base, ps -> ps_cnt = ps -> ps_bufsiz;
	    }
	    if (ps)
		ps_free (ps);

	    dn_free (*dn);
	    *dn = NULLDN;
	}
	dn_seq_free (dns);

	if (unbind) {
	    bound = FALSE;
	    ds_unbind ();
	}

	return addr;
}


static	set_el ()
{
    register envlist  en,
		     *ep;
    DN	    local_dn,
	    c_dn;
    static int  inited = FALSE;
    extern char *local_dit;

    if (!inited) {
	quipu_syntaxes ();
	dsap_init ((int *)0,(char ***)0);
	inited = TRUE;
    }
    if (el = read_envlist ())
	return;

    if (local_dn = str2dn (local_dit)) {
	DN	dn = local_dn -> dn_parent;

	local_dn -> dn_parent = NULLDN;
	c_dn = dn_cpy (local_dn);
	local_dn -> dn_parent = dn;
    }

    ep = ⪙

    if ((en = (envlist) calloc (1, sizeof **ep)) == NULL) {
no_mem: ;
	SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("out of memory"));
	if (el) {
	    for (; el; el = en) {
		en = el -> Next;

		dn_seq_free (el -> Dns);
		free ((char *) el);
	    }

	    el = NULLEL;
	}
	goto done;
    }
    *ep = en, ep = &en -> Next;
    en -> Dns =
	dn_seq_push (local_dn,
		     dn_seq_push (c_dn, dn_seq_push (NULLDN, NULLDNSEQ)));
    en -> Upper = en -> Lower = 1;

    if ((en = (envlist) calloc (1, sizeof **ep)) == NULL)
	goto no_mem;
    *ep = en, ep = &en -> Next;
    en -> Dns =
	dn_seq_push (c_dn,
		     dn_seq_push (local_dn, dn_seq_push (NULLDN, NULLDNSEQ)));
    en -> Upper = en -> Lower = 2;

    if ((en = (envlist) calloc (1, sizeof **ep)) == NULL)
	goto no_mem;
    *ep = en, ep = &en -> Next;
    en -> Dns =
	dn_seq_push (NULLDN,
		     dn_seq_push (c_dn, dn_seq_push (local_dn, NULLDNSEQ)));
    en -> Upper = 32767, en -> Lower = 3;

done: ;
    dn_free (local_dn);
    dn_free (c_dn);
}


set_lookup_ufn (flag)
char	flag;	/* if TRUE always unbind */
{
    if ((unbind = flag) && bound) {
	bound = FALSE;
	ds_unbind ();
    }

    acsap_lookup = name2value_ufn;

    if (el == NULLEL)
	set_el ();
}


#ifdef STANDALONE_AET_TEST

main (argc,argv)
int argc;
char ** argv;
{
char buffer [1024];
int ontty, n;
PE title, paddr;

	buffer[0] = NULL;

	ontty = isatty (fileno (stdin));
	for (n=1; n<argc; n++) {
		(void) strcat (buffer," ");
		(void) strcat (buffer, argv[n]);
	}

	isodetailor ("ufn_aet",1);

	quipu_syntaxes ();
	dsap_init ((int *)0,(char ***)0);

	addr_log -> ll_events |= LLOG_ALL, addr_log -> ll_stat |= LLOGTTY;

	if (pe = name2value_ufn (buffer, "iso ftam", ontty, &title)) {
	    struct PSAPaddr pas;

	    if (parse_DSE_PSAPaddr (pe, 1, NULLIP, NULLVP, (char *) &pas)
		    == NOTOK)
		fprintf (stderr, "parse of presentation address failed: %s",
			 PY_pepy);
	    else
		(void) printf ("%s\n", paddr2str (&pas));
	}
	else
	    fprintf (stderr, "directory returns no value");

	if (title) {
	    (void) printf ("AETitle\n");
	    vunknown (title);
	}

	exit (0);
}

advise ()
{
;
}

#endif