|
|
1.1 root 1: /* ftamsystem.c - FTAM responder routines */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftamsystem.c,v 7.2 90/07/01 21:03:35 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/ftam2/RCS/ftamsystem.c,v 7.2 90/07/01 21:03:35 mrose Exp $
9: *
10: *
11: * $Log: ftamsystem.c,v $
12: * Revision 7.2 90/07/01 21:03:35 mrose
13: * pepsy
14: *
15: * Revision 7.1 90/01/16 22:37:20 mrose
16: * very last time
17: *
18: * Revision 7.0 89/11/23 21:54:40 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: #if defined(DEBUG) && !defined(NULL_INITIATOR)
35: #define NULL_INITIATOR
36: #endif
37:
38: #include <ctype.h>
39: #include <stdio.h>
40: #include <grp.h>
41: #include <pwd.h>
42: #include "ftamsystem.h"
43: #ifdef NULL_INITIATOR
44: #include "tailor.h"
45: #else
46: #include "logger.h"
47: #endif
48: #include <utmp.h>
49:
50:
51: #ifdef SYS5
52: struct group *getgrnam ();
53: struct passwd *getpwnam ();
54: #endif
55:
56: #ifndef ANON
57: #define ANON "ftp"
58: #endif
59:
60: /* UNIX DATA */
61:
62: int myuid;
63:
64: int myhomelen;
65: char myhome[MAXPATHLEN];
66:
67: dev_t null_dev;
68: ino_t null_ino;
69:
70:
71: static int wtmp = NOTOK;
72:
73: static long clok;
74:
75:
76: struct utmp uts;
77:
78:
79: long lseek (), time ();
80: char *crypt ();
81:
82: /* VFS DATA */
83:
84: struct vfsmap vfs[] = {
85: /* VFS_UBF */
86: "FTAM-3", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, binarypeek, 'b', VFS_XXX,
87: FA_ACC_UA,
88: -1, binarycheck,
89: _ZFTAM_3_ParametersDOCS,
90: "unstructured binary file",
91:
92: /* VFS_UTF */
93: "FTAM-1", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, textpeek, 't', VFS_UBF,
94: FA_ACC_UA,
95: -1, textcheck,
96: _ZFTAM_1_ParametersDOCS,
97: "unstructured text file",
98:
99: /* VFS_FDF */
100: "NBS-9", NULLOID, NULLCP, VF_NULL, 0, S_IFDIR, fdfpeek, 'd', VFS_XXX,
101: FA_ACC_UA,
102: 1, NULLIFP,
103: _ZNBS_9_ParametersDOCS,
104: "file directory file",
105:
106: NULL
107: };
108: #ifdef BRIDGE
109: int vfs_fdf = VFS_FDF;
110: #endif
111:
112: /* REGIME DATA */
113:
114: int fqos;
115: int class;
116: int units = FUNIT_READ | FUNIT_WRITE | FUNIT_LIMITED | FUNIT_ENHANCED
117: | FUNIT_GROUPING;
118: int attrs = FATTR_STORAGE;
119:
120: int fadusize = 0;
121:
122: /* ACTIVITY DATA */
123:
124: int myfd = NOTOK; /* handle to file */
125: char *myfile;
126: struct stat myst;
127: int statok;
128:
129: struct vfsmap *myvf; /* active contents type */
130: caddr_t myparam; /* .. */
131:
132: int myaccess; /* current access request */
133:
134: char *initiator; /* current initiator identity */
135: #ifdef NULL_INITIATOR
136: static int null_initiator = 0; /* none given, do EurOSInet style */
137: #endif
138:
139: struct FADUidentity mylocation;/* current location */
140:
141: int mymode; /* current processing mode */
142: int myoperation; /* .. */
143:
144: #ifdef notdef
145: AEI mycalling; /* current calling AET */
146: AEI myresponding; /* current responding AET */
147: #endif
148:
149: char *account; /* current account */
150: int mygid; /* "inner" account */
151:
152: int mylock; /* current concurrency control */
153: struct FTAMconcurrency myconctl;/* .. */
154:
155: int mylockstyle; /* current locking style */
156:
157:
158: int mycontext; /* current access context */
159: int mylevel; /* .. */
160:
161: #ifdef BRIDGE
162: static char *RemoteHost;
163: static char *password;
164:
165: int ftp_default = VFS_UBF;
166: #endif
167:
168: /* REGIME */
169:
170: #ifdef BRIDGE
171: #define seterr(id,ob,so,des) \
172: { \
173: dp -> ftd_identifier = (id); \
174: dp -> ftd_observer = (ob), dp -> ftd_source = (so); \
175: (void) strncpy (dp -> ftd_data, des, FTD_SIZE);\
176: dp -> ftd_cc = strlen(dp -> ftd_data);\
177: goto bad2; \
178: }
179: #else
180: #define seterr(id,ob,so,des) \
181: { \
182: dp -> ftd_identifier = (id); \
183: dp -> ftd_observer = (ob), dp -> ftd_source = (so); \
184: goto bad2; \
185: }
186: #endif
187:
188:
189: int ftam_start (fts)
190: register struct FTAMstart *fts;
191: {
192: register int i;
193: #ifndef BRIDGE
194: int guest;
195: struct passwd *pw;
196: #endif
197: struct stat st;
198: register struct isodocument *id;
199: register struct vfsmap *vf;
200: register struct FTAMcontent *fx;
201: struct FTAMdiagnostic diags[NFDIAG];
202: register struct FTAMdiagnostic *dp = diags;
203: struct FTAMindication ftis;
204: struct FTAMindication *fti = &ftis;
205:
206: (void) time (&clok);
207:
208: if (stat ("/dev/null", &st) != NOTOK)
209: null_dev = st.st_dev, null_ino = st.st_ino;
210: else
211: null_dev = (dev_t) 0, null_ino = (ino_t) 0;
212:
213: for (vf = vfs; vf -> vf_entry; vf++)
214: if (id = getisodocumentbyentry (vf -> vf_entry)) {
215: if ((vf -> vf_oid = oid_cpy (id -> id_type)) == NULLOID)
216: adios (NULLCP, "%s: out of memory", vf -> vf_entry);
217: }
218: else
219: if (vf -> vf_flags & VF_WARN)
220: advise (LLOG_NOTICE, NULLCP, "%s: unknown", vf -> vf_entry);
221:
222: ftamfd = fts -> fts_sd;
223: if ((class = fts -> fts_class) & FCLASS_TM)
224: class = FCLASS_TM;
225: else
226: if (class & FCLASS_TRANSFER)
227: class = FCLASS_TRANSFER;
228: else
229: if (class & FCLASS_MANAGE)
230: class = FCLASS_MANAGE;
231: else
232: seterr (FS_ACS_CLASS, EREF_RFSU, EREF_IFSU, "");
233: units &= fts -> fts_units;
234: attrs &= fts -> fts_attrs;
235: if ((fqos = fts -> fts_fqos) != FQOS_NORECOVERY)
236: seterr (FS_ACS_ROLLBACK, EREF_RFPM, EREF_IFSU, "");
237: if ((fadusize = fts -> fts_ssdusize) < 0)
238: fadusize = 0;
239:
240: for (fx = fts -> fts_contents.fc_contents,
241: i = fts -> fts_contents.fc_ncontent - 1;
242: i >= 0;
243: fx++, i--) {
244: if (fx -> fc_result != PC_ACCEPT)
245: continue;
246:
247: for (vf = vfs; vf -> vf_entry; vf++)
248: if (vf -> vf_oid
249: && oid_cmp (vf -> vf_oid, fx -> fc_dtn) == 0) {
250: vf -> vf_flags |= VF_OK;
251: vf -> vf_id = fx -> fc_id;
252: break;
253: }
254: if (!vf -> vf_entry) {
255: advise (LLOG_NOTICE, NULLCP, "%s: unknown document-type",
256: oid2ode (fx -> fc_dtn));
257: fx -> fc_result = PC_REJECTED;
258: }
259: }
260:
261: if ((initiator = fts -> fts_initiator) == NULL) {
262: #ifdef NULL_INITIATOR
263: initiator = ANON;
264: null_initiator = 1;
265: #else
266: seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU, "");
267: #endif
268: }
269: fts -> fts_initiator = NULL;
270:
271: #ifdef BRIDGE
272: /* scan initiator for remote host */
273: if ((RemoteHost = rindex(initiator, '@')) == NULL) {
274: advise (LLOG_EXCEPTIONS, NULLCP, "missing remote host name in \"%s\"",
275: initiator);
276: seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU,
277: "missing remote hostname");
278: }
279: *RemoteHost++ = '\0';
280: if (strcmp (initiator, "ANON") == 0 || strcmp (initiator, ANON) == 0) {
281: initiator = "ANONYMOUS"; /* FTP guest name */
282: }
283: password = (fts -> fts_password == NULL) ? "guest" : fts -> fts_password;
284: account = fts -> fts_account;
285: advise (LLOG_NOTICE, NULLCP,
286: "attemping connection with TCP host \"%s\" for user \"%s\"",
287: RemoteHost, initiator);
288: if (ftp_login(RemoteHost, initiator, password, account) == NOTOK)
289: seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU, ftp_error);
290: (void) strcpy (myhome, "");
291: myhomelen = strlen (myhome);
292: #else
293: guest = 0;
294: #ifdef NULL_INITIATOR
295: if (!baduser (NULLCP, initiator) && baduser ("ftamguests", initiator)) {
296: initiator = ANON;
297: null_initiator = 1;
298: }
299: #endif
300: if (strcmp (initiator, "ANON") == 0 || strcmp (initiator, ANON) == 0) {
301: if ((pw = getpwnam (ANON)) && pw -> pw_uid == 0)
302: pw = NULL;
303: guest = 1;
304: }
305: else
306: pw = baduser ("ftamusers", initiator) ? NULL : getpwnam (initiator);
307: if (pw == NULL)
308: seterr (FS_ACS_USER, EREF_RFSU, EREF_IFSU, "");
309: if ((!guest && fts -> fts_password == NULL)
310: || *pw -> pw_passwd == NULL
311: || (!guest && strcmp (crypt (fts -> fts_password, pw -> pw_passwd),
312: pw -> pw_passwd)))
313: seterr (FS_ACS_PASSWORD, EREF_RFSU, EREF_IFSU, "");
314:
315: if (account = fts -> fts_account) {
316: register struct group *gr = getgrnam (account);
317: register char **gp;
318:
319: if (gr == NULL) {
320: bad_account: ;
321: seterr (FS_ACS_ACCT, EREF_RFPM, EREF_IFSU, "");
322: }
323: if (gr -> gr_gid != pw -> pw_gid) {
324: for (gp = gr -> gr_mem; *gp; gp++)
325: if (strcmp (*gp, initiator) == 0)
326: break;
327: if (!*gp)
328: goto bad_account;
329: }
330:
331: fts -> fts_account = NULL;
332: }
333:
334: if (chdir (pw -> pw_dir) == NOTOK) {
335: dp -> ftd_type = DIAG_PERM;
336: dp -> ftd_identifier = FS_ACS_MGMT;
337: dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU;
338: dp -> ftd_delay = DIAG_NODELAY;
339: (void) sprintf (dp -> ftd_data, "unable to change to %s: %s",
340: pw -> pw_dir, sys_errname (errno));
341: dp -> ftd_cc = strlen (dp -> ftd_data);
342: dp++;
343: }
344: #endif
345:
346: if ((wtmp = open ("/usr/adm/wtmp", O_WRONLY | O_APPEND)) != NOTOK) {
347: char line[32];
348:
349: (void) sprintf (line, "ftam%d", getpid ());
350: (void) SCPYN (uts.ut_line, line);
351: #ifndef BRIDGE
352: (void) SCPYN (uts.ut_name, pw -> pw_name);
353: #else
354: (void) SCPYN (uts.ut_name, initiator);
355: #endif
356: #if !defined(SYS5) && !defined(bsd43_ut_host)
357: (void) SCPYN (uts.ut_host,
358: na2str (fts -> fts_callingaddr.pa_addr.sa_addr.ta_addrs));
359: #else
360: uts.ut_type = USER_PROCESS;
361: #endif
362: uts.ut_time = clok;
363: (void) write (wtmp, (char *) &uts, sizeof uts);
364: #if defined(SYS5) || defined(bsd43_ut_host)
365: (void) close (wtmp);
366: #endif
367: }
368:
369: #ifndef BRIDGE
370: if (cflag || guest) {
371: (void) setisobject (1); /* for PDU pretty-printing
372: AND for A-ASSOCIATE.RESPONSE!!! */
373: if (chroot (pw -> pw_dir) == NOTOK) {
374: if (!debug)
375: dp = diags;
376: dp -> ftd_type = DIAG_PERM;
377: if (debug) {
378: dp -> ftd_identifier = FS_ACS_MGMT;
379: dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU;
380: }
381: else {
382: dp -> ftd_identifier = FS_ACS_USER;
383: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
384: }
385: dp -> ftd_delay = DIAG_NODELAY;
386: (void) sprintf (dp -> ftd_data, "unable to change root to %s: %s",
387: pw -> pw_dir, sys_errname (errno));
388: dp -> ftd_cc = strlen (dp -> ftd_data);
389: if (debug)
390: dp++;
391: else
392: goto bad1;
393: }
394: #ifdef NULL_INITIATOR
395: else
396: if (null_initiator) {
397: if (chdir (pw -> pw_dir = "/pub") == NOTOK) {
398: dp -> ftd_type = DIAG_PERM;
399: dp -> ftd_identifier = FS_ACS_MGMT;
400: dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU;
401: dp -> ftd_delay = DIAG_NODELAY;
402: (void) sprintf (dp -> ftd_data,
403: "unable to change to %s: %s",
404: pw -> pw_dir, sys_errname (errno));
405: dp -> ftd_cc = strlen (dp -> ftd_data);
406: dp++;
407: }
408: }
409: #endif
410: else {
411: dp -> ftd_type = DIAG_INFORM;
412: dp -> ftd_identifier = FS_GEN_NOREASON;
413: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_RFSU;
414: dp -> ftd_delay = DIAG_NODELAY;
415: if (guest)
416: (void) strcpy (dp -> ftd_data,
417: "ANONymous user permitted, access restrictions apply");
418: dp -> ftd_cc = strlen (dp -> ftd_data);
419: dp++;
420:
421: pw -> pw_dir = "/";
422: }
423: }
424:
425: (void) sprintf (myhome, "%s/", pw -> pw_dir);
426: myhomelen = strlen (myhome);
427:
428: (void) setgid (pw -> pw_gid);
429: #ifndef SYS5
430: (void) initgroups (pw -> pw_name, pw -> pw_gid);
431: (void) seteuid (myuid = pw -> pw_uid);
432: #else
433: (void) setuid (myuid = pw -> pw_uid);
434: #endif
435:
436: (void) umask (0022);
437: #endif
438:
439: if (FInitializeResponse (ftamfd, FSTATE_SUCCESS, FACTION_SUCCESS,
440: NULLOID, NULLAEI, NULLPA, fts -> fts_manage,
441: class, units, attrs, NULLPE,
442: fqos, &fts -> fts_contents, diags, dp - diags,
443: fti) == NOTOK)
444: ftam_adios (&fti -> fti_abort, "F-INITIALIZE.RESPONSE");
445:
446: advise (LLOG_NOTICE, NULLCP, "accepting association");
447: ftam_diag (diags, dp - diags);
448: return;
449:
450: bad2: ;
451: dp -> ftd_type = DIAG_PERM;
452: dp -> ftd_delay = DIAG_NODELAY;
453: #ifndef BRIDGE
454: dp -> ftd_cc = 0;
455:
456: bad1: ;
457: #endif
458: advise (LLOG_NOTICE, NULLCP, "rejecting association");
459: ftam_diag (diags, 1);
460:
461: if (FInitializeResponse (ftamfd, FSTATE_FAILURE, FACTION_PERM, NULLOID,
462: NULLAEI, NULLPA, fts -> fts_manage, class, units, 0, NULLPE,
463: fqos, (struct FTAMcontentlist *) 0, diags, 1, fti) == NOTOK)
464: ftam_adios (&fti -> fti_abort, "F-INITIALIZE.RESPONSE(reject)");
465:
466: closewtmp ();
467:
468: exit (1);
469: }
470:
471: /* */
472:
473: int ftam_indication (fti)
474: register struct FTAMindication *fti;
475: {
476: switch (fti -> fti_type) {
477: case FTI_FINISH:
478: ftam_finishindication (&fti -> fti_finish);
479: break;
480:
481: case FTI_ABORT:
482: ftam_abortindication (&fti -> fti_abort);
483: break;
484:
485: case FTI_BULKBEGIN:
486: ftam_bulkbeginindication (&fti -> fti_group);
487: break;
488:
489: case FTI_READWRITE:
490: ftam_readwriteindication (&fti -> fti_readwrite);
491: break;
492:
493: case FTI_DATA:
494: ftam_dataindication (&fti -> fti_data);
495: break;
496:
497: case FTI_DATAEND:
498: ftam_dataendindication (&fti -> fti_dataend);
499: break;
500:
501: case FTI_CANCEL:
502: ftam_cancelindication (&fti -> fti_cancel);
503: break;
504:
505: case FTI_TRANSEND:
506: ftam_transendindication (&fti -> fti_transend);
507: break;
508:
509: case FTI_BULKEND:
510: ftam_bulkendindication (&fti -> fti_group);
511: break;
512:
513: case FTI_MANAGEMENT:
514: ftam_managementindication (&fti -> fti_group);
515: break;
516:
517: default:
518: adios (NULLCP, "unknown indication type=%d", fti -> fti_type);
519: }
520: }
521:
522: /* TERMINATION */
523:
524: /* ARGSUSED */
525:
526: static ftam_finishindication (ftf)
527: struct FTAMfinish *ftf;
528: {
529: #ifdef DEBUG
530: long now;
531: struct FTAMcharging fcs;
532: register struct FTAMcharging *fc = &fcs;
533: #else
534: #define fc ((struct FTAMcharging *) 0)
535: #endif
536: struct FTAMindication ftis;
537: register struct FTAMindication *fti = &ftis;
538: #ifdef BRIDGE
539: (void) ftp_quit ();
540: #endif
541:
542: advise (LLOG_NOTICE, NULLCP, "F-TERMINATE.INDICATION");
543:
544: #ifdef DEBUG
545: fc -> fc_ncharge = 0;
546: if (account) {
547: (void) time (&now);
548:
549: fc -> fc_charges[fc -> fc_ncharge].fc_resource = "elapsed time";
550: fc -> fc_charges[fc -> fc_ncharge].fc_unit = "seconds";
551: fc -> fc_charges[fc -> fc_ncharge++].fc_value = (int) (now - clok);
552: }
553: #endif
554:
555: if (FTerminateResponse (ftamfd, NULLPE, fc, fti) == NOTOK)
556: ftam_adios (&fti -> fti_abort, "F-TERMINATE.RESPONSE");
557:
558: FTFFREE (ftf);
559:
560: closewtmp ();
561:
562: exit (0);
563: }
564:
565:
566: closewtmp ()
567: {
568: #if !defined(SYS5) && !defined(bsd43_ut_host)
569: long now;
570:
571: (void) time (&now);
572:
573: if (wtmp != NOTOK) {
574: (void) lseek (wtmp, 0L, L_XTND);
575: (void) SCPYN (uts.ut_name, "");
576: (void) SCPYN (uts.ut_host, "");
577: uts.ut_time = now;
578: (void) write (wtmp, (char *) &uts, sizeof uts);
579: (void) close (wtmp);
580: }
581: #endif
582: }
583:
584: /* ABORT */
585:
586: static ftam_abortindication (fta)
587: register struct FTAMabort *fta;
588: {
589: struct FTAMindication ftis;
590:
591: advise (LLOG_NOTICE, NULLCP, "F-%s-ABORT.INDICATION %d",
592: fta -> fta_peer ? "U" : "P", fta -> fta_action);
593: ftam_diag (fta -> fta_diags, fta -> fta_ndiag);
594: #ifdef BRIDGE
595: (void) ftp_abort ();
596: (void) ftp_quit ();
597: #endif
598:
599: if (fta -> fta_action != FACTION_PERM && !fta -> fta_peer)
600: (void) FUAbortRequest (ftamfd, FACTION_PERM,
601: (struct FTAMdiagnostic *) 0, 0, &ftis);
602:
603: closewtmp ();
604:
605: exit (1);
606: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.