|
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 c
Length: 15027 (0x3ab3) Types: TextFile Names: »conn_init.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/quipu/conn_init.c«
/* conn_init.c - deal with incoming association requests */ #ifndef lint static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_init.c,v 7.2 89/12/19 16:20:03 mrose Exp $"; #endif /* * $Header: /f/osi/quipu/RCS/conn_init.c,v 7.2 89/12/19 16:20:03 mrose Exp $ * * * $Log: conn_init.c,v $ * Revision 7.2 89/12/19 16:20:03 mrose * sync * * Revision 7.1 89/11/24 16:21:53 mrose * sync * * Revision 7.0 89/11/23 22:16:46 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. * */ #include "acsap.h" #include "rosap.h" #include "tsap.h" #include "quipu/util.h" #include "quipu/connection.h" extern LLog * log_dsap; #ifndef NO_STATS extern LLog * log_stat; #endif Conn conn_alloc(); void acs_log(); extern OID acse_pci; extern OID x500_da_ac; extern OID x500_ds_ac; extern OID quipu_ds_ac; extern struct PSAPctxlist * x500_da_pcdl; extern struct PSAPctxlist * x500_ds_pcdl; extern struct PSAPctxlist * quipu_ds_pcdl; extern time_t time (); char check_acs_ctx(acs_ctx) OID acs_ctx; { DLOG (log_dsap, LLOG_TRACE, ("check_acs_ctx")); if(oid_cmp(acs_ctx, x500_da_ac) == 0) return(CN_CTX_X500_DAP); if(oid_cmp(acs_ctx, x500_ds_ac) == 0) return(CN_CTX_X500_DSP); if(oid_cmp(acs_ctx, quipu_ds_ac) == 0) return(CN_CTX_QUIPU_DSP); return(CN_CTX_UNKNOWN); } /* ARGSUSED */ int judge_ctxlist(req_ctxlist, ok_ctxlist) struct PSAPctxlist * req_ctxlist; struct PSAPctxlist * ok_ctxlist; { int ctxlist_notok = 0; int i; int j; OID ok_asn; OID req_asn; DLOG (log_dsap, LLOG_TRACE, ("judge_ctxlist")); for(i=0; i<req_ctxlist->pc_nctx; i++) { DLOG (log_dsap, LLOG_DEBUG, ("Context (%d): id=%d, %s", i, req_ctxlist->pc_ctx[i].pc_id, oid2ode (req_ctxlist->pc_ctx[i].pc_asn))); if(req_ctxlist->pc_ctx[i].pc_result == PC_ACCEPT) req_ctxlist->pc_ctx[i].pc_result = PC_REJECTED; } for(j=0; j<ok_ctxlist->pc_nctx; j++) { ok_asn = ok_ctxlist->pc_ctx[j].pc_asn; for(i=0; i<req_ctxlist->pc_nctx; i++) { if((req_asn = req_ctxlist->pc_ctx[i].pc_asn) == NULLOID) { LLOG (log_dsap,LLOG_EXCEPTIONS,( "Reject: asn is NULLOID")); continue; } if((oid_cmp(req_asn, ok_asn) == 0)) break; } if(i < req_ctxlist->pc_nctx) { req_ctxlist->pc_ctx[i].pc_result = PC_ACCEPT; } else { LLOG (log_dsap, LLOG_EXCEPTIONS, ("Missing Context: %s", oid2ode (ok_asn))); ctxlist_notok = 1; } } #ifdef DEBUG for(i=0; i<req_ctxlist->pc_nctx; i++) { DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i, req_ctxlist->pc_ctx[i].pc_id, req_ctxlist->pc_ctx[i].pc_result)); if(req_ctxlist->pc_ctx[i].pc_result == PC_REJECTED) DLOG (log_dsap, LLOG_DEBUG, ("Context Rejected: id=%d, %s", req_ctxlist->pc_ctx[i].pc_id, oid2ode (req_ctxlist->pc_ctx[i].pc_asn))); } #endif return(ctxlist_notok); } int find_ctx_id(pcdl, ctx_oid) struct PSAPctxlist * pcdl; OID ctx_oid; { int i; DLOG (log_dsap, LLOG_TRACE, ("find_ctx_id")); for(i=0; i<pcdl->pc_nctx; i++) { if(oid_cmp(ctx_oid, pcdl->pc_ctx[i].pc_asn) == 0) break; } if(i < pcdl->pc_nctx) return(pcdl->pc_ctx[i].pc_id); LLOG(log_dsap, LLOG_EXCEPTIONS, ("Couldn't find context identifier %s", sprintoid(ctx_oid))); return(NOTOK); } conn_init(cn) Conn cn; { struct AcSAPstart * acs; struct AcSAPindication aci_s; struct AcSAPindication * aci = &aci_s; struct AcSAPabort * aca = &(aci->aci_abort); struct TSAPdisconnect td_s; struct TSAPdisconnect *td = &td_s; struct ds_bind_arg * bind_arg; char ** vec; DLOG (log_dsap,LLOG_TRACE,( "conn_init()")); acs = (struct AcSAPstart *) smalloc(sizeof(struct AcSAPstart)); vec = cn->cn_init_act.ia_vec; watch_dog ("AcInit"); if(AcInit(cn->cn_init_act.ia_vecp, vec, acs, aci) != OK) { watch_dog_reset(); LLOG (log_dsap,LLOG_EXCEPTIONS,( "net_wait_init_request() : AcInit() NOTOK")); acs_log(aca, "initialization fails"); ACAFREE(aca); conn_extract (cn); free((char *)acs); return; } watch_dog_reset(); DLOG (log_dsap,LLOG_TRACE,( "net_wait_init_request() : AcInit() OK")); /* * Log the arrival of a connection request. */ DLOG (log_dsap,LLOG_NOTICE, ("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d> <%s>", acs->acs_sd, oid2ode(acs->acs_context), sprintaei (&acs->acs_callingtitle), sprintaei (&acs->acs_calledtitle), acs->acs_ninfo, paddr2str (&(acs->acs_start.ps_calling), NULLNA))); if(SetROPS(acs->acs_sd) != OK) { DLOG (log_dsap,LLOG_NOTICE,( "Calling AcUAbort directly (no cn)")); #ifndef NO_STATS LLOG (log_stat,LLOG_EXCEPTIONS,("Failed association: %s",paddr2str(&(acs->acs_start.ps_calling),NULLNA))); #endif (void) AcUAbortRequest(acs->acs_sd, NULLPEP, 0, aci); ACSFREE(acs); conn_extract (cn); free((char *)acs); return; } cn->cn_ad = acs->acs_sd; cn->cn_initiator = INITIATED_BY_THAT; cn->cn_init_act.ia_acs = acs; LLOG (log_dsap,LLOG_NOTICE, ("Association (%d) from %s", cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA))); /* * Peel off the remote operations BIND tag. Continue * if it is not present even though this is in error. */ if (acs->acs_info[0] != NULLPE) { PE pe; pe = pe_cpy (acs->acs_info[0]); pe_free(acs->acs_info[0]); if (parse_Remote__Operations__Notation_BindArgumentValue (pe, 1, NULL, NULLCP, &acs->acs_info[0]) != OK) { LLOG (log_dsap, LLOG_EXCEPTIONS, ("parse_Remote__Operations__Notation_BindArgumentValue failed - continuing")); acs->acs_info[0] = pe_cpy(pe); } pe_free (pe); } else { LLOG (log_dsap, LLOG_EXCEPTIONS, ("No DirectoryBindArgument")); conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); return; } /* * Check application context. */ switch(cn->cn_ctx = check_acs_ctx(acs->acs_context)) { case CN_CTX_X500_DAP: #ifndef NO_STATS LLOG (log_stat,LLOG_NOTICE,("X500 DAP context association (%d): %s",cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA))); #endif if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), x500_da_pcdl) == 0) { cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_ACCESS_AS); } else { LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for X.500 DAP")); cn->cn_context_id = NOTOK; conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); return; } break; case CN_CTX_X500_DSP: #ifndef NO_STATS LLOG (log_stat,LLOG_NOTICE,("X500 DSP context association (%d): %s",cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA))); #endif if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), x500_ds_pcdl) == 0) { cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_SYSTEM_AS); } else { LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for X.500 DSP")); cn->cn_context_id = NOTOK; conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); return; } break; case CN_CTX_QUIPU_DSP: #ifndef NO_STATS LLOG (log_stat,LLOG_NOTICE,("QUIPU DSP context association (%d): %s",cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA))); #endif if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), quipu_ds_pcdl) == 0) { cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_QUIPU_AS); } else { LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for QUIPU DSP")); cn->cn_context_id = NOTOK; conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); return; } break; default: #ifndef NO_STATS LLOG (log_stat,LLOG_EXCEPTIONS,("UNKNOWN context association (%d): %s",cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA))); #endif cn->cn_context_id = NOTOK; conn_respond(cn, ACS_TRANSIENT, ACS_CONTEXT, NULLPEP, 0); return; } /* * The following takes advantage of the fact that all 3 contexts * have the same BIND ARGUMENT. */ if(cn->cn_context_id != NOTOK) { bind_arg = &(cn->cn_init_act.ia_req); if(decode_DAS_DirectoryBindArgument( acs->acs_info[0], 1, NULLCP, NULLIP, bind_arg) == OK) { DLOG(log_dsap,LLOG_DEBUG, ("Bind Argument decoded")); (void) dn_decode(bind_arg->dba_dn); cn->cn_who = dn_cpy(bind_arg->dba_dn); if(cn->cn_ctx != CN_CTX_X500_DAP) { cn->cn_what = dn_cpy(bind_arg->dba_dn); } } else { LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unable to parse DirectoryBindArgument")); conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); return; } } /* * If we haven't returned yet then the protocol for binding has been * satisfactorily completed. * Now attempt to perform the ds_bind for the argument decoded, which * can either succeed, fail or suspend waiting for a remote compare. * If a remote compare has been scheduled then return, otherwise * complete the connection initialisation by sending an AcAssocResponse. */ if (TSetQueuesOK (cn->cn_ad, 1, td) == NOTOK) td_log (td, "TSetQueuesOK (incoming)"); switch(ds_bind_init(cn)) { case DS_OK: conn_init_res(cn); break; case DS_ERROR_CONNECT: conn_init_err(cn); break; case DS_CONTINUE: cn->cn_state = CN_INDICATED; break; default: LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unexpected return by ds_bind_init")); conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0); break; } } conn_init_res(cn) struct connection * cn; { PE data; PE ro_data; PE * ro_datap = &(ro_data); int ndata; int status = ACS_ACCEPT; int reason = ACS_USER_NULL; DLOG(log_dsap,LLOG_TRACE, ("conn_init_res()")); *ro_datap = NULLPE; if(encode_DAS_DirectoryBindResult(&data, 1, NULLIP, NULLCP, &(cn->cn_init_act.ia_res)) == OK) { DLOG(log_dsap,LLOG_TRACE, ("Encoded DirectoryBindResult")); if (build_Remote__Operations__Notation_BindResultValue (ro_datap, 1, NULL, NULLCP, data) == OK) { DLOG(log_dsap,LLOG_TRACE, ("Built BindResultValue")); ndata = 1; } else { LLOG (log_dsap, LLOG_EXCEPTIONS, ("build_Remote__Operations__Notation_BindResultValue failed")); status = ACS_TRANSIENT; reason = ACS_USER_NOREASON; ndata = 0; } pe_free(data); } else { LLOG(log_dsap,LLOG_EXCEPTIONS, ("Failed to encode DirectoryBindResult")); status = ACS_TRANSIENT; reason = ACS_USER_NOREASON; ndata = 0; } if(ndata != 0) { (*ro_datap) -> pe_context = cn->cn_context_id; } conn_respond(cn, status, reason, ro_datap, ndata); if (ro_data != NULLPE) pe_free (ro_data); } conn_init_err(cn) struct connection * cn; { PE data; PE ro_data; PE *ro_datap = &(ro_data); int ndata; int status = ACS_ACCEPT; int reason = ACS_USER_NULL; DLOG(log_dsap,LLOG_TRACE, ("conn_init_err()")); *ro_datap = NULLPE; #ifndef NO_STATS LLOG (log_stat,LLOG_EXCEPTIONS,("Bind (%d) rejected",cn->cn_ad)); #endif LLOG (log_dsap,LLOG_NOTICE,("association %d rejected - authentication failed",cn->cn_ad)); if(encode_DAS_DirectoryBindError(&data, 1, NULLIP, NULLCP, &(cn->cn_init_act.ia_err)) == OK) { DLOG(log_dsap,LLOG_TRACE, ("Encoded DirectoryBindError")); if (build_Remote__Operations__Notation_BindErrorValue (ro_datap, 1, NULL, NULLCP, data) == OK) { DLOG(log_dsap,LLOG_TRACE, ("Built BindErrorValue")); status = ACS_PERMANENT; reason = ACS_USER_NOREASON; ndata = 1; } else { LLOG (log_dsap, LLOG_EXCEPTIONS, ("build_Remote__Operations__Notation_BindErrorValue failed")); status = ACS_TRANSIENT; reason = ACS_USER_NOREASON; ndata = 0; } pe_free(data); } else { LLOG(log_dsap,LLOG_EXCEPTIONS, ("Failed to encode DirectoryBindError")); status = ACS_TRANSIENT; reason = ACS_USER_NOREASON; ndata = 0; } if(ndata != 0) { (*ro_datap) -> pe_context = cn->cn_context_id; } conn_respond(cn, status, reason, ro_datap, ndata); if (ro_data != NULLPE) pe_free (ro_data); } conn_respond(cn, status, reason, data_p, ndata) struct connection * cn; int status; int reason; PE * data_p; int ndata; { struct AcSAPindication aci_s; struct AcSAPindication *aci = &aci_s; struct AcSAPabort *aca = &aci->aci_abort; struct AcSAPstart * acs = cn->cn_init_act.ia_acs; struct PSAPstart * ps = &(acs->acs_start); DLOG(log_dsap,LLOG_TRACE, ("conn_respond()")); DLOG(log_dsap,LLOG_NOTICE, ("A-ASSOCIATE.RESPONSE: %s%s%s", AcErrString (status), ((status == ACS_ACCEPT) ? "" : ", "), ((status == ACS_ACCEPT) ? "" : AcErrString (reason)))); #ifdef DEBUG { int i; for(i=0; i<ps->ps_ctxlist.pc_nctx; i++) { DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i, ps->ps_ctxlist.pc_ctx[i].pc_id, ps->ps_ctxlist.pc_ctx[i].pc_result)); } } #endif watch_dog ("AcAssocResponse"); if(AcAssocResponse(cn->cn_ad, status, reason, acs->acs_context, NULLAEI, mydsaaddr, &(ps->ps_ctxlist), ps->ps_defctxresult, PR_MYREQUIRE, ROS_MYREQUIRE, SERIAL_NONE, ps->ps_settings, &(ps->ps_connect), data_p, ndata, aci) == OK) { watch_dog_reset(); DLOG(log_dsap,LLOG_TRACE, ("AcAssocResponse OK")); if(status == ACS_ACCEPT) { cn->cn_state = CN_OPEN; } else { DLOG(log_dsap,LLOG_TRACE, ("status != ACS_ACCEPT")); DLOG(log_dsap, LLOG_DEBUG, ("conn_respond calling conn_extract 1")); conn_extract(cn); } } else { watch_dog_reset(); acs_log(aca, "A-ASSOCIATE.RESPONSE"); ACAFREE(aca); DLOG(log_dsap, LLOG_DEBUG, ("conn_respond calling conn_extract 2")); conn_extract(cn); } ACSFREE(acs); free ((char *) acs); } conn_pre_init(newfd, vecp, vec) int newfd; int vecp; char **vec; { Conn cn; cn = conn_alloc(); cn->cn_next = connlist; connlist = cn; conns_used++; cn->cn_ad = newfd; cn->cn_initiator = INITIATED_BY_THAT; cn->cn_init_act.ia_vecp = vecp; if (vec[0]) cn->cn_init_act.ia_vec[0] = strdup (vec[0]); if (vec[1]) cn->cn_init_act.ia_vec[1] = strdup (vec[1]); if (vec[2]) cn->cn_init_act.ia_vec[2] = strdup (vec[2]); if (vec[3]) cn->cn_init_act.ia_vec[3] = strdup (vec[3]); cn->cn_state = CN_OPENING; cn->cn_last_used = time ((time_t*)0); if (newfd == NOTOK) conn_init (cn); else DLOG (log_dsap,LLOG_NOTICE, ("opening association on %d",newfd )); }