/* referral.c - create referral notices */
static char *rcsid
= "$Header: /f/osi/quipu/RCS/referral.c,v 7.3 91/02/22 09:39:46 mrose Interim $";
* $Header: /f/osi/quipu/RCS/referral.c,v 7.3 91/02/22 09:39:46 mrose Interim $
* Revision 7.3 91/02/22 09:39:46 mrose
* Revision 7.2 90/10/17 11:54:41 mrose
* Revision 7.1 89/12/19 16:20:45 mrose
* Revision 7.0 89/11/23 22:18:01 mrose
* 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
#include "quipu/connection.h"
char remote_lookup
= TRUE
;
struct PSAPaddr
* psap_cpy();
struct dn_seq
* dn_seq_push();
struct dn_seq
* dn_seq_pop();
struct di_block
* di_alloc();
static struct access_point
* top_ap
= NULLACCESSPOINT
;
struct access_point
* ap_cpy(ap
)
struct access_point
* ap
;
struct access_point
* ret_ap
;
struct access_point
**tmp_ap
;
if(ap
== NULLACCESSPOINT
)
for(tmp_ap
= &ret_ap
; ap
!= NULLACCESSPOINT
; ap
=ap
->ap_next
)
(*tmp_ap
) = (struct access_point
*) calloc(1, sizeof(struct access_point
));
(*tmp_ap
)->ap_name
= dn_cpy(ap
->ap_name
);
(*tmp_ap
)->ap_address
= psap_cpy(ap
->ap_address
);
tmp_ap
= &((*tmp_ap
)->ap_next
);
(*tmp_ap
) = NULLACCESSPOINT
;
static ContinuationRef
new_ref (name
,rt
,ap
)
struct access_point
* ap
;
if (ap
== NULLACCESSPOINT
)
return (NULLCONTINUATIONREF
);
ptr
= (ContinuationRef
) smalloc (sizeof(continuation_ref
));
ptr
->cr_aliasedRDNs
= CR_NOALIASEDRDNS
;
ptr
->cr_name
= dn_cpy (name
);
ptr
->cr_rdn_resolved
= CR_RDNRESOLVED_NOTDEFINED
;
ptr
->cr_accesspoints
= ap_cpy(ap
);
struct access_point
* ap_append (a
,b
)
struct access_point
* trail
;
struct access_point
* top
;
if (a
== NULLACCESSPOINT
)
if ( b
== NULLACCESSPOINT
)
for (top
= a
; a
!= NULLACCESSPOINT
; a
= a
->ap_next
)
ContinuationRef
cont_ref_parent (name
)
return (new_ref(name
,RT_SUPERIOR
,top_ap
));
add_str_parent (sdn
,spsap
)
struct PSAPaddr
*psap
, * str2paddr();
struct access_point
* next_ap
;
/* add string DN and string PSAP to list of parents */
if ((psap
= str2paddr (spsap
)) == NULLPA
) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Invalid parent address %s",spsap
));
if (( dn
= str2dn (sdn
)) == NULLDN
) {
LLOG (log_dsap
,LLOG_EXCEPTIONS
,("Invalid parent dn %s",sdn
));
next_ap
= (struct access_point
*) smalloc (sizeof(struct access_point
));
next_ap
->ap_address
= psap_cpy(psap
);
next_ap
->ap_next
= NULLACCESSPOINT
;
top_ap
= ap_append (top_ap
,next_ap
);
struct PSAPaddr
*parent_psap()
if (top_ap
== NULLACCESSPOINT
)
return (top_ap
->ap_address
);
* Generate a list of dsa information blocks (di_block) from the master-dsa
* and slave-dsa attributes of the entry, the dsa dn for which an info block
* is generated is the name from the attribute.
* Currently all of the dsa DNs are used to generate info blocks in the
* list; since this requires access to the entry for each DSA dn this may
* result in some suspended operations being initiated.
* If some info blocks are generated then DS_CONTINUE is returned;
* If no completed or suspended info blocks can be generated then the calling
* process is returned an invalid reference error.
* NB - As with get_dsa_info, the blocks generated need to be further
* processed by the calling routine.
int dsa_info_new (name
,dn_stack
,master
,entry_ptr
,err
,di_p
)
struct dn_seq
* dn_stack
;
struct di_block
**di_trail
;
struct dn_seq
* new_dn_stack
;
struct access_point
* aps
;
DLOG (log_dsap
,LLOG_TRACE
,("in dsa_info_new"));
ret_val
= DS_ERROR_LOCAL
;
new_dn_stack
= dn_seq_push(name
,dn_stack
);
if (entry_ptr
->e_external
) {
aps
= (struct access_point
*) entry_ptr
->e_reference
->avseq_av
.av_struct
;
(*di_p
)->di_type
= DI_TASK
;
(*di_p
)->di_dn
= dn_cpy(aps
->ap_name
);
(*di_p
)->di_target
= dn_cpy (name
);
(*di_p
)->di_state
= DI_ACCESSPOINT
;
(*di_p
)->di_rdn_resolved
= CR_RDNRESOLVED_NOTDEFINED
;
(*di_p
)->di_aliasedRDNs
= CR_NOALIASEDRDNS
;
if (((*di_p
)->di_reftype
= entry_ptr
->e_reftype
) == RT_NONSPECIFICSUBORDINATE
) {
for (avs
= entry_ptr
->e_reference
; avs
!= NULLAV
; avs
= avs
->avseq_next
) {
if (((struct access_point
*) avs
->avseq_av
.av_struct
)->ap_address
== NULLPA
) {
pslog (log_dsap
,LLOG_EXCEPTIONS
,"No address in NSSR",dn_print
,(caddr_t
)name
);
aps
= ap_cpy ((struct access_point
*) avs
->avseq_av
.av_struct
);
aps
->ap_next
= (*di_p
)->di_accesspoints
;
(*di_p
)->di_accesspoints
= aps
;
if ((*di_p
)->di_accesspoints
== NULLACCESSPOINT
) {
err
->dse_type
= DSE_SERVICEERROR
;
err
->ERR_SERVICE
.DSE_sv_problem
= DSE_SV_INVALIDREFERENCE
;
new_dn_stack
= dn_seq_pop(new_dn_stack
);
if (aps
->ap_address
!= NULLPA
) {
(*di_p
)->di_accesspoints
= ap_cpy (aps
);
switch(get_dsa_info(aps
->ap_name
, new_dn_stack
,
(*di_p
)->di_target
= dn_cpy(name
);
/* Error encountered generating di_block */
DLOG(log_dsap
, LLOG_NOTICE
, ("dsa_info_new - get_dsa_info (external) returned X500 ERROR"));
if ((err_tmp
.dse_type
== DSE_SERVICEERROR
)
&& (err_tmp
.ERR_SERVICE
.DSE_sv_problem
== DSE_SV_DITERROR
)) {
new_dn_stack
= dn_seq_pop(new_dn_stack
);
for (avs
= entry_ptr
->e_master
; avs
!= NULLAV
; avs
=avs
->avseq_next
) {
if (avs
->avseq_av
.av_struct
== NULL
)
switch(get_dsa_info((DN
)avs
->avseq_av
.av_struct
, new_dn_stack
,
(*di_trail
)->di_target
= dn_cpy(name
);
di_trail
= &((*di_trail
)->di_next
);
/* Error encountered generating di_block */
DLOG(log_dsap
, LLOG_NOTICE
, ("dsa_info_new - get_dsa_info (master) returned X500 ERROR"));
if ((err_tmp
.dse_type
== DSE_SERVICEERROR
)
&& (err_tmp
.ERR_SERVICE
.DSE_sv_problem
== DSE_SV_DITERROR
)) {
new_dn_stack
= dn_seq_pop(new_dn_stack
);
for (avs
= entry_ptr
->e_slave
; avs
!= NULLAV
; avs
=avs
->avseq_next
) {
if (avs
->avseq_av
.av_struct
== NULL
)
switch(get_dsa_info((DN
)avs
->avseq_av
.av_struct
, new_dn_stack
,
(*di_trail
)->di_target
= dn_cpy(name
);
di_trail
= &((*di_trail
)->di_next
);
/* Error encountered generating di_block */
DLOG(log_dsap
, LLOG_NOTICE
, ("dsa_info_new - get_dsa_info slave returned X500 ERROR"));
if ((err_tmp
.dse_type
== DSE_SERVICEERROR
)
&& (err_tmp
.ERR_SERVICE
.DSE_sv_problem
== DSE_SV_DITERROR
)) {
new_dn_stack
= dn_seq_pop(new_dn_stack
);
new_dn_stack
= dn_seq_pop(new_dn_stack
);
if((ret_val
== DS_ERROR_LOCAL
) || (ret_val
== DS_X500_ERROR
))
err
->dse_type
= DSE_SERVICEERROR
;
err
->ERR_SERVICE
.DSE_sv_problem
= DSE_SV_INVALIDREFERENCE
;
pslog (log_dsap
,LLOG_EXCEPTIONS
,"Invalid reference in entry",dn_print
,(caddr_t
)name
);
struct di_block
* ap2di (ap
,name
,master
,di_type
,oper
,cr_type
)
struct access_point
*loop
;
struct di_block
*res
= NULL_DI_BLOCK
;
if(ap
== NULLACCESSPOINT
)
LLOG(log_dsap
, LLOG_EXCEPTIONS
, ("No acces point to make into a di"));
for (loop
=ap
; loop
!=NULLACCESSPOINT
; loop
=loop
->ap_next
) {
ptr
->di_dn
= dn_cpy(loop
->ap_name
);
ptr
->di_target
= dn_cpy(name
);
ptr
->di_reftype
= cr_type
;
ptr
->di_state
= DI_ACCESSPOINT
;
ptr
->di_accesspoints
= (struct access_point
*) calloc(1, sizeof(struct access_point
));
ptr
->di_accesspoints
->ap_name
= dn_cpy(loop
->ap_name
);
ptr
->di_accesspoints
->ap_address
= psap_cpy(loop
->ap_address
);
if (res
== NULL_DI_BLOCK
)
trail
= (trail
->di_next
= ptr
);
break; /* Only want to use first AP */
int dsa_info_parent (name
,err
,di_p
,master
)
DLOG(log_dsap
, LLOG_TRACE
, ("dsa_info_parent"));
if(top_ap
== NULLACCESSPOINT
)
LLOG(log_dsap
, LLOG_EXCEPTIONS
, ("No parents!"));
err
->dse_type
= DSE_SERVICEERROR
;
err
->ERR_SERVICE
.DSE_sv_problem
= DSE_SV_INVALIDREFERENCE
;
*di_p
= ap2di (top_ap
,name
,master
,DI_TASK
,NULLOPER
,RT_SUPERIOR
);