|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T n
Length: 11742 (0x2dde) Types: TextFile Names: »nsa.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/quipu/nsa.c«
/* nsa.c - Name server access to the directory */ #ifndef lint static char *rcsid = "$Header: /f/osi/quipu/RCS/nsa.c,v 7.1 89/12/19 16:20:40 mrose Exp $"; #endif /* * $Header: /f/osi/quipu/RCS/nsa.c,v 7.1 89/12/19 16:20:40 mrose Exp $ * * * $Log: nsa.c,v $ * Revision 7.1 89/12/19 16:20:40 mrose * sync * * Revision 7.0 89/11/23 22:17:48 mrose * Release 6.0 * */ /* * 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. * */ /* * In next release, make this generic to CL-mode transport: * * UDP, CLTP, or CLTP over UDP * */ #include <signal.h> #include <stdio.h> #include <varargs.h> #include "psap.h" #include "rosap.h" #include "isoaddrs.h" #include "logger.h" #include "tailor.h" #include "quipu/util.h" #include "quipu/read.h" #include "quipu/dua.h" #include "quipu/connection.h" #include "quipu/entry.h" #include <sys/ioctl.h> #ifdef BSD42 #include <sys/file.h> #endif #ifdef SYS5 #include <fcntl.h> #endif #include "dgram.h" #ifdef TCP #include "internet.h" #endif #ifndef NO_STATS extern LLog *log_stat; #endif #define DSA_WAIT 30 /* \f DATA */ extern LLog *log_dsap; extern int dn_print(); DN str2dn (); void advise (), adios(); static resolve (); static send_ns_result (); static ns_tidy (); extern int dsap_ad; extern int nameserver_unused; int nfds, nameservice; fd_set ifds, rfds; /* \f */ #if defined(SOCKETS) && defined(TCP) ns_init () { register int i; register struct NSAPaddr *na; register struct PSAPaddr *pa; struct sockaddr_in in_socket; register struct sockaddr_in *isock = &in_socket; register struct hostent *hp; if ((pa = str2paddr (ns_address)) == NULL) adios (NULLCP, "unable to parse resolver address \"%s\"", ns_address); if ((i = pa -> pa_addr.sa_addr.ta_naddr) == 0) adios (NULLCP, "no network addresses present in \"%s\"", ns_address); for (na = pa -> pa_addr.sa_addr.ta_addrs; i-- > 0; na++) if (na -> na_type == NA_TCP) break; if (i < 0) adios (NULLCP, "no TCP-based network addresses present in \"%s\"", ns_address); if (na -> na_domain[0]) { if ((hp = gethostbystring (na -> na_domain)) == NULL) adios (NULLCP, "%s: unknown host", na -> na_domain); } else hp = NULL; if (na -> na_port == 0) adios (NULLCP, "UDP port not specified"); if (na -> na_tset && !(na -> na_tset & NA_TSET_UDP)) adios (NULLCP, "UDP service not specified in transport-set: 0x%x", na -> na_tset); bzero ((char *) isock, sizeof *isock); isock -> sin_family = hp ? hp -> h_addrtype : AF_INET; isock -> sin_port = na -> na_port; if (hp) inaddr_copy (hp, isock); if ((nameservice = start_udp_server (isock, 0, 0, 0)) == NOTOK) adios ("failed", "start_udp_server"); } /* \f */ ns_process (ud) int ud; { int fd; struct sockaddr_in out_socket; register struct sockaddr_in *osock = &out_socket; struct ns_query nss; register struct ns_query *ns = &nss; PE pe; PS ps; LLOG (log_dsap, LLOG_NOTICE, ("name server")); if ((fd = join_udp_client (ud, osock)) == NOTOK) { advise (LLOG_EXCEPTIONS, "failed", "join_udp_client"); return; } pe = NULLPE; bzero ((char *) ns, sizeof *ns); if ((ps = ps_alloc (dg_open)) == NULLPS || dg_setup (ps, fd, MAXDGRAM, read_udp_socket, write_udp_socket) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "%s failed", ps ? "dg_setup" : "ps_alloc"); goto out; } if ((pe = ps2pe (ps)) == NULLPE) { advise (LLOG_NOTICE, NULLCP, "unable to read query: %s", ps_error (ps -> ps_errno)); goto out; } if (parse_NS_Query (pe, 1, NULLIP, NULLVP, (char *) ns) == NOTOK) { advise (LLOG_NOTICE, NULLCP, "parse of Query failed: %s", PY_pepy); goto out; } PLOG (log_dsap, print_NS_Message, pe, "message", 1); nameserver_unused = FALSE; if (! (resolve (ps, ns -> ns_id, ns -> ns_name, ns -> ns_attribute, fd))) goto out2; out: ; (void) close_udp_socket (fd); nameserver_unused = TRUE; if (ps) ps_free (ps); out2: ; if (ns -> ns_name) free (ns -> ns_name); if (ns -> ns_attribute) free (ns -> ns_attribute); if (pe) pe_free (pe); } /* \f */ static resolve (ps, id, name, attribute, fd) register PS ps; int id; char *name, *attribute; int fd; { struct oper_act * oper_alloc(); struct oper_act * on; struct ds_read_arg * read_arg; struct di_block * di_ptr, *di_tmp; struct ds_read_result result; struct DSError error; int i; DN dn; AttributeType myattr; static struct common_args ca_def = default_common_args; on = oper_alloc(); on->on_type = ON_TYPE_NAMESERVICE; on->on_req.dca_dsarg.arg_type = OP_READ; on->on_req.dca_dsarg.arg_rd.rda_common = ca_def; /* struct copy */ on->on_req.dca_dsarg.arg_rd.rda_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH; read_arg = & on->on_req.dca_dsarg.arg_rd; if ((dn = str2dn (name)) == NULLDN) { advise (LLOG_EXCEPTIONS, NULLCP, "str2dn of \"%s\" failed", name); goto out1; } read_arg->rda_object = dn; if ((myattr = AttrT_new (attribute)) == NULLAttrT) { advise (LLOG_EXCEPTIONS, NULLCP, "attribute \"%s\" unknown", attribute); goto out1; } #ifndef NO_STATS pslog (log_stat,LLOG_NOTICE,"NS read",dn_print,(caddr_t)dn); #endif read_arg->rda_eis.eis_allattributes = FALSE; read_arg->rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; read_arg->rda_eis.eis_select = as_comp_new (myattr, NULLAV, NULLACL_INFO); switch (i = do_ds_read (read_arg, &error, &result, NULLDN, NULLDN, &di_ptr, FALSE,FALSE)) { case DS_OK: break; case DS_X500_ERROR: advise (LLOG_EXCEPTIONS, NULLCP, "ds_read for \"%s\" failed: X500 Error",name); log_ds_error (&error); ds_error_free (&error); goto out1; case DS_CONTINUE: on->on_nstask = (struct ns_task_act *) calloc (1,sizeof(struct ns_task_act)); on->on_nstask->ns_ts_ps = ps; on->on_nstask->ns_ts_id = id; on->on_nstask->ns_ts_fd = fd; on->on_nstask->ns_ts_attr = AttrT_cpy (myattr); read_arg->rda_eis.eis_allattributes = TRUE; /* so we can cache */ as_free (read_arg->rda_eis.eis_select); read_arg->rda_eis.eis_select = NULLATTR; on->on_arg = &(on->on_req); set_my_chain_args(&(on->on_req.dca_charg), dn); on->on_dsas = di_ptr; for(di_tmp=on->on_dsas; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) { di_tmp->di_type = DI_OPERATION; di_tmp->di_oper = on; } if(oper_chain(on) == OK) return FALSE; /* indicate we are waiting */ free ((char *) on->on_nstask); advise (LLOG_EXCEPTIONS, NULLCP, "ds_read for \"%s\" failed: oper_chain",name); goto out1; default: advise (LLOG_EXCEPTIONS, NULLCP, "ds_read for \"%s\" failed: %d",name,i); goto out1; } send_ns_result (ps,id,myattr,&result); entryinfo_comp_free (&result.rdr_entry, 1); out1: ; if (dn) dn_free (dn); if (read_arg->rda_eis.eis_select) as_free (read_arg->rda_eis.eis_select); free ((char *) on); return TRUE; } nameservice_result_wakeup(on) struct oper_act * on; { DLOG(log_dsap, LLOG_TRACE, ("nameservice_result_wakeup")); if (on->on_nstask == NULLNS_TASK) LLOG(log_dsap, LLOG_EXCEPTIONS, ("nameservice result_wakeup - connection initiating compare already failed")); else { dsp_cache (&on->on_req.dca_dsarg,&on->on_resp.resp_res.dcr_dsres,CN_CTX_X500_DAP,NULLDN); send_ns_result (on->on_nstask->ns_ts_ps,on->on_nstask->ns_ts_id,on->on_nstask->ns_ts_attr,&on->on_resp.resp_res.dcr_dsres.res_rd); } ns_tidy(on); } nameservice_error_wakeup(on) struct oper_act * on; { DLOG(log_dsap, LLOG_TRACE, ("nameservice_error_wakeup")); if (on->on_nstask == NULLNS_TASK) { LLOG(log_dsap, LLOG_EXCEPTIONS, ("nameservice error_wakeup - connection initiating compare already failed")); } else { switch(on->on_resp.resp_err.dse_type) { case DSE_NOERROR: LLOG(log_dsap, LLOG_EXCEPTIONS, ("nameservice error_wakeup() - no error!")); break; case DSE_REFERRAL: LLOG(log_dsap, LLOG_EXCEPTIONS, ("nameservice error_wakeup() - DAP referral received!")); case DSE_DSAREFERRAL: /* Follow referral */ if(oper_rechain(on) == OK) return; break; default: DLOG(log_dsap, LLOG_DEBUG, ("nameservice error_wakeup() - assuming all errors finish operation!")); break; } } ns_tidy(on); } nameservice_fail_wakeup(on) struct oper_act * on; { DLOG(log_dsap, LLOG_TRACE, ("nameservice_fail_wakeup")); if (on->on_nstask == NULLNS_TASK) LLOG(log_dsap, LLOG_EXCEPTIONS, ("nameservice_fail_wakeup task alread gone")); else { if(on->on_dsas) { if(oper_chain(on) == OK) return; } if(on->on_dsas) { /* oper_chain must be awaiting deferred di_blocks */ return; } } ns_tidy(on); } static send_ns_result (ps,id,at,result) PS ps; int id; AttributeType at; struct ds_read_result *result; { struct ns_response nss; register struct ns_response *ns = &nss; Attr_Sequence ap; PE pe, grab_pe(); char * attr2name_aux(); #ifdef DEBUG if (result->rdr_entry.ent_next != NULL) DLOG (log_dsap, LLOG_EXCEPTIONS, ("multiple entries returned in read")); #endif bzero ((char *) ns, sizeof *ns); ns -> ns_id = id; if (encode_IF_Name (&ns -> ns_name, 0, 0, NULLCP, result->rdr_entry.ent_dn) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "encoding of Distinguished Name failed; %s", PY_pepy); return; } if ((ap = as_find_type (result->rdr_entry.ent_attr, at)) == NULLATTR) { advise (LLOG_EXCEPTIONS, NULLCP, "no \"%s\" attribute in result", attr2name_aux(at->at_table)); if (ns -> ns_name) pe_free (ns -> ns_name); return; } ns->ns_value = grab_pe (&ap->attr_value->avseq_av); pe = NULLPE; if (build_NS_Response (&pe, 1, NULL, NULLCP, (char *) ns) == NOTOK) { advise (LLOG_EXCEPTIONS, NULLCP, "build of Response failed: %s", PY_pepy); if (ns -> ns_name) pe_free (ns -> ns_name); if (ns -> ns_value) pe_free (ns -> ns_value); return; } PLOG (log_dsap, print_NS_Message, pe, "message", 0); if (pe2ps (ps, pe) == NOTOK) advise (LLOG_EXCEPTIONS, NULLCP, "unable to write Response: %s", ps_error (ps -> ps_errno)); if (pe) pe_free (pe); if (ns -> ns_name) pe_free (ns -> ns_name); if (ns -> ns_value) pe_free (ns -> ns_value); return; } static ns_tidy (on) struct oper_act * on; { (void) close_udp_socket (on->on_nstask->ns_ts_fd); nameserver_unused = TRUE; dn_free (on->on_req.dca_dsarg.arg_rd.rda_object); on->on_req.dca_dsarg.arg_rd.rda_object = NULLDN; if (on->on_req.dca_dsarg.arg_rd.rda_eis.eis_select) { as_free (on->on_req.dca_dsarg.arg_rd.rda_eis.eis_select); on->on_req.dca_dsarg.arg_rd.rda_eis.eis_select = NULLATTR; } ps_free (on->on_nstask->ns_ts_ps); free ((char *)on->on_nstask); on->on_nstask = NULLNS_TASK; oper_conn_extract(on); oper_free(on); } #else ns_init () { adios (NULLCP, "nameservice enabled, but ISODE not configured for UDP"); } /* ARGSUSED */ ns_process (ud) int ud; { adios (NULLCP, "ns_process: ISODE not configured for UDP"); } /* ARGSUSED */ nameservice_result_wakeup(on) struct oper_act * on; { adios (NULLCP, "nameservice_result_wakeup: ISODE not configured for UDP"); } /* ARGSUSED */ nameservice_error_wakeup(on) struct oper_act * on; { adios (NULLCP, nameservice_error_wakeup": ISODE not configured for UDP"); } /* ARGSUSED */ nameservice_fail_wakeup(on) struct oper_act * on; { adios (NULLCP,nameservice_fail_wakeup ": ISODE not configured for UDP"); } #endif