|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 14636 (0x392c) Types: TextFile Names: »ftamsystem.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/ftam2/ftamsystem.c«
/* ftamsystem.c - FTAM responder routines */ #ifndef lint static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftamsystem.c,v 7.1 90/01/16 22:37:20 mrose Exp $"; #endif /* * $Header: /f/osi/ftam2/RCS/ftamsystem.c,v 7.1 90/01/16 22:37:20 mrose Exp $ * * * $Log: ftamsystem.c,v $ * Revision 7.1 90/01/16 22:37:20 mrose * very last time * * Revision 7.0 89/11/23 21:54:40 mrose * Release 6.0 * */ /* * NOTICE * * 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 * this agreement. * */ #if defined(DEBUG) && !defined(NULL_INITIATOR) #define NULL_INITIATOR #endif #include <ctype.h> #include <stdio.h> #include <grp.h> #include <pwd.h> #include "ftamsystem.h" #ifdef NULL_INITIATOR #include "tailor.h" #else #include "logger.h" #endif #include <utmp.h> #ifdef SYS5 struct group *getgrnam (); struct passwd *getpwnam (); #endif #ifndef ANON #define ANON "ftp" #endif /* \f UNIX DATA */ int myuid; int myhomelen; char myhome[MAXPATHLEN]; dev_t null_dev; ino_t null_ino; static int wtmp = NOTOK; static long clok; struct utmp uts; long lseek (), time (); char *crypt (); /* \f VFS DATA */ struct vfsmap vfs[] = { /* VFS_UBF */ "FTAM-3", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, binarypeek, 'b', VFS_XXX, FA_ACC_UA, -1, binarycheck, encode_DOCS_FTAM__3__Parameters, decode_DOCS_FTAM__3__Parameters, free_DOCS_FTAM__3__Parameters, "unstructured binary file", /* VFS_UTF */ "FTAM-1", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, textpeek, 't', VFS_UBF, FA_ACC_UA, -1, textcheck, encode_DOCS_FTAM__1__Parameters, decode_DOCS_FTAM__1__Parameters, free_DOCS_FTAM__1__Parameters, "unstructured text file", /* VFS_FDF */ "NBS-9", NULLOID, NULLCP, VF_NULL, 0, S_IFDIR, fdfpeek, 'd', VFS_XXX, FA_ACC_UA, 1, NULLIFP, encode_DOCS_NBS__9__Parameters, decode_DOCS_NBS__9__Parameters, free_DOCS_NBS__9__Parameters, "file directory file", NULL }; #ifdef BRIDGE int vfs_fdf = VFS_FDF; #endif /* \f REGIME DATA */ int fqos; int class; int units = FUNIT_READ | FUNIT_WRITE | FUNIT_LIMITED | FUNIT_ENHANCED | FUNIT_GROUPING; int attrs = FATTR_STORAGE; int fadusize = 0; /* \f ACTIVITY DATA */ int myfd = NOTOK; /* handle to file */ char *myfile; struct stat myst; int statok; struct vfsmap *myvf; /* active contents type */ caddr_t myparam; /* .. */ int myaccess; /* current access request */ char *initiator; /* current initiator identity */ #ifdef NULL_INITIATOR static int null_initiator = 0; /* none given, do EurOSInet style */ #endif struct FADUidentity mylocation;/* current location */ int mymode; /* current processing mode */ int myoperation; /* .. */ #ifdef notdef AEI mycalling; /* current calling AET */ AEI myresponding; /* current responding AET */ #endif char *account; /* current account */ int mygid; /* "inner" account */ int mylock; /* current concurrency control */ struct FTAMconcurrency myconctl;/* .. */ int mylockstyle; /* current locking style */ int mycontext; /* current access context */ int mylevel; /* .. */ #ifdef BRIDGE static char *RemoteHost; static char *password; int ftp_default = VFS_UBF; #endif /* \f REGIME */ #ifdef BRIDGE #define seterr(id,ob,so,des) \ { \ dp -> ftd_identifier = (id); \ dp -> ftd_observer = (ob), dp -> ftd_source = (so); \ (void) strncpy (dp -> ftd_data, des, FTD_SIZE);\ dp -> ftd_cc = strlen(dp -> ftd_data);\ goto bad2; \ } #else #define seterr(id,ob,so,des) \ { \ dp -> ftd_identifier = (id); \ dp -> ftd_observer = (ob), dp -> ftd_source = (so); \ goto bad2; \ } #endif int ftam_start (fts) register struct FTAMstart *fts; { register int i; #ifndef BRIDGE int guest; struct passwd *pw; #endif struct stat st; register struct isodocument *id; register struct vfsmap *vf; register struct FTAMcontent *fx; struct FTAMdiagnostic diags[NFDIAG]; register struct FTAMdiagnostic *dp = diags; struct FTAMindication ftis; struct FTAMindication *fti = &ftis; (void) time (&clok); if (stat ("/dev/null", &st) != NOTOK) null_dev = st.st_dev, null_ino = st.st_ino; else null_dev = (dev_t) 0, null_ino = (ino_t) 0; for (vf = vfs; vf -> vf_entry; vf++) if (id = getisodocumentbyentry (vf -> vf_entry)) { if ((vf -> vf_oid = oid_cpy (id -> id_type)) == NULLOID) adios (NULLCP, "%s: out of memory", vf -> vf_entry); } else if (vf -> vf_flags & VF_WARN) advise (LLOG_NOTICE, NULLCP, "%s: unknown", vf -> vf_entry); ftamfd = fts -> fts_sd; if ((class = fts -> fts_class) & FCLASS_TM) class = FCLASS_TM; else if (class & FCLASS_TRANSFER) class = FCLASS_TRANSFER; else if (class & FCLASS_MANAGE) class = FCLASS_MANAGE; else seterr (FS_ACS_CLASS, EREF_RFSU, EREF_IFSU, ""); units &= fts -> fts_units; attrs &= fts -> fts_attrs; if ((fqos = fts -> fts_fqos) != FQOS_NORECOVERY) seterr (FS_ACS_ROLLBACK, EREF_RFPM, EREF_IFSU, ""); if ((fadusize = fts -> fts_ssdusize) < 0) fadusize = 0; for (fx = fts -> fts_contents.fc_contents, i = fts -> fts_contents.fc_ncontent - 1; i >= 0; fx++, i--) { if (fx -> fc_result != PC_ACCEPT) continue; for (vf = vfs; vf -> vf_entry; vf++) if (vf -> vf_oid && oid_cmp (vf -> vf_oid, fx -> fc_dtn) == 0) { vf -> vf_flags |= VF_OK; vf -> vf_id = fx -> fc_id; break; } if (!vf -> vf_entry) { advise (LLOG_NOTICE, NULLCP, "%s: unknown document-type", oid2ode (fx -> fc_dtn)); fx -> fc_result = PC_REJECTED; } } if ((initiator = fts -> fts_initiator) == NULL) { #ifdef NULL_INITIATOR initiator = ANON; null_initiator = 1; #else seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU, ""); #endif } fts -> fts_initiator = NULL; #ifdef BRIDGE /* scan initiator for remote host */ if ((RemoteHost = rindex(initiator, '@')) == NULL) { advise (LLOG_EXCEPTIONS, NULLCP, "missing remote host name in \"%s\"", initiator); seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU, "missing remote hostname"); } *RemoteHost++ = '\0'; if (strcmp (initiator, "ANON") == 0 || strcmp (initiator, ANON) == 0) { initiator = "ANONYMOUS"; /* FTP guest name */ } password = (fts -> fts_password == NULL) ? "guest" : fts -> fts_password; account = fts -> fts_account; advise (LLOG_NOTICE, NULLCP, "attemping connection with TCP host \"%s\" for user \"%s\"", RemoteHost, initiator); if (ftp_login(RemoteHost, initiator, password, account) == NOTOK) seterr (FS_ACS_IDENTITY, EREF_RFSU, EREF_IFSU, ftp_error); (void) strcpy (myhome, ""); myhomelen = strlen (myhome); #else guest = 0; #ifdef NULL_INITIATOR if (!baduser (NULLCP, initiator) && baduser ("ftamguests", initiator)) { initiator = ANON; null_initiator = 1; } #endif if (strcmp (initiator, "ANON") == 0 || strcmp (initiator, ANON) == 0) { if ((pw = getpwnam (ANON)) && pw -> pw_uid == 0) pw = NULL; guest = 1; } else pw = baduser ("ftamusers", initiator) ? NULL : getpwnam (initiator); if (pw == NULL) seterr (FS_ACS_USER, EREF_RFSU, EREF_IFSU, ""); if ((!guest && fts -> fts_password == NULL) || *pw -> pw_passwd == NULL || (!guest && strcmp (crypt (fts -> fts_password, pw -> pw_passwd), pw -> pw_passwd))) seterr (FS_ACS_PASSWORD, EREF_RFSU, EREF_IFSU, ""); if (account = fts -> fts_account) { register struct group *gr = getgrnam (account); register char **gp; if (gr == NULL) { bad_account: ; seterr (FS_ACS_ACCT, EREF_RFPM, EREF_IFSU, ""); } if (gr -> gr_gid != pw -> pw_gid) { for (gp = gr -> gr_mem; *gp; gp++) if (strcmp (*gp, initiator) == 0) break; if (!*gp) goto bad_account; } fts -> fts_account = NULL; } if (chdir (pw -> pw_dir) == NOTOK) { dp -> ftd_type = DIAG_PERM; dp -> ftd_identifier = FS_ACS_MGMT; dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU; dp -> ftd_delay = DIAG_NODELAY; (void) sprintf (dp -> ftd_data, "unable to change to %s: %s", pw -> pw_dir, sys_errname (errno)); dp -> ftd_cc = strlen (dp -> ftd_data); dp++; } #endif if ((wtmp = open ("/usr/adm/wtmp", O_WRONLY | O_APPEND)) != NOTOK) { char line[32]; (void) sprintf (line, "ftam%d", getpid ()); (void) SCPYN (uts.ut_line, line); #ifndef BRIDGE (void) SCPYN (uts.ut_name, pw -> pw_name); #else (void) SCPYN (uts.ut_name, initiator); #endif #if !defined(SYS5) && !defined(bsd43_ut_host) (void) SCPYN (uts.ut_host, na2str (fts -> fts_callingaddr.pa_addr.sa_addr.ta_addrs)); #else uts.ut_type = USER_PROCESS; #endif uts.ut_time = clok; (void) write (wtmp, (char *) &uts, sizeof uts); #if defined(SYS5) || defined(bsd43_ut_host) (void) close (wtmp); #endif } #ifndef BRIDGE if (cflag || guest) { (void) setisobject (1); /* for PDU pretty-printing AND for A-ASSOCIATE.RESPONSE!!! */ if (chroot (pw -> pw_dir) == NOTOK) { if (!debug) dp = diags; dp -> ftd_type = DIAG_PERM; if (debug) { dp -> ftd_identifier = FS_ACS_MGMT; dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU; } else { dp -> ftd_identifier = FS_ACS_USER; dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; } dp -> ftd_delay = DIAG_NODELAY; (void) sprintf (dp -> ftd_data, "unable to change root to %s: %s", pw -> pw_dir, sys_errname (errno)); dp -> ftd_cc = strlen (dp -> ftd_data); if (debug) dp++; else goto bad1; } #ifdef NULL_INITIATOR else if (null_initiator) { if (chdir (pw -> pw_dir = "/pub") == NOTOK) { dp -> ftd_type = DIAG_PERM; dp -> ftd_identifier = FS_ACS_MGMT; dp -> ftd_observer = EREF_RFPM, dp -> ftd_source = EREF_IFSU; dp -> ftd_delay = DIAG_NODELAY; (void) sprintf (dp -> ftd_data, "unable to change to %s: %s", pw -> pw_dir, sys_errname (errno)); dp -> ftd_cc = strlen (dp -> ftd_data); dp++; } } #endif else { dp -> ftd_type = DIAG_INFORM; dp -> ftd_identifier = FS_GEN_NOREASON; dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_RFSU; dp -> ftd_delay = DIAG_NODELAY; if (guest) (void) strcpy (dp -> ftd_data, "ANONymous user permitted, access restrictions apply"); dp -> ftd_cc = strlen (dp -> ftd_data); dp++; pw -> pw_dir = "/"; } } (void) sprintf (myhome, "%s/", pw -> pw_dir); myhomelen = strlen (myhome); (void) setgid (pw -> pw_gid); #ifndef SYS5 (void) initgroups (pw -> pw_name, pw -> pw_gid); (void) seteuid (myuid = pw -> pw_uid); #else (void) setuid (myuid = pw -> pw_uid); #endif (void) umask (0022); #endif if (FInitializeResponse (ftamfd, FSTATE_SUCCESS, FACTION_SUCCESS, NULLOID, NULLAEI, NULLPA, fts -> fts_manage, class, units, attrs, NULLPE, fqos, &fts -> fts_contents, diags, dp - diags, fti) == NOTOK) ftam_adios (&fti -> fti_abort, "F-INITIALIZE.RESPONSE"); advise (LLOG_NOTICE, NULLCP, "accepting association"); ftam_diag (diags, dp - diags); return; bad2: ; dp -> ftd_type = DIAG_PERM; dp -> ftd_delay = DIAG_NODELAY; #ifndef BRIDGE dp -> ftd_cc = 0; bad1: ; #endif advise (LLOG_NOTICE, NULLCP, "rejecting association"); ftam_diag (diags, 1); if (FInitializeResponse (ftamfd, FSTATE_FAILURE, FACTION_PERM, NULLOID, NULLAEI, NULLPA, fts -> fts_manage, class, units, 0, NULLPE, fqos, (struct FTAMcontentlist *) 0, diags, 1, fti) == NOTOK) ftam_adios (&fti -> fti_abort, "F-INITIALIZE.RESPONSE(reject)"); closewtmp (); exit (1); } /* \f */ int ftam_indication (fti) register struct FTAMindication *fti; { switch (fti -> fti_type) { case FTI_FINISH: ftam_finishindication (&fti -> fti_finish); break; case FTI_ABORT: ftam_abortindication (&fti -> fti_abort); break; case FTI_BULKBEGIN: ftam_bulkbeginindication (&fti -> fti_group); break; case FTI_READWRITE: ftam_readwriteindication (&fti -> fti_readwrite); break; case FTI_DATA: ftam_dataindication (&fti -> fti_data); break; case FTI_DATAEND: ftam_dataendindication (&fti -> fti_dataend); break; case FTI_CANCEL: ftam_cancelindication (&fti -> fti_cancel); break; case FTI_TRANSEND: ftam_transendindication (&fti -> fti_transend); break; case FTI_BULKEND: ftam_bulkendindication (&fti -> fti_group); break; case FTI_MANAGEMENT: ftam_managementindication (&fti -> fti_group); break; default: adios (NULLCP, "unknown indication type=%d", fti -> fti_type); } } /* \f TERMINATION */ /* ARGSUSED */ static ftam_finishindication (ftf) struct FTAMfinish *ftf; { #ifdef DEBUG long now; struct FTAMcharging fcs; register struct FTAMcharging *fc = &fcs; #else #define fc ((struct FTAMcharging *) 0) #endif struct FTAMindication ftis; register struct FTAMindication *fti = &ftis; #ifdef BRIDGE (void) ftp_quit (); #endif advise (LLOG_NOTICE, NULLCP, "F-TERMINATE.INDICATION"); #ifdef DEBUG fc -> fc_ncharge = 0; if (account) { (void) time (&now); fc -> fc_charges[fc -> fc_ncharge].fc_resource = "elapsed time"; fc -> fc_charges[fc -> fc_ncharge].fc_unit = "seconds"; fc -> fc_charges[fc -> fc_ncharge++].fc_value = (int) (now - clok); } #endif if (FTerminateResponse (ftamfd, NULLPE, fc, fti) == NOTOK) ftam_adios (&fti -> fti_abort, "F-TERMINATE.RESPONSE"); FTFFREE (ftf); closewtmp (); exit (0); } closewtmp () { #if !defined(SYS5) && !defined(bsd43_ut_host) long now; (void) time (&now); if (wtmp != NOTOK) { (void) lseek (wtmp, 0L, L_XTND); (void) SCPYN (uts.ut_name, ""); (void) SCPYN (uts.ut_host, ""); uts.ut_time = now; (void) write (wtmp, (char *) &uts, sizeof uts); (void) close (wtmp); } #endif } /* \f ABORT */ static ftam_abortindication (fta) register struct FTAMabort *fta; { struct FTAMindication ftis; advise (LLOG_NOTICE, NULLCP, "F-%s-ABORT.INDICATION %d", fta -> fta_peer ? "U" : "P", fta -> fta_action); ftam_diag (fta -> fta_diags, fta -> fta_ndiag); #ifdef BRIDGE (void) ftp_abort (); (void) ftp_quit (); #endif if (fta -> fta_action != FACTION_PERM && !fta -> fta_peer) (void) FUAbortRequest (ftamfd, FACTION_PERM, (struct FTAMdiagnostic *) 0, 0, &ftis); closewtmp (); exit (1); }