|
|
1.1 root 1: /* referral.c - create referral notices */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/quipu/RCS/referral.c,v 7.1 89/12/19 16:20:45 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/quipu/RCS/referral.c,v 7.1 89/12/19 16:20:45 mrose Exp $
9: *
10: *
11: * $Log: referral.c,v $
12: * Revision 7.1 89/12/19 16:20:45 mrose
13: * sync
14: *
15: * Revision 7.0 89/11/23 22:18:01 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include "quipu/util.h"
32: #include "quipu/connection.h"
33:
34: extern LLog * log_dsap;
35: char remote_lookup = TRUE;
36: struct PSAPaddr * psap_cpy();
37: struct dn_seq * dn_seq_push();
38: struct dn_seq * dn_seq_pop();
39: struct di_block * di_alloc();
40:
41: extern int dn_print ();
42:
43: static struct access_point * top_ap = NULLACCESSPOINT;
44:
45: struct access_point * ap_cpy(ap)
46: struct access_point * ap;
47: {
48: struct access_point * ret_ap;
49: struct access_point **tmp_ap;
50:
51: if(ap == NULLACCESSPOINT)
52: return(NULLACCESSPOINT);
53:
54:
55: for(tmp_ap = &ret_ap; ap != NULLACCESSPOINT; ap=ap->ap_next)
56: {
57: (*tmp_ap) = (struct access_point *) calloc(1, sizeof(struct access_point));
58: (*tmp_ap)->ap_name = dn_cpy(ap->ap_name);
59: (*tmp_ap)->ap_address = psap_cpy(ap->ap_address);
60: tmp_ap = &((*tmp_ap)->ap_next);
61: }
62:
63: (*tmp_ap) = NULLACCESSPOINT;
64:
65: return(ret_ap);
66: }
67:
68:
69: static ContinuationRef new_ref (name,rt,ap)
70: DN name;
71: int rt;
72: struct access_point * ap;
73: {
74: ContinuationRef ptr;
75:
76: if (ap == NULLACCESSPOINT)
77: return (NULLCONTINUATIONREF);
78:
79: ptr = (ContinuationRef) smalloc (sizeof(continuation_ref));
80: ptr->cr_aliasedRDNs = CR_NOALIASEDRDNS;
81: ptr->cr_name = dn_cpy (name);
82: ptr->cr_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED;
83: ptr->cr_reftype = rt;
84: ptr->cr_accesspoints = ap_cpy(ap);
85:
86: return (ptr);
87: }
88:
89: struct access_point * ap_append (a,b)
90: struct access_point * a;
91: struct access_point * b;
92: {
93: struct access_point * trail;
94: struct access_point * top;
95:
96: if (a == NULLACCESSPOINT)
97: return (b);
98: if ( b == NULLACCESSPOINT)
99: return (a);
100:
101: for (top = a ; a != NULLACCESSPOINT; a = a->ap_next)
102: trail = a;
103:
104: trail->ap_next = b;
105: return (top);
106: }
107:
108: ContinuationRef cont_ref_parent (name)
109: DN name;
110: {
111: return (new_ref(name,RT_SUPERIOR,top_ap));
112: }
113:
114: add_str_parent (sdn,spsap)
115: char * sdn, *spsap;
116: {
117: DN dn,str2dn();
118: struct PSAPaddr *psap, * str2paddr();
119: struct access_point * next_ap;
120:
121: /* add string DN and string PSAP to list of parents */
122:
123: if ((psap = str2paddr (spsap)) == NULLPA) {
124: LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid parent address %s",spsap));
125: return;
126: }
127: if (( dn = str2dn (sdn)) == NULLDN ) {
128: LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid parent dn %s",sdn));
129: return;
130: }
131:
132: next_ap = (struct access_point *) smalloc (sizeof(struct access_point));
133: next_ap->ap_name = dn;
134: next_ap->ap_address = psap_cpy(psap);
135: next_ap->ap_next = NULLACCESSPOINT;
136: top_ap = ap_append (top_ap,next_ap);
137:
138: }
139:
140: struct PSAPaddr *parent_psap()
141: {
142: if (top_ap == NULLACCESSPOINT)
143: return (NULLPA);
144: return (top_ap->ap_address);
145: }
146:
147: /*
148: * Generate a list of dsa information blocks (di_block) from the master-dsa
149: * and slave-dsa attributes of the entry, the dsa dn for which an info block
150: * is generated is the name from the attribute.
151: * Currently all of the dsa DNs are used to generate info blocks in the
152: * list; since this requires access to the entry for each DSA dn this may
153: * result in some suspended operations being initiated.
154: * If some info blocks are generated then DS_CONTINUE is returned;
155: * If no completed or suspended info blocks can be generated then the calling
156: * process is returned an invalid reference error.
157: *
158: * NB - As with get_dsa_info, the blocks generated need to be further
159: * processed by the calling routine.
160: */
161: int dsa_info_new (name,dn_stack,master,entry_ptr,err,di_p)
162: DN name;
163: struct dn_seq * dn_stack;
164: int master;
165: Entry entry_ptr;
166: struct DSError * err;
167: struct di_block **di_p;
168: {
169: AV_Sequence avs;
170: int ret_val;
171: struct DSError err_tmp;
172: struct di_block **di_trail;
173: struct dn_seq * new_dn_stack;
174:
175: DLOG (log_dsap,LLOG_TRACE,("in dsa_info_new"));
176: ret_val = DS_ERROR_LOCAL;
177: di_trail = di_p;
178:
179: new_dn_stack = dn_seq_push(name,dn_stack);
180:
181: for (avs = entry_ptr->e_master; avs != NULLAV; avs=avs->avseq_next) {
182: if (avs->avseq_av.av_struct == NULL)
183: continue;
184:
185:
186: switch(get_dsa_info((DN)avs->avseq_av.av_struct, new_dn_stack,
187: &(err_tmp), di_trail))
188: {
189: case DS_OK:
190: /* di_trail is a completed dsa info block */
191: DLOG(log_dsap, LLOG_DEBUG, ("In dsa_info_new gdiOK:"));
192: #ifdef DEBUG
193: di_list_log(*di_trail);
194: #endif
195: (*di_trail)->di_target = dn_cpy(name);
196: di_trail = &((*di_trail)->di_next);
197: ret_val = DS_CONTINUE;
198: break;
199:
200: case DS_CONTINUE:
201: /* di_trail is a deferred dsa info block */
202: DLOG(log_dsap, LLOG_DEBUG, ("In dsa_info_new gdiCONT:"));
203: #ifdef DEBUG
204: di_list_log(*di_trail);
205: #endif
206: (*di_trail)->di_target = dn_cpy(name);
207: di_trail = &((*di_trail)->di_next);
208: ret_val = DS_CONTINUE;
209: break;
210:
211: case DS_X500_ERROR:
212: /* Error encountered generating di_block */
213: DLOG(log_dsap, LLOG_NOTICE, ("dsa_info_new - get_dsa_info (slave) returned X500 ERROR"));
214: if ((err_tmp.dse_type == DSE_SERVICEERROR )
215: && (err_tmp.ERR_SERVICE.DSE_sv_problem == DSE_SV_DITERROR)) {
216: *err = err_tmp;
217: return DS_X500_ERROR;
218: }
219: ds_error_free(&err_tmp);
220: break;
221:
222: default:
223: LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_info_new - get_dsa_info (master) unexpected return"));
224: break;
225: }
226:
227: }
228:
229: if(!master)
230: {
231: /* repeat for slaves */
232: for (avs = entry_ptr->e_slave; avs != NULLAV; avs=avs->avseq_next)
233: {
234:
235: if (avs->avseq_av.av_struct == NULL)
236: continue;
237:
238: switch(get_dsa_info((DN)avs->avseq_av.av_struct, new_dn_stack,
239: &(err_tmp), di_trail))
240: {
241: case DS_OK:
242: /* di_trail is a completed dsa info block */
243: DLOG(log_dsap, LLOG_DEBUG, ("In dsa_info_new (slave) gdiOK:"));
244: #ifdef DEBUG
245: di_list_log(*di_trail);
246: #endif
247: (*di_trail)->di_target = dn_cpy(name);
248: di_trail = &((*di_trail)->di_next);
249: ret_val = DS_CONTINUE;
250: break;
251:
252: case DS_CONTINUE:
253: /* di_trail is a deferred dsa info block */
254: DLOG(log_dsap, LLOG_DEBUG, ("In dsa_info_new (slave) gdiCONT:"));
255: #ifdef DEBUG
256: di_list_log(*di_trail);
257: #endif
258: (*di_trail)->di_target = dn_cpy(name);
259: di_trail = &((*di_trail)->di_next);
260: ret_val = DS_CONTINUE;
261: break;
262:
263: case DS_X500_ERROR:
264: /* Error encountered generating di_block */
265: DLOG(log_dsap, LLOG_NOTICE, ("dsa_info_new - get_dsa_info slave returned X500 ERROR"));
266: if ((err_tmp.dse_type == DSE_SERVICEERROR )
267: && (err_tmp.ERR_SERVICE.DSE_sv_problem == DSE_SV_DITERROR)) {
268: *err = err_tmp;
269: return DS_X500_ERROR;
270: }
271: ds_error_free(&err_tmp);
272: break;
273:
274: default:
275: LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_info_new - get_dsa_info slave unexpected return"));
276: break;
277: }
278:
279: }
280: }
281:
282: new_dn_stack = dn_seq_pop(new_dn_stack);
283:
284: if((ret_val == DS_ERROR_LOCAL) || (ret_val == DS_X500_ERROR))
285: {
286: err->dse_type = DSE_SERVICEERROR;
287: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
288: ret_val = DS_X500_ERROR;
289: pslog (log_dsap,LLOG_EXCEPTIONS,"Invalid reference in entry",dn_print,(caddr_t)name);
290: }
291:
292: return (ret_val);
293: }
294:
295: struct di_block * ap2di (ap,name,master,di_type,oper,cr_type)
296: struct access_point *ap;
297: DN name;
298: char master;
299: char di_type;
300: struct oper_act *oper;
301: int cr_type;
302: {
303: struct access_point *loop;
304: struct di_block *res = NULL_DI_BLOCK;
305: struct di_block *ptr;
306: struct di_block *trail;
307:
308: if(ap == NULLACCESSPOINT)
309: {
310: LLOG(log_dsap, LLOG_EXCEPTIONS, ("No acces point to make into a di"));
311: return NULL_DI_BLOCK;
312: }
313:
314: for (loop=ap; loop!=NULLACCESSPOINT; loop=loop->ap_next) {
315: ptr = di_alloc();
316: ptr->di_dn = dn_cpy(loop->ap_name);
317: ptr->di_target = dn_cpy(name);
318: ptr->di_reftype = cr_type;
319: ptr->di_state = DI_ACCESSPOINT;
320: ptr->di_type = di_type;
321: ptr->di_oper = oper;
322: ptr->di_accesspoints = (struct access_point *) calloc(1, sizeof(struct access_point));
323: ptr->di_accesspoints->ap_name = dn_cpy(loop->ap_name);
324: ptr->di_accesspoints->ap_address = psap_cpy(loop->ap_address);
325: if (res == NULL_DI_BLOCK)
326: trail = res = ptr;
327: else
328: trail = (trail->di_next = ptr);
329:
330: if (master)
331: break; /* Only want to use first AP */
332: }
333:
334: sort_dsa_list (&res);
335:
336: return res;
337: }
338:
339:
340: int dsa_info_parent (name,err,di_p,master)
341: DN name;
342: struct DSError * err;
343: struct di_block **di_p;
344: char master;
345: {
346: DLOG(log_dsap, LLOG_TRACE, ("dsa_info_parent"));
347:
348: if(top_ap == NULLACCESSPOINT)
349: {
350: LLOG(log_dsap, LLOG_EXCEPTIONS, ("No parents!"));
351: err->dse_type = DSE_SERVICEERROR;
352: err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE;
353: return(DS_X500_ERROR);
354: }
355:
356: *di_p = ap2di (top_ap,name,master,DI_TASK,NULLOPER,RT_SUPERIOR);
357:
358: return(DS_CONTINUE);
359: }
360:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.