|
|
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.