Commit | Line | Data |
---|---|---|
04c6839a WJ |
1 | /* aetufn.c - UFN-based DSE */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/dsap/common/RCS/aetufn.c,v 7.4 91/02/22 09:18:09 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/dsap/common/RCS/aetufn.c,v 7.4 91/02/22 09:18:09 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: aetufn.c,v $ | |
12 | * Revision 7.4 91/02/22 09:18:09 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.3 90/12/11 10:53:50 mrose | |
16 | * lock-and-load | |
17 | * | |
18 | * Revision 7.2 90/10/17 11:40:51 mrose | |
19 | * sync | |
20 | * | |
21 | * Revision 7.1 90/07/09 14:33:49 mrose | |
22 | * sync | |
23 | * | |
24 | * Revision 7.0 90/07/06 23:18:10 mrose | |
25 | * *** empty log message *** | |
26 | * | |
27 | */ | |
28 | ||
29 | /* | |
30 | * NOTICE | |
31 | * | |
32 | * Acquisition, use, and distribution of this module and related | |
33 | * materials are subject to the restrictions of a license agreement. | |
34 | * Consult the Preface in the User's Manual for the full terms of | |
35 | * this agreement. | |
36 | * | |
37 | */ | |
38 | ||
39 | ||
40 | /* LINTLIBRARY */ | |
41 | ||
42 | #include "quipu/ufn.h" | |
43 | #include "quipu/util.h" | |
44 | #include "quipu/read.h" | |
45 | #include "quipu/dua.h" | |
46 | #include "quipu/bind.h" | |
47 | #include "tailor.h" | |
48 | ||
49 | extern LLog * addr_log; | |
50 | ||
51 | extern char * dn2str(); | |
52 | extern char * dn2ufn(); | |
53 | extern struct dn_seq *dn_seq_push (); | |
54 | ||
55 | ||
56 | /* ARGSUSED */ | |
57 | static DNS ufn_interact (dns,dn,s) | |
58 | DNS dns; | |
59 | DN dn; | |
60 | char * s; | |
61 | { | |
62 | char buf[LINESIZE]; | |
63 | DNS result = NULLDNS; | |
64 | DNS tmp; | |
65 | ||
66 | if (dns == NULLDNS) | |
67 | return NULLDNS; | |
68 | ||
69 | (void) printf ("Please select from the following (matching '%s'):\n",s); | |
70 | while (dns != NULLDNS) { | |
71 | (void) printf (" %s [y/n] ? ",dn2ufn(dns->dns_dn,FALSE)); | |
72 | (void) fflush (stdout); | |
73 | again:; | |
74 | if (gets (buf) == NULL) { | |
75 | clearerr (stdin); | |
76 | (void) printf ("\n"); | |
77 | return result; | |
78 | } | |
79 | ||
80 | if ((buf[0] == NULL) | |
81 | || (strlen(buf) != 1) | |
82 | || ((buf[0] != 'y') && (buf[0] != 'n'))) { | |
83 | (void) printf ("Please type 'y' or 'n': "); | |
84 | (void) fflush (stdout); | |
85 | goto again; | |
86 | } | |
87 | ||
88 | if (buf[0] == 'y') { | |
89 | tmp = dns -> dns_next; | |
90 | dns -> dns_next = result; | |
91 | result = dns; | |
92 | dns = tmp; | |
93 | } else { | |
94 | tmp = dns; | |
95 | dns = dns -> dns_next; | |
96 | tmp -> dns_next = NULL; | |
97 | dn_seq_free (tmp); | |
98 | } | |
99 | } | |
100 | return result; | |
101 | } | |
102 | ||
103 | /* ARGSUSED */ | |
104 | ||
105 | static DNS just_say_no (dns,dn,s) | |
106 | DNS dns; | |
107 | DN dn; | |
108 | char * s; | |
109 | { | |
110 | /* we only want good hits ! */ | |
111 | ||
112 | dn_seq_free (dns); | |
113 | SLOG (addr_log, LLOG_NOTICE, NULLCP, | |
114 | ("UFN asked for interactive response -- auto reply of NO")); | |
115 | return NULLDNS; | |
116 | } | |
117 | ||
118 | static DN username = NULLDN; | |
119 | static char password[DBA_MAX_PASSWD_LEN] = ""; | |
120 | ||
121 | static bind_to_dsa () | |
122 | { | |
123 | struct ds_bind_arg bindarg; | |
124 | struct ds_bind_arg bindresult; | |
125 | struct ds_bind_error binderr; | |
126 | ||
127 | bindarg.dba_version = DBA_VERSION_V1988; | |
128 | bindarg.dba_dn = username; | |
129 | if (bindarg.dba_passwd_len = strlen (password)) | |
130 | (void) strcpy (bindarg.dba_passwd, password); | |
131 | ||
132 | if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK) { | |
133 | PY_advise (NULLCP, "unable to bind to directory (%s)", | |
134 | binderr.dbe_type == DBE_TYPE_SECURITY ? "security error" | |
135 | : "DSA unavailable"); | |
136 | ||
137 | return FALSE; | |
138 | } | |
139 | ||
140 | return TRUE; | |
141 | } | |
142 | ||
143 | static char bound = FALSE; | |
144 | ||
145 | static PE name2psap (dn) | |
146 | DN dn; | |
147 | { | |
148 | AttributeType at; | |
149 | extern PE grab_pe(); | |
150 | PE res_pe; | |
151 | static struct ds_read_arg read_arg = | |
152 | { | |
153 | default_common_args, | |
154 | NULLDN, /* read_arg DN */ | |
155 | { /* entry info selection */ | |
156 | FALSE, | |
157 | NULLATTR, | |
158 | EIS_ATTRIBUTESANDVALUES | |
159 | } | |
160 | }; | |
161 | struct DSError error; | |
162 | struct ds_read_result result; | |
163 | ||
164 | ||
165 | if (! bound) { | |
166 | if (! bind_to_dsa()) | |
167 | goto out; | |
168 | ||
169 | bound = TRUE; | |
170 | } | |
171 | ||
172 | if ( (at = AttrT_new (DSAADDRESS_OID)) == NULLAttrT) { | |
173 | PY_advise (NULLCP, "build of attribute failed: %s", | |
174 | DSAADDRESS_OID); | |
175 | out: ; | |
176 | SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy)); | |
177 | return NULLPE; | |
178 | } | |
179 | ||
180 | read_arg.rda_common.ca_servicecontrol.svc_prio = SVC_PRIO_HIGH; | |
181 | read_arg.rda_object = dn; | |
182 | read_arg.rda_eis.eis_select = as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO); | |
183 | ||
184 | if (ds_read (&read_arg,&error,&result) != DS_OK) { | |
185 | PY_advise (NULLCP, "DAP lookup failed: %s",dn2str(dn)); | |
186 | log_ds_error (&error); | |
187 | ds_error_free (&error); | |
188 | AttrT_free (at); | |
189 | as_free (read_arg.rda_eis.eis_select); | |
190 | goto out; | |
191 | } else { | |
192 | if (result.rdr_entry.ent_attr == NULLATTR) { | |
193 | PY_advise (NULLCP, "No '%s' attribute in entry '%s'", | |
194 | DSAADDRESS_OID,dn2str(dn)); | |
195 | AttrT_free (at); | |
196 | as_free (read_arg.rda_eis.eis_select); | |
197 | goto out; | |
198 | } | |
199 | AttrT_free (at); | |
200 | as_free (read_arg.rda_eis.eis_select); | |
201 | res_pe = grab_pe(&result.rdr_entry.ent_attr->attr_value->avseq_av); | |
202 | as_free (result.rdr_entry.ent_attr); | |
203 | return (res_pe); | |
204 | } | |
205 | } | |
206 | ||
207 | static char unbind = FALSE; | |
208 | static envlist el = NULLEL; | |
209 | ||
210 | /* ARGSUSED */ | |
211 | ||
212 | static PE name2value_ufn (name, context, ontty, userdn, passwd, real_name) | |
213 | char *name, | |
214 | *context, | |
215 | *userdn, | |
216 | *passwd; | |
217 | int ontty; | |
218 | PE *real_name; | |
219 | { | |
220 | int n; | |
221 | char * v[20],buffer[LINESIZE]; | |
222 | DNS dns = NULLDNS; | |
223 | DN *dn; | |
224 | PE addr; | |
225 | ||
226 | *real_name = NULLPE; | |
227 | ||
228 | if (username) | |
229 | dn_free (username), username = NULLDN; | |
230 | if (userdn) { | |
231 | if ((username = str2dn (userdn)) == NULLDN) { | |
232 | PY_advise (NULLCP, "invalid DN for binding: \"%s\"", userdn); | |
233 | goto out; | |
234 | } | |
235 | } | |
236 | password[0] = NULL; | |
237 | if (passwd) | |
238 | (void) strcpy (password, passwd); | |
239 | ||
240 | (void) strcpy (buffer, name); | |
241 | if (*buffer == '@') { | |
242 | static DN dnstat; | |
243 | ||
244 | if ((dnstat = str2dn (buffer)) == NULLDN) { | |
245 | PY_advise (NULLCP, "invalid name"); | |
246 | goto out; | |
247 | } | |
248 | addr = name2psap (*(dn = &dnstat)); | |
249 | goto all_done; | |
250 | } | |
251 | ||
252 | if (el == NULLEL) | |
253 | set_el (); | |
254 | ||
255 | PY_pepy[0] = NULL; | |
256 | ||
257 | if ((n = sstr2arg (buffer,20,v,",")) == NOTOK) { | |
258 | PY_advise (NULLCP, "invalid name"); | |
259 | out: ; | |
260 | SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy)); | |
261 | return NULLPE; | |
262 | } | |
263 | ||
264 | if (! bound) { | |
265 | if (! bind_to_dsa()) | |
266 | goto out; | |
267 | ||
268 | bound = TRUE; | |
269 | } | |
270 | ||
271 | if ( ! aet_match (n, v, ontty ? ufn_interact : just_say_no, &dns, el, | |
272 | context)) { | |
273 | if (PY_pepy[0] == NULL) { | |
274 | PY_advise (NULLCP, "unable to resolve name"); | |
275 | goto out; | |
276 | } | |
277 | return NULLPE; | |
278 | } | |
279 | ||
280 | if (dns == NULLDNS) { | |
281 | PY_advise (NULLCP, "search failed to find anything"); | |
282 | goto out; | |
283 | } | |
284 | dn = NULL; | |
285 | ||
286 | addr = NULLPE; | |
287 | if (dns->dns_next == NULLDNS) { | |
288 | dn = &dns -> dns_dn; | |
289 | addr = name2psap (*dn); | |
290 | } | |
291 | else { | |
292 | /* Multiple hits */ | |
293 | /* Continue until one works */ | |
294 | if ( ontty ) | |
295 | (void) dnSelect (name,&dns,ufn_interact,el->Dns); | |
296 | ||
297 | for (; dns!= NULLDNS; dns=dns->dns_next) { | |
298 | dn = &dns -> dns_dn; | |
299 | if (addr = name2psap (*dn)) | |
300 | break; | |
301 | } | |
302 | } | |
303 | ||
304 | all_done: ; | |
305 | if (dn) { | |
306 | PS ps = NULLPS; | |
307 | ||
308 | (void) encode_IF_DistinguishedName (real_name, 1, 0, NULLCP, *dn); | |
309 | ||
310 | if (ontty | |
311 | && (ps = ps_alloc (str_open)) | |
312 | && str_setup (ps, NULLCP, 0, 0) != NOTOK) { | |
313 | (void) ufn_dn_print_aux (ps, *dn, NULLDN, 0); | |
314 | ps_print (ps, " "); | |
315 | *--ps -> ps_ptr = NULL, ps -> ps_cnt++; | |
316 | ||
317 | (void) printf ("[ using %s ]\n", ps -> ps_base); | |
318 | (void) fflush (stdout); | |
319 | ||
320 | ps -> ps_ptr = ps -> ps_base, ps -> ps_cnt = ps -> ps_bufsiz; | |
321 | } | |
322 | if (ps) | |
323 | ps_free (ps); | |
324 | ||
325 | dn_free (*dn); | |
326 | *dn = NULLDN; | |
327 | } | |
328 | dn_seq_free (dns); | |
329 | ||
330 | if (unbind) { | |
331 | bound = FALSE; | |
332 | ds_unbind (); | |
333 | } | |
334 | ||
335 | return addr; | |
336 | } | |
337 | ||
338 | ||
339 | static set_el () | |
340 | { | |
341 | register envlist en, | |
342 | *ep; | |
343 | DN local_dn, | |
344 | c_dn; | |
345 | static int inited = FALSE; | |
346 | extern char *local_dit; | |
347 | ||
348 | if (!inited) { | |
349 | quipu_syntaxes (); | |
350 | dsap_init ((int *)0,(char ***)0); | |
351 | inited = TRUE; | |
352 | } | |
353 | if (el = read_envlist ()) | |
354 | return; | |
355 | ||
356 | if (local_dn = str2dn (local_dit)) { | |
357 | DN dn = local_dn -> dn_parent; | |
358 | ||
359 | local_dn -> dn_parent = NULLDN; | |
360 | c_dn = dn_cpy (local_dn); | |
361 | local_dn -> dn_parent = dn; | |
362 | } | |
363 | ||
364 | ep = ⪙ | |
365 | ||
366 | if ((en = (envlist) calloc (1, sizeof **ep)) == NULL) { | |
367 | no_mem: ; | |
368 | SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("out of memory")); | |
369 | if (el) { | |
370 | for (; el; el = en) { | |
371 | en = el -> Next; | |
372 | ||
373 | dn_seq_free (el -> Dns); | |
374 | free ((char *) el); | |
375 | } | |
376 | ||
377 | el = NULLEL; | |
378 | } | |
379 | goto done; | |
380 | } | |
381 | *ep = en, ep = &en -> Next; | |
382 | en -> Dns = | |
383 | dn_seq_push (local_dn, | |
384 | dn_seq_push (c_dn, dn_seq_push (NULLDN, NULLDNSEQ))); | |
385 | en -> Upper = en -> Lower = 1; | |
386 | ||
387 | if ((en = (envlist) calloc (1, sizeof **ep)) == NULL) | |
388 | goto no_mem; | |
389 | *ep = en, ep = &en -> Next; | |
390 | en -> Dns = | |
391 | dn_seq_push (c_dn, | |
392 | dn_seq_push (local_dn, dn_seq_push (NULLDN, NULLDNSEQ))); | |
393 | en -> Upper = en -> Lower = 2; | |
394 | ||
395 | if ((en = (envlist) calloc (1, sizeof **ep)) == NULL) | |
396 | goto no_mem; | |
397 | *ep = en, ep = &en -> Next; | |
398 | en -> Dns = | |
399 | dn_seq_push (NULLDN, | |
400 | dn_seq_push (c_dn, dn_seq_push (local_dn, NULLDNSEQ))); | |
401 | en -> Upper = 32767, en -> Lower = 3; | |
402 | ||
403 | done: ; | |
404 | dn_free (local_dn); | |
405 | dn_free (c_dn); | |
406 | } | |
407 | ||
408 | ||
409 | set_lookup_ufn (flag) | |
410 | char flag; /* if TRUE always unbind */ | |
411 | { | |
412 | if ((unbind = flag) && bound) { | |
413 | bound = FALSE; | |
414 | ds_unbind (); | |
415 | } | |
416 | ||
417 | acsap_lookup = name2value_ufn; | |
418 | ||
419 | if (el == NULLEL) | |
420 | set_el (); | |
421 | } | |
422 | ||
423 | ||
424 | #ifdef STANDALONE_AET_TEST | |
425 | ||
426 | main (argc,argv) | |
427 | int argc; | |
428 | char ** argv; | |
429 | { | |
430 | char buffer [1024]; | |
431 | int ontty, n; | |
432 | PE title, paddr; | |
433 | ||
434 | buffer[0] = NULL; | |
435 | ||
436 | ontty = isatty (fileno (stdin)); | |
437 | for (n=1; n<argc; n++) { | |
438 | (void) strcat (buffer," "); | |
439 | (void) strcat (buffer, argv[n]); | |
440 | } | |
441 | ||
442 | isodetailor ("ufn_aet",1); | |
443 | ||
444 | quipu_syntaxes (); | |
445 | dsap_init ((int *)0,(char ***)0); | |
446 | ||
447 | addr_log -> ll_events |= LLOG_ALL, addr_log -> ll_stat |= LLOGTTY; | |
448 | ||
449 | if (pe = name2value_ufn (buffer, "iso ftam", ontty, &title)) { | |
450 | struct PSAPaddr pas; | |
451 | ||
452 | if (parse_DSE_PSAPaddr (pe, 1, NULLIP, NULLVP, (char *) &pas) | |
453 | == NOTOK) | |
454 | fprintf (stderr, "parse of presentation address failed: %s", | |
455 | PY_pepy); | |
456 | else | |
457 | (void) printf ("%s\n", paddr2str (&pas)); | |
458 | } | |
459 | else | |
460 | fprintf (stderr, "directory returns no value"); | |
461 | ||
462 | if (title) { | |
463 | (void) printf ("AETitle\n"); | |
464 | vunknown (title); | |
465 | } | |
466 | ||
467 | exit (0); | |
468 | } | |
469 | ||
470 | advise () | |
471 | { | |
472 | ; | |
473 | } | |
474 | ||
475 | #endif |