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