|
|
1.1 root 1: /* idistd.c - remote distribution -- responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/idist/RCS/idistd.c,v 7.1 90/07/09 14:39:17 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/idist/RCS/idistd.c,v 7.1 90/07/09 14:39:17 mrose Exp $
9: *
10: * Idist daemon - this module handles the remote operations as they
11: * are received. It runs as a state machine for file transfer
12: * expecting the sequence transfer, data..., terminate for each file
13: * transfered. This module has only slight correlation with the
14: * original UCB version. It is entirely client driven. This server is
15: * not designed to run other than under tsapd. Two reasons for this :-
16: * 1) There is a lot of state info kept around in global variables
17: * (this is fixable if required)
18: * 2) Its first operation is to setuid to the authenticated user. This
19: * is a one way operation - thus 1) is not really worth fixing (IMHO).
20: *
21: * Julian Onions <[email protected]>
22: * Nottingham University Computer Science.
23: *
24: *
25: * $Log: idistd.c,v $
26: * Revision 7.1 90/07/09 14:39:17 mrose
27: * sync
28: *
29: * Revision 7.0 89/11/23 21:58:31 mrose
30: * Release 6.0
31: *
32: */
33:
34: #include <stdio.h>
35: #include <varargs.h>
36: #include "ryresponder.h" /* for generic idempotent responders */
37: #include "Idist-ops.h" /* operation definitions */
38: #include "Idist-types.h" /* type definitions */
39: #include "defs.h"
40:
41: /* DATA */
42:
43: static char *myservice = "isode idist";
44:
45: extern struct type_Idist_QueryResult *query ();
46: extern struct type_Idist_FileList *do_listcdir ();
47:
48: static int error (), strerror (), syserror (), ureject ();
49:
50: /* OPERATIONS */
51: int op_init (), op_transfer (), op_terminate (), op_listcdir (),
52: op_query (), op_special (), op_data (), op_deletefile ();
53:
54: static struct dispatch dispatches[] = {
55: "init", operation_Idist_init, op_init,
56:
57: "transfer", operation_Idist_transfer, op_transfer,
58:
59: "terminate", operation_Idist_terminate, op_terminate,
60:
61: "listcdir", operation_Idist_listcdir, op_listcdir,
62:
63: "deletefile", operation_Idist_deletefile, op_deletefile,
64:
65: "query", operation_Idist_query, op_query,
66:
67: "special", operation_Idist_special, op_special,
68:
69: "data", operation_Idist_data, op_data,
70:
71: NULL
72: };
73:
74: int catname = 0;
75: char target[BUFSIZ];
76: extern char *tp;
77: extern char *stp[];
78: FILE *cfile; /* the currently open file */
79: struct type_Idist_FileSpec *cfiletype;
80: int oumask;
81: char utmpfile[] = "/tmp/idistXXXXXX";
82: char *tmpname = &utmpfile[5];
83: struct type_Idist_IA5List *ia5list;
84:
85: char *host;
86: int groupid, userid;
87: char homedir[BUFSIZ];
88: char user[100];
89: struct passwd *pw;
90: struct group *gr;
91:
92: /* MAIN */
93:
94: /* ARGSUSED */
95:
96: main (argc, argv, envp)
97: int argc;
98: char **argv,
99: **envp;
100: {
101: static int initiate ();
102: oumask = umask (0);
103:
104: host = getlocalhost ();
105:
106: (void) ryresponder (argc, argv, PLocalHostName (), myservice, NULLCP,
107: dispatches, table_Idist_Operations, initiate,
108: NULLIFP);
109:
110: exit (0); /* NOTREACHED */
111: }
112:
113: /* OPERATIONS */
114:
115: static int op_init (sd, ryo, rox, in, roi)
116: int sd;
117: struct RyOperation *ryo;
118: struct RoSAPinvoke *rox;
119: caddr_t in;
120: struct RoSAPindication *roi;
121: {
122: char *str;
123: register struct type_Idist_InitDir *arg =
124: (struct type_Idist_InitDir *) in;
125:
126: if (rox -> rox_nolinked == 0) {
127: advise (LLOG_NOTICE, NULLCP,
128: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
129: sd, ryo -> ryo_name, rox -> rox_linkid);
130: return ureject (sd, ROS_IP_LINKED, rox, roi);
131: }
132: if (debug)
133: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
134: sd, ryo -> ryo_name);
135:
136: if (arg -> offset == type_Idist_InitDir_destdir) {
137: catname = 1;
138: str = qb2str (arg -> un.destdir);
139: }
140: else {
141: catname = 0;
142: str = qb2str (arg ->un.nodestdir);
143: }
144: if (exptilde (target, str) == NULL)
145: return error (sd, error_Idist_badfilename, (caddr_t)ia5list,
146: rox, roi);
147:
148: tp = target + strlen (target);
149:
150: if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO,
151: roi) == NOTOK)
152: ros_adios (&roi -> roi_preject, "RESULT");
153:
154: return OK;
155: }
156:
157: op_transfer (sd, ryo, rox, in, roi)
158: int sd;
159: struct RyOperation *ryo;
160: struct RoSAPinvoke *rox;
161: caddr_t in;
162: struct RoSAPindication *roi;
163: {
164: register struct type_Idist_FileSpec *arg =
165: (struct type_Idist_FileSpec *) in;
166:
167: if (rox -> rox_nolinked == 0) {
168: advise (LLOG_NOTICE, NULLCP,
169: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
170: sd, ryo -> ryo_name, rox -> rox_linkid);
171: return ureject (sd, ROS_IP_LINKED, rox, roi);
172: }
173: if (debug)
174: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
175: sd, ryo -> ryo_name);
176:
177: switch (arg -> filetype -> parm) {
178:
179: case int_Idist_FileType_regular:
180: if (do_rfile (arg) == NOTOK)
181: return error (sd, error_Idist_badfilename,
182: (caddr_t)ia5list, rox, roi);
183: break;
184:
185: case int_Idist_FileType_directory:
186: if (do_direct (arg) == NOTOK)
187: return error (sd, error_Idist_badfilename,
188: (caddr_t)ia5list, rox, roi);
189: break;
190:
191: case int_Idist_FileType_symlink:
192: if (do_symlink (arg) == NOTOK)
193: return error (sd, error_Idist_badfilename,
194: (caddr_t) ia5list, rox, roi);
195: break;
196:
197: case int_Idist_FileType_hardlink:
198: if ( do_hardlink (arg) == NOTOK)
199: return error (sd, error_Idist_badfilename,
200: (caddr_t) ia5list, rox, roi);
201: break;
202:
203: default:
204: return error (sd, error_Idist_badfiletype, (caddr_t) NULL,
205: rox, roi);
206: }
207:
208: if (cfiletype != NULL)
209: free_Idist_FileSpec (cfiletype);
210: cfiletype = arg;
211:
212: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi)
213: == NOTOK)
214: ros_adios (&roi -> roi_preject, "RESULT");
215:
216: free_Idist_IA5List (ia5list);
217: ia5list = NULL;
218:
219: return OK;
220: }
221:
222: op_data (sd, ryo, rox, in, roi)
223: int sd;
224: struct RyOperation *ryo;
225: struct RoSAPinvoke *rox;
226: caddr_t in;
227: struct RoSAPindication *roi;
228: {
229: register struct type_Idist_Data *arg =
230: (struct type_Idist_Data *) in;
231: register struct qbuf *qb;
232:
233: if (rox -> rox_nolinked == 0) {
234: advise (LLOG_NOTICE, NULLCP,
235: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
236: sd, ryo -> ryo_name, rox -> rox_linkid);
237: return ureject (sd, ROS_IP_LINKED, rox, roi);
238: }
239: if (debug)
240: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
241: sd, ryo -> ryo_name);
242: for (qb = arg -> qb_forw; qb != arg; qb = qb -> qb_forw) {
243: if (fwrite (qb -> qb_data, sizeof (char),
244: qb -> qb_len, cfile) != qb -> qb_len)
245: return syserror (sd, error_Idist_writeerror,
246: rox, roi);
247: }
248: if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi)
249: == NOTOK)
250: ros_adios (&roi -> roi_preject, "RESULT");
251:
252: return OK;
253: }
254:
255: op_query (sd, ryo, rox, in, roi)
256: int sd;
257: struct RyOperation *ryo;
258: struct RoSAPinvoke *rox;
259: caddr_t in;
260: struct RoSAPindication *roi;
261: {
262: register struct type_UNIV_IA5String *arg =
263: (struct type_UNIV_IA5String *) in;
264: struct type_Idist_QueryResult *qr;
265: char *str;
266:
267: if (rox -> rox_nolinked == 0) {
268: advise (LLOG_NOTICE, NULLCP,
269: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
270: sd, ryo -> ryo_name, rox -> rox_linkid);
271: return ureject (sd, ROS_IP_LINKED, rox, roi);
272: }
273: if (debug)
274: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
275: sd, ryo -> ryo_name);
276:
277: str = qb2str (arg);
278: qr = query (str);
279: free (str);
280:
281: if (qr == NULL)
282: return error (sd, error_Idist_congested, (caddr_t)ia5list,
283: rox, roi);
284:
285: if (RyDsResult (sd, rox -> rox_id, (caddr_t) qr, ROS_NOPRIO, roi)
286: == NOTOK)
287: ros_adios (&roi -> roi_preject, "RESULT");
288:
289: free_Idist_QueryResult (qr);
290:
291: return OK;
292: }
293:
294: op_terminate (sd, ryo, rox, in, roi)
295: int sd;
296: struct RyOperation *ryo;
297: struct RoSAPinvoke *rox;
298: caddr_t in;
299: struct RoSAPindication *roi;
300: {
301: register struct type_Idist_TermStatus *arg =
302: (struct type_Idist_TermStatus *) in;
303:
304: if (rox -> rox_nolinked == 0) {
305: advise (LLOG_NOTICE, NULLCP,
306: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
307: sd, ryo -> ryo_name, rox -> rox_linkid);
308: return ureject (sd, ROS_IP_LINKED, rox, roi);
309: }
310: if (debug)
311: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
312: sd, ryo -> ryo_name);
313:
314: switch (arg -> filetype -> parm) {
315: case int_Idist_FileType_regular:
316: if (cfile == NULL)
317: return strerror (sd, error_Idist_protocol,
318: "File not open", rox, roi);
319: (void) fflush (cfile);
320: if (ferror (cfile))
321: return syserror (sd, error_Idist_writeerror, rox, roi);
322: (void) fclose (cfile);
323: if ( fixup () < 0)
324: return error (sd, error_Idist_fileproblem,
325: (caddr_t) ia5list, rox, roi);
326: break;
327:
328: case int_Idist_FileType_directory:
329: *tp = '\0';
330: if (catname <= 0)
331: return strerror (sd, error_Idist_protocol,
332: "Too many directory levels popped",
333: rox, roi);
334: tp = stp[--catname];
335: *tp = '\0';
336: break;
337:
338: case int_Idist_FileType_symlink:
339: case int_Idist_FileType_hardlink:
340: return strerror (sd, error_Idist_protocol,
341: "Bad file type for terminate operation",
342: rox, roi);
343:
344: default:
345: return error (sd, error_Idist_badfiletype, (caddr_t)NULL,
346: rox, roi);
347: }
348:
349: if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL, ROS_NOPRIO, roi)
350: == NOTOK)
351: ros_adios (&roi -> roi_preject, "RESULT");
352:
353: return OK;
354: }
355:
356: op_special (sd, ryo, rox, in, roi)
357: int sd;
358: struct RyOperation *ryo;
359: struct RoSAPinvoke *rox;
360: caddr_t in;
361: struct RoSAPindication *roi;
362: {
363: register struct type_UNIV_IA5String *arg =
364: (struct type_UNIV_IA5String *) in;
365: int result;
366: char *str;
367:
368: if (rox -> rox_nolinked == 0) {
369: advise (LLOG_NOTICE, NULLCP,
370: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
371: sd, ryo -> ryo_name, rox -> rox_linkid);
372: return ureject (sd, ROS_IP_LINKED, rox, roi);
373: }
374: if (debug)
375: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
376: sd, ryo -> ryo_name);
377:
378: str = qb2str (arg);
379: result = doexec (str);
380: free (str);
381:
382: if (result == NOTOK)
383: return syserror (sd, error_Idist_execError, rox, roi);
384:
385: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi)
386: == NOTOK)
387: ros_adios (&roi -> roi_preject, "RESULT");
388:
389: free_Idist_IA5List (ia5list);
390: ia5list = NULL;
391:
392: return OK;
393: }
394:
395: op_deletefile (sd, ryo, rox, in, roi)
396: int sd;
397: struct RyOperation *ryo;
398: struct RoSAPinvoke *rox;
399: caddr_t in;
400: struct RoSAPindication *roi;
401: {
402: register struct type_UNIV_IA5String *arg =
403: (struct type_UNIV_IA5String *) in;
404: int result;
405: char *str;
406: char buf[BUFSIZ];
407:
408: if (rox -> rox_nolinked == 0) {
409: advise (LLOG_NOTICE, NULLCP,
410: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
411: sd, ryo -> ryo_name, rox -> rox_linkid);
412: return ureject (sd, ROS_IP_LINKED, rox, roi);
413: }
414: if (debug)
415: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
416: sd, ryo -> ryo_name);
417:
418: str = qb2str (arg);
419: (void) sprintf (buf, "%s/%s", target, str);
420: free (str);
421: result = remove (buf);
422:
423: if (result == NOTOK)
424: return error (sd, error_Idist_badfilename, (caddr_t) ia5list,
425: rox, roi);
426:
427: if (RyDsResult (sd, rox -> rox_id, (caddr_t) ia5list, ROS_NOPRIO, roi)
428: == NOTOK)
429: ros_adios (&roi -> roi_preject, "RESULT");
430:
431: free_Idist_IA5List (ia5list);
432: ia5list = NULL;
433: return OK;
434: }
435:
436: /* ARGSUSED */
437: op_listcdir (sd, ryo, rox, in, roi)
438: int sd;
439: struct RyOperation *ryo;
440: struct RoSAPinvoke *rox;
441: caddr_t in;
442: struct RoSAPindication *roi;
443: {
444: struct type_Idist_FileList *fl;
445:
446: if (rox -> rox_nolinked == 0) {
447: advise (LLOG_NOTICE, NULLCP,
448: "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
449: sd, ryo -> ryo_name, rox -> rox_linkid);
450: return ureject (sd, ROS_IP_LINKED, rox, roi);
451: }
452: if (debug)
453: advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s",
454: sd, ryo -> ryo_name);
455:
456: fl = do_listcdir ();
457:
458: if (RyDsResult (sd, rox -> rox_id, (caddr_t) fl, ROS_NOPRIO, roi)
459: == NOTOK)
460: ros_adios (&roi -> roi_preject, "RESULT");
461:
462: free_Idist_FileList (fl);
463:
464: return OK;
465: }
466:
467:
468: /* ERROR */
469:
470: static int error (sd, err, param, rox, roi)
471: int sd,
472: err;
473: caddr_t param;
474: struct RoSAPinvoke *rox;
475: struct RoSAPindication *roi;
476: {
477: if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK)
478: ros_adios (&roi -> roi_preject, "ERROR");
479:
480: if (ia5list)
481: free_Idist_IA5List (ia5list);
482: ia5list = NULL;
483:
484: return OK;
485: }
486:
487: static int strerror (sd, err, str, rox, roi)
488: int sd, err;
489: char *str;
490: struct RoSAPinvoke *rox;
491: struct RoSAPindication *roi;
492: {
493: addtoia5 (str, strlen(str));
494:
495: return error (sd, err, (caddr_t)ia5list, rox, roi);
496: }
497:
498: static int syserror (sd, err, rox, roi)
499: int sd, err;
500: struct RoSAPinvoke *rox;
501: struct RoSAPindication *roi;
502: {
503: extern int errno;
504:
505: return strerror (sd, err, sys_errname (errno), rox, roi);
506: }
507:
508:
509: /* U-REJECT */
510:
511: static int ureject (sd, reason, rox, roi)
512: int sd,
513: reason;
514: struct RoSAPinvoke *rox;
515: struct RoSAPindication *roi;
516: {
517: if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK)
518: ros_adios (&roi -> roi_preject, "U-REJECT");
519:
520: return OK;
521: }
522:
523: /* Initialisation stuff */
524:
525: /* ARGSUSED */
526: initiate (sd, acs, pe)
527: int sd;
528: struct AcSAPstart *acs;
529: PE *pe;
530: {
531: struct type_Idist_Initiate *initial;
532: char *cp, *crypt ();
533:
534: *pe = NULLPE;
535: if ( acs -> acs_ninfo != 1)
536: return init_lose (ACS_PERMANENT, pe, "No Association data");
537:
538: if (decode_Idist_Initiate (acs -> acs_info[0], 1, NULLIP, NULLVP,
539: &initial) == NOTOK)
540: return init_lose (ACS_PERMANENT, pe,
541: "Can't parse initial data");
542:
543: if (initial -> version != VERSION)
544: return init_lose (ACS_PERMANENT, pe, "Version mismatch");
545:
546: cp = qb2str (initial -> user);
547: (void) strcpy (user, cp);
548: free (cp);
549:
550: if (baduser (NULLCP, user)) {
551: advise (LLOG_EXCEPTIONS, NULLCP, "Bad listed user '%s'", user);
552: return init_lose (ACS_PERMANENT, pe, "Bad user/password");
553: }
554:
555: if ((pw = getpwnam (user)) == NULL) {
556: advise (LLOG_NOTICE, NULLCP, "Unknown user '%s'", user);
557: return init_lose (ACS_PERMANENT, pe, "Bad user/password");
558:
559: }
560:
561: userid = pw -> pw_uid;
562: groupid = pw -> pw_gid;
563: (void) strcpy (homedir, pw -> pw_dir);
564:
565: cp = qb2str (initial -> passwd);
566:
567: if (pw -> pw_passwd == NULL
568: || strcmp (crypt (cp, pw -> pw_passwd), pw -> pw_passwd) != 0) {
569: advise (LLOG_NOTICE, NULLCP, "Password mismatch for %s", user);
570: return init_lose (ACS_PERMANENT, pe, "Bad user/password");
571:
572: }
573: bzero (cp, strlen(cp)); /* in case of cores */
574: free (cp);
575:
576: free_Idist_Initiate (initial);
577:
578: if (chdir (homedir) == -1) {
579: advise (LLOG_NOTICE, NULLCP, "Can't set home directory to '%s'",
580: homedir);
581: return init_lose (ACS_PERMANENT, pe, "No home directory");
582: }
583:
584: if (setreuid (userid, userid) < 0) {
585: advise (LLOG_NOTICE, NULLCP, "Cant set userid %d for %s",
586: userid, user);
587: return init_lose (ACS_PERMANENT, pe, "Can't set user id");
588: }
589:
590: (void) mktemp (utmpfile);
591:
592: return ACS_ACCEPT;
593: }
594:
595: init_lose (type, pe, str)
596: int type;
597: PE *pe;
598: char *str;
599: {
600: *pe = ia5s2prim (str, strlen(str));
601: (*pe) -> pe_context = 3; /* magic!! - don't ask me why */
602: return type;
603: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.