|
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 i
Length: 14544 (0x38d0) Types: TextFile Names: »idistd.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/others/idist/idistd.c«
/* idistd.c - remote distribution -- responder */ #ifndef lint static char *rcsid = "$Header: /f/osi/others/idist/RCS/idistd.c,v 7.0 89/11/23 21:58:31 mrose Rel $"; #endif /* * $Header: /f/osi/others/idist/RCS/idistd.c,v 7.0 89/11/23 21:58:31 mrose Rel $ * * Idist daemon - this module handles the remote operations as they * are received. It runs as a state machine for file transfer * expecting the sequence transfer, data..., terminate for each file * transfered. This module has only slight correlation with the * original UCB version. It is entirely client driven. This server is * not designed to run other than under tsapd. Two reasons for this :- * 1) There is a lot of state info kept around in global variables * (this is fixable if required) * 2) Its first operation is to setuid to the authenticated user. This * is a one way operation - thus 1) is not really worth fixing (IMHO). * * Julian Onions <jpo@cs.nott.ac.uk> * Nottingham University Computer Science. * * * $Log: idistd.c,v $ * Revision 7.0 89/11/23 21:58:31 mrose * Release 6.0 * */ #include <stdio.h> #include <varargs.h> #include "ryresponder.h" /* for generic idempotent responders */ #include "Idist-ops.h" /* operation definitions */ #include "Idist-types.h" /* type definitions */ #include "defs.h" /* \f DATA */ static char *myservice = "isode idist"; extern struct type_Idist_QueryResult *query (); extern struct type_Idist_FileList *do_listcdir (); static int error (), strerror (), syserror (), ureject (); /* OPERATIONS */ int op_init (), op_transfer (), op_terminate (), op_listcdir (), op_query (), op_special (), op_data (), op_deletefile (); static struct dispatch dispatches[] = { "init", operation_Idist_init, op_init, "transfer", operation_Idist_transfer, op_transfer, "terminate", operation_Idist_terminate, op_terminate, "listcdir", operation_Idist_listcdir, op_listcdir, "deletefile", operation_Idist_deletefile, op_deletefile, "query", operation_Idist_query, op_query, "special", operation_Idist_special, op_special, "data", operation_Idist_data, op_data, NULL }; int catname = 0; char target[BUFSIZ]; extern char *tp; extern char *stp[]; FILE *cfile; /* the currently open file */ struct type_Idist_FileSpec *cfiletype; int oumask; char utmpfile[] = "/tmp/idistXXXXXX"; char *tmpname = &utmpfile[5]; struct type_Idist_IA5List *ia5list; char *host; int groupid, userid; char homedir[BUFSIZ]; char user[100]; struct passwd *pw; struct group *gr; /* \f MAIN */ /* ARGSUSED */ main (argc, argv, envp) int argc; char **argv, **envp; { static int initiate (); oumask = umask (0); host = getlocalhost (); (void) ryresponder (argc, argv, PLocalHostName (), myservice, dispatches, table_Idist_Operations, initiate, NULLIFP); exit (0); /* NOTREACHED */ } /* \f OPERATIONS */ static int op_init (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { char *str; register struct type_Idist_InitDir *arg = (struct type_Idist_InitDir *) in; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); if (arg -> offset == type_Idist_InitDir_destdir) { catname = 1; str = qb2str (arg -> un.destdir); } else { catname = 0; str = qb2str (arg ->un.nodestdir); } if (exptilde (target, str) == NULL) return error (sd, error_Idist_badfilename, (caddr_t)ia5list, rox, roi); tp = target + strlen (target); if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); return OK; } op_transfer (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_Idist_FileSpec *arg = (struct type_Idist_FileSpec *) in; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); switch (arg -> filetype -> parm) { case int_Idist_FileType_regular: if (do_rfile (arg) == NOTOK) return error (sd, error_Idist_badfilename, (caddr_t)ia5list, rox, roi); break; case int_Idist_FileType_directory: if (do_direct (arg) == NOTOK) return error (sd, error_Idist_badfilename, (caddr_t)ia5list, rox, roi); break; case int_Idist_FileType_symlink: if (do_symlink (arg) == NOTOK) return error (sd, error_Idist_badfilename, (caddr_t) ia5list, rox, roi); break; case int_Idist_FileType_hardlink: if ( do_hardlink (arg) == NOTOK) return error (sd, error_Idist_badfilename, (caddr_t) ia5list, rox, roi); break; default: return error (sd, error_Idist_badfiletype, (caddr_t) NULL, rox, roi); } if (cfiletype != NULL) free_Idist_FileSpec (cfiletype); cfiletype = arg; if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); free_Idist_IA5List (ia5list); ia5list = NULL; return OK; } op_data (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_Idist_Data *arg = (struct type_Idist_Data *) in; register struct qbuf *qb; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); for (qb = arg -> qb_forw; qb != arg; qb = qb -> qb_forw) { if (fwrite (qb -> qb_data, sizeof (char), qb -> qb_len, cfile) != qb -> qb_len) return syserror (sd, error_Idist_writeerror, rox, roi); } if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); return OK; } op_query (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_UNIV_IA5String *arg = (struct type_UNIV_IA5String *) in; struct type_Idist_QueryResult *qr; char *str; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); str = qb2str (arg); qr = query (str); free (str); if (qr == NULL) return error (sd, error_Idist_congested, (caddr_t)ia5list, rox, roi); if (RyDsResult (sd, rox -> rox_id, (caddr_t) qr, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); free_Idist_QueryResult (qr); return OK; } op_terminate (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_Idist_TermStatus *arg = (struct type_Idist_TermStatus *) in; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); switch (arg -> filetype -> parm) { case int_Idist_FileType_regular: if (cfile == NULL) return strerror (sd, error_Idist_protocol, "File not open", rox, roi); (void) fflush (cfile); if (ferror (cfile)) return syserror (sd, error_Idist_writeerror, rox, roi); (void) fclose (cfile); if ( fixup () < 0) return error (sd, error_Idist_fileproblem, (caddr_t) ia5list, rox, roi); break; case int_Idist_FileType_directory: *tp = '\0'; if (catname <= 0) return strerror (sd, error_Idist_protocol, "Too many directory levels popped", rox, roi); tp = stp[--catname]; *tp = '\0'; break; case int_Idist_FileType_symlink: case int_Idist_FileType_hardlink: return strerror (sd, error_Idist_protocol, "Bad file type for terminate operation", rox, roi); default: return error (sd, error_Idist_badfiletype, (caddr_t)NULL, rox, roi); } if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); return OK; } op_special (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_UNIV_IA5String *arg = (struct type_UNIV_IA5String *) in; int result; char *str; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); str = qb2str (arg); result = doexec (str); free (str); if (result == NOTOK) return syserror (sd, error_Idist_execError, rox, roi); if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); free_Idist_IA5List (ia5list); ia5list = NULL; return OK; } op_deletefile (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { register struct type_UNIV_IA5String *arg = (struct type_UNIV_IA5String *) in; int result; char *str; char buf[BUFSIZ]; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); str = qb2str (arg); (void) sprintf (buf, "%s/%s", target, str); free (str); result = remove (buf); if (result == NOTOK) return error (sd, error_Idist_badfilename, (caddr_t) ia5list, rox, roi); if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); free_Idist_IA5List (ia5list); ia5list = NULL; return OK; } /* ARGSUSED */ op_listcdir (sd, ryo, rox, in, roi) int sd; struct RyOperation *ryo; struct RoSAPinvoke *rox; caddr_t in; struct RoSAPindication *roi; { struct type_Idist_FileList *fl; if (rox -> rox_nolinked == 0) { advise (LLOG_NOTICE, NULLCP, "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", sd, ryo -> ryo_name, rox -> rox_linkid); return ureject (sd, ROS_IP_LINKED, rox, roi); } if (debug) advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name); fl = do_listcdir (); if (RyDsResult (sd, rox -> rox_id, (caddr_t) fl, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "RESULT"); free_Idist_FileList (fl); return OK; } /* \f ERROR */ static int error (sd, err, param, rox, roi) int sd, err; caddr_t param; struct RoSAPinvoke *rox; struct RoSAPindication *roi; { if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "ERROR"); if (ia5list) free_Idist_IA5List (ia5list); ia5list = NULL; return OK; } static int strerror (sd, err, str, rox, roi) int sd, err; char *str; struct RoSAPinvoke *rox; struct RoSAPindication *roi; { addtoia5 (str, strlen(str)); return error (sd, err, (caddr_t)ia5list, rox, roi); } static int syserror (sd, err, rox, roi) int sd, err; struct RoSAPinvoke *rox; struct RoSAPindication *roi; { extern int errno; return strerror (sd, err, sys_errname (errno), rox, roi); } /* \f U-REJECT */ static int ureject (sd, reason, rox, roi) int sd, reason; struct RoSAPinvoke *rox; struct RoSAPindication *roi; { if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK) ros_adios (&roi -> roi_preject, "U-REJECT"); return OK; } /* \f Initialisation stuff */ /* ARGSUSED */ initiate (sd, acs, pe) int sd; struct AcSAPstart *acs; PE *pe; { struct type_Idist_Initiate *initial; char *cp, *crypt (); *pe = NULLPE; if ( acs -> acs_ninfo != 1) return init_lose (ACS_PERMANENT, pe, "No Association data"); if (decode_Idist_Initiate (acs -> acs_info[0], 1, NULLIP, NULLVP, &initial) == NOTOK) return init_lose (ACS_PERMANENT, pe, "Can't parse initial data"); if (initial -> version != VERSION) return init_lose (ACS_PERMANENT, pe, "Version mismatch"); cp = qb2str (initial -> user); (void) strcpy (user, cp); free (cp); if (baduser (NULLCP, user)) { advise (LLOG_EXCEPTIONS, NULLCP, "Bad listed user '%s'", user); return init_lose (ACS_PERMANENT, pe, "Bad user/password"); } if ((pw = getpwnam (user)) == NULL) { advise (LLOG_NOTICE, NULLCP, "Unknown user '%s'", user); return init_lose (ACS_PERMANENT, pe, "Bad user/password"); } userid = pw -> pw_uid; groupid = pw -> pw_gid; (void) strcpy (homedir, pw -> pw_dir); cp = qb2str (initial -> passwd); if (pw -> pw_passwd == NULL || strcmp (crypt (cp, pw -> pw_passwd), pw -> pw_passwd) != 0) { advise (LLOG_NOTICE, NULLCP, "Password mismatch for %s", user); return init_lose (ACS_PERMANENT, pe, "Bad user/password"); } bzero (cp, strlen(cp)); /* in case of cores */ free (cp); free_Idist_Initiate (initial); if (chdir (homedir) == -1) { advise (LLOG_NOTICE, NULLCP, "Can't set home directory to '%s'", homedir); return init_lose (ACS_PERMANENT, pe, "No home directory"); } if (setreuid (userid, userid) < 0) { advise (LLOG_NOTICE, NULLCP, "Cant set userid %d for %s", userid, user); return init_lose (ACS_PERMANENT, pe, "Can't set user id"); } (void) mktemp (utmpfile); return ACS_ACCEPT; } init_lose (type, pe, str) int type; PE *pe; char *str; { *pe = ia5s2prim (str, strlen(str)); (*pe) -> pe_context = 3; /* magic!! - don't ask me why */ return type; }