|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Rick Macklem at The University of Guelph. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted provided ! 9: * that: (1) source distributions retain this entire copyright notice and ! 10: * comment, and (2) distributions including binaries display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * University of California, Berkeley and its contributors'' in the ! 13: * documentation or other materials provided with the distribution and in ! 14: * all advertising materials mentioning features or use of this software. ! 15: * Neither the name of the University nor the names of its contributors may ! 16: * be used to endorse or promote products derived from this software without ! 17: * specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 19: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 20: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1989 Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif not lint ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)mountd.c 5.11 (Berkeley) 6/29/90"; ! 31: #endif not lint ! 32: ! 33: #include <sys/param.h> ! 34: #include <sys/ioctl.h> ! 35: #include <sys/stat.h> ! 36: #include <sys/file.h> ! 37: #include <sys/mount.h> ! 38: #include <sys/socket.h> ! 39: #include <sys/errno.h> ! 40: #include <sys/signal.h> ! 41: #include <stdio.h> ! 42: #include <string.h> ! 43: #include <syslog.h> ! 44: #include <netdb.h> ! 45: #include <rpc/rpc.h> ! 46: #include <rpc/pmap_clnt.h> ! 47: #include <rpc/pmap_prot.h> ! 48: #include <nfs/rpcv2.h> ! 49: #include <nfs/nfsv2.h> ! 50: #include "pathnames.h" ! 51: ! 52: struct ufid { ! 53: u_short ufid_len; ! 54: ino_t ufid_ino; ! 55: long ufid_gen; ! 56: }; ! 57: /* ! 58: * Structures for keeping the mount list and export list ! 59: */ ! 60: struct mountlist { ! 61: struct mountlist *ml_next; ! 62: char ml_host[RPCMNT_NAMELEN+1]; ! 63: char ml_dirp[RPCMNT_PATHLEN+1]; ! 64: }; ! 65: ! 66: struct exportlist { ! 67: struct exportlist *ex_next; ! 68: struct exportlist *ex_prev; ! 69: struct grouplist *ex_groups; ! 70: int ex_rootuid; ! 71: int ex_exflags; ! 72: dev_t ex_dev; ! 73: char ex_dirp[RPCMNT_PATHLEN+1]; ! 74: }; ! 75: ! 76: struct grouplist { ! 77: struct grouplist *gr_next; ! 78: struct hostent *gr_hp; ! 79: }; ! 80: ! 81: /* Global defs */ ! 82: int xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist(); ! 83: int mntsrv(), get_exportlist(), send_umntall(), umntall_each(); ! 84: void get_mountlist(), add_mlist(), del_mlist(); ! 85: struct exportlist exphead; ! 86: struct mountlist *mlhead; ! 87: char exname[MAXPATHLEN]; ! 88: int def_rootuid = -2; ! 89: int root_only = 1; ! 90: extern int errno; ! 91: #ifdef DEBUG ! 92: int debug = 1; ! 93: #else ! 94: int debug = 0; ! 95: #endif ! 96: ! 97: /* ! 98: * Mountd server for NFS mount protocol as described in: ! 99: * NFS: Network File System Protocol Specification, RFC1094, Appendix A ! 100: * The optional arguments are the exports file name ! 101: * default: _PATH_EXPORTS ! 102: * and "-n" to allow nonroot mount. ! 103: */ ! 104: main(argc, argv) ! 105: int argc; ! 106: char **argv; ! 107: { ! 108: SVCXPRT *transp; ! 109: int c; ! 110: extern int optind; ! 111: extern char *optarg; ! 112: ! 113: while ((c = getopt(argc, argv, "n")) != EOF) ! 114: switch (c) { ! 115: case 'n': ! 116: root_only = 0; ! 117: break; ! 118: default: ! 119: fprintf(stderr, "Usage: mountd [-n] [export_file]\n"); ! 120: exit(1); ! 121: }; ! 122: argc -= optind; ! 123: argv += optind; ! 124: exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; ! 125: mlhead = (struct mountlist *)0; ! 126: if (argc == 1) { ! 127: strncpy(exname, *argv, MAXPATHLEN-1); ! 128: exname[MAXPATHLEN-1] = '\0'; ! 129: } else ! 130: strcpy(exname, _PATH_EXPORTS); ! 131: openlog("mountd:", LOG_PID, LOG_DAEMON); ! 132: get_exportlist(); ! 133: get_mountlist(); ! 134: if (debug == 0) { ! 135: daemon(0, 0); ! 136: signal(SIGINT, SIG_IGN); ! 137: signal(SIGQUIT, SIG_IGN); ! 138: } ! 139: signal(SIGHUP, get_exportlist); ! 140: signal(SIGTERM, send_umntall); ! 141: { FILE *pidfile = fopen(_PATH_MOUNTDPID, "w"); ! 142: if (pidfile != NULL) { ! 143: fprintf(pidfile, "%d\n", getpid()); ! 144: fclose(pidfile); ! 145: } ! 146: } ! 147: if ((transp = svcudp_create(RPC_ANYSOCK)) == NULL) { ! 148: syslog(LOG_ERR, "Can't create socket"); ! 149: exit(1); ! 150: } ! 151: pmap_unset(RPCPROG_MNT, RPCMNT_VER1); ! 152: if (!svc_register(transp, RPCPROG_MNT, RPCMNT_VER1, mntsrv, IPPROTO_UDP)) { ! 153: syslog(LOG_ERR, "Can't register mount"); ! 154: exit(1); ! 155: } ! 156: svc_run(); ! 157: syslog(LOG_ERR, "Mountd died"); ! 158: exit(1); ! 159: } ! 160: ! 161: /* ! 162: * The mount rpc service ! 163: */ ! 164: mntsrv(rqstp, transp) ! 165: register struct svc_req *rqstp; ! 166: register SVCXPRT *transp; ! 167: { ! 168: register struct grouplist *grp; ! 169: register u_long **addrp; ! 170: register struct exportlist *ep; ! 171: nfsv2fh_t nfh; ! 172: struct authunix_parms *ucr; ! 173: struct stat stb; ! 174: struct hostent *hp; ! 175: u_long saddr; ! 176: char dirpath[RPCMNT_PATHLEN+1]; ! 177: int bad = ENOENT; ! 178: int omask; ! 179: uid_t uid = -2; ! 180: ! 181: /* Get authorization */ ! 182: switch (rqstp->rq_cred.oa_flavor) { ! 183: case AUTH_UNIX: ! 184: ucr = (struct authunix_parms *)rqstp->rq_clntcred; ! 185: uid = ucr->aup_uid; ! 186: break; ! 187: case AUTH_NULL: ! 188: default: ! 189: break; ! 190: } ! 191: ! 192: saddr = transp->xp_raddr.sin_addr.s_addr; ! 193: hp = (struct hostent *)0; ! 194: switch (rqstp->rq_proc) { ! 195: case NULLPROC: ! 196: if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) ! 197: syslog(LOG_ERR, "Can't send reply"); ! 198: return; ! 199: case RPCMNT_MOUNT: ! 200: if (uid != 0 && root_only) { ! 201: svcerr_weakauth(transp); ! 202: return; ! 203: } ! 204: if (!svc_getargs(transp, xdr_dir, dirpath)) { ! 205: svcerr_decode(transp); ! 206: return; ! 207: } ! 208: ! 209: /* Check to see if it's a valid dirpath */ ! 210: if (stat(dirpath, &stb) < 0 || (stb.st_mode&S_IFMT) != ! 211: S_IFDIR) { ! 212: if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) ! 213: syslog(LOG_ERR, "Can't send reply"); ! 214: return; ! 215: } ! 216: ! 217: /* Check in the exports list */ ! 218: omask = sigblock(sigmask(SIGHUP)); ! 219: ep = exphead.ex_next; ! 220: while (ep != NULL) { ! 221: if (!strcmp(ep->ex_dirp, dirpath)) { ! 222: grp = ep->ex_groups; ! 223: if (grp == NULL) ! 224: break; ! 225: ! 226: /* Check for a host match */ ! 227: addrp = (u_long **)grp->gr_hp->h_addr_list; ! 228: for (;;) { ! 229: if (**addrp == saddr) ! 230: break; ! 231: if (*++addrp == NULL) ! 232: if (grp = grp->gr_next) { ! 233: addrp = (u_long **) ! 234: grp->gr_hp->h_addr_list; ! 235: } else { ! 236: bad = EACCES; ! 237: if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) ! 238: syslog(LOG_ERR, "Can't send reply"); ! 239: sigsetmask(omask); ! 240: return; ! 241: } ! 242: } ! 243: hp = grp->gr_hp; ! 244: break; ! 245: } ! 246: ep = ep->ex_next; ! 247: } ! 248: sigsetmask(omask); ! 249: if (ep == NULL) { ! 250: bad = EACCES; ! 251: if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) ! 252: syslog(LOG_ERR, "Can't send reply"); ! 253: return; ! 254: } ! 255: ! 256: /* Get the file handle */ ! 257: bzero((caddr_t)&nfh, sizeof(nfh)); ! 258: if (getfh(dirpath, (fhandle_t *)&nfh) < 0) { ! 259: bad = errno; ! 260: if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) ! 261: syslog(LOG_ERR, "Can't send reply"); ! 262: return; ! 263: } ! 264: if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&nfh)) ! 265: syslog(LOG_ERR, "Can't send reply"); ! 266: if (hp == NULL) ! 267: hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); ! 268: if (hp) ! 269: add_mlist(hp->h_name, dirpath); ! 270: return; ! 271: case RPCMNT_DUMP: ! 272: if (!svc_sendreply(transp, xdr_mlist, (caddr_t)0)) ! 273: syslog(LOG_ERR, "Can't send reply"); ! 274: return; ! 275: case RPCMNT_UMOUNT: ! 276: if (uid != 0 && root_only) { ! 277: svcerr_weakauth(transp); ! 278: return; ! 279: } ! 280: if (!svc_getargs(transp, xdr_dir, dirpath)) { ! 281: svcerr_decode(transp); ! 282: return; ! 283: } ! 284: if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) ! 285: syslog(LOG_ERR, "Can't send reply"); ! 286: hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); ! 287: if (hp) ! 288: del_mlist(hp->h_name, dirpath); ! 289: return; ! 290: case RPCMNT_UMNTALL: ! 291: if (uid != 0 && root_only) { ! 292: svcerr_weakauth(transp); ! 293: return; ! 294: } ! 295: if (!svc_sendreply(transp, xdr_void, (caddr_t)0)) ! 296: syslog(LOG_ERR, "Can't send reply"); ! 297: hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); ! 298: if (hp) ! 299: del_mlist(hp->h_name, (char *)0); ! 300: return; ! 301: case RPCMNT_EXPORT: ! 302: if (!svc_sendreply(transp, xdr_explist, (caddr_t)0)) ! 303: syslog(LOG_ERR, "Can't send reply"); ! 304: return; ! 305: default: ! 306: svcerr_noproc(transp); ! 307: return; ! 308: } ! 309: } ! 310: ! 311: /* ! 312: * Xdr conversion for a dirpath string ! 313: */ ! 314: xdr_dir(xdrsp, dirp) ! 315: XDR *xdrsp; ! 316: char *dirp; ! 317: { ! 318: return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); ! 319: } ! 320: ! 321: /* ! 322: * Xdr routine to generate fhstatus ! 323: */ ! 324: xdr_fhs(xdrsp, nfh) ! 325: XDR *xdrsp; ! 326: nfsv2fh_t *nfh; ! 327: { ! 328: int ok = 0; ! 329: ! 330: if (!xdr_long(xdrsp, &ok)) ! 331: return (0); ! 332: return (xdr_opaque(xdrsp, (caddr_t)nfh, NFSX_FH)); ! 333: } ! 334: ! 335: xdr_mlist(xdrsp, cp) ! 336: XDR *xdrsp; ! 337: caddr_t cp; ! 338: { ! 339: register struct mountlist *mlp; ! 340: int true = 1; ! 341: int false = 0; ! 342: char *strp; ! 343: ! 344: mlp = mlhead; ! 345: while (mlp) { ! 346: if (!xdr_bool(xdrsp, &true)) ! 347: return (0); ! 348: strp = &mlp->ml_host[0]; ! 349: if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) ! 350: return (0); ! 351: strp = &mlp->ml_dirp[0]; ! 352: if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) ! 353: return (0); ! 354: mlp = mlp->ml_next; ! 355: } ! 356: if (!xdr_bool(xdrsp, &false)) ! 357: return (0); ! 358: return (1); ! 359: } ! 360: ! 361: /* ! 362: * Xdr conversion for export list ! 363: */ ! 364: xdr_explist(xdrsp, cp) ! 365: XDR *xdrsp; ! 366: caddr_t cp; ! 367: { ! 368: register struct exportlist *ep; ! 369: register struct grouplist *grp; ! 370: int true = 1; ! 371: int false = 0; ! 372: char *strp; ! 373: int omask; ! 374: ! 375: omask = sigblock(sigmask(SIGHUP)); ! 376: ep = exphead.ex_next; ! 377: while (ep != NULL) { ! 378: if (!xdr_bool(xdrsp, &true)) ! 379: goto errout; ! 380: strp = &ep->ex_dirp[0]; ! 381: if (!xdr_string(xdrsp, &strp, RPCMNT_PATHLEN)) ! 382: goto errout; ! 383: grp = ep->ex_groups; ! 384: while (grp != NULL) { ! 385: if (!xdr_bool(xdrsp, &true)) ! 386: goto errout; ! 387: strp = grp->gr_hp->h_name; ! 388: if (!xdr_string(xdrsp, &strp, RPCMNT_NAMELEN)) ! 389: goto errout; ! 390: grp = grp->gr_next; ! 391: } ! 392: if (!xdr_bool(xdrsp, &false)) ! 393: goto errout; ! 394: ep = ep->ex_next; ! 395: } ! 396: sigsetmask(omask); ! 397: if (!xdr_bool(xdrsp, &false)) ! 398: return (0); ! 399: return (1); ! 400: errout: ! 401: sigsetmask(omask); ! 402: return (0); ! 403: } ! 404: ! 405: #define LINESIZ 10240 ! 406: char line[LINESIZ]; ! 407: ! 408: /* ! 409: * Get the export list ! 410: */ ! 411: get_exportlist() ! 412: { ! 413: register struct hostent *hp, *nhp; ! 414: register char **addrp, **naddrp; ! 415: register int i; ! 416: register struct grouplist *grp; ! 417: register struct exportlist *ep, *ep2; ! 418: struct ufs_args args; ! 419: struct stat sb; ! 420: FILE *inf; ! 421: char *cp, *endcp; ! 422: char savedc; ! 423: int len, dirplen; ! 424: int rootuid, exflags; ! 425: u_long saddr; ! 426: struct exportlist *fep; ! 427: ! 428: /* ! 429: * First, get rid of the old list ! 430: */ ! 431: ep = exphead.ex_next; ! 432: while (ep != NULL) { ! 433: ep2 = ep; ! 434: ep = ep->ex_next; ! 435: free_exp(ep2); ! 436: } ! 437: ! 438: /* ! 439: * Read in the exports file and build the list, calling ! 440: * exportfs() as we go along ! 441: */ ! 442: exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; ! 443: if ((inf = fopen(exname, "r")) == NULL) { ! 444: syslog(LOG_ERR, "Can't open %s", exname); ! 445: exit(2); ! 446: } ! 447: while (fgets(line, LINESIZ, inf)) { ! 448: exflags = MNT_EXPORTED; ! 449: rootuid = def_rootuid; ! 450: cp = line; ! 451: nextfield(&cp, &endcp); ! 452: ! 453: /* ! 454: * Get file system devno and see if an entry for this ! 455: * file system already exists. ! 456: */ ! 457: savedc = *endcp; ! 458: *endcp = '\0'; ! 459: if (stat(cp, &sb) < 0 || (sb.st_mode & S_IFMT) != S_IFDIR) ! 460: goto err; ! 461: fep = (struct exportlist *)0; ! 462: ep = exphead.ex_next; ! 463: while (ep) { ! 464: if (ep->ex_dev == sb.st_dev) { ! 465: fep = ep; ! 466: break; ! 467: } ! 468: ep = ep->ex_next; ! 469: } ! 470: *endcp = savedc; ! 471: ! 472: /* ! 473: * Create new exports list entry ! 474: */ ! 475: len = endcp-cp; ! 476: if (len <= RPCMNT_PATHLEN && len > 0) { ! 477: ep = (struct exportlist *)malloc(sizeof(*ep)); ! 478: ep->ex_next = ep->ex_prev = (struct exportlist *)0; ! 479: ep->ex_groups = (struct grouplist *)0; ! 480: bcopy(cp, ep->ex_dirp, len); ! 481: ep->ex_dirp[len] = '\0'; ! 482: dirplen = len; ! 483: } else ! 484: goto err; ! 485: cp = endcp; ! 486: nextfield(&cp, &endcp); ! 487: len = endcp-cp; ! 488: while (len > 0) { ! 489: savedc = *endcp; ! 490: *endcp = '\0'; ! 491: if (len <= RPCMNT_NAMELEN) { ! 492: if (*cp == '-') { ! 493: do_opt(cp+1, fep, ep, &exflags, &rootuid); ! 494: } else { ! 495: if (isdigit(*cp)) { ! 496: saddr = inet_addr(cp); ! 497: if (saddr == -1 || ! 498: (hp = gethostbyaddr((caddr_t)&saddr, ! 499: sizeof(saddr), AF_INET)) == NULL) ! 500: goto err; ! 501: } else if ((hp = gethostbyname(cp)) == NULL) ! 502: goto err; ! 503: grp = (struct grouplist *) ! 504: malloc(sizeof(struct grouplist)); ! 505: if (grp == NULL) ! 506: goto err; ! 507: nhp = grp->gr_hp = (struct hostent *) ! 508: malloc(sizeof(struct hostent)); ! 509: if (nhp == NULL) ! 510: goto err; ! 511: bcopy((caddr_t)hp, (caddr_t)nhp, ! 512: sizeof(struct hostent)); ! 513: i = strlen(hp->h_name)+1; ! 514: nhp->h_name = (char *)malloc(i); ! 515: if (nhp->h_name == NULL) ! 516: goto err; ! 517: bcopy(hp->h_name, nhp->h_name, i); ! 518: addrp = hp->h_addr_list; ! 519: i = 1; ! 520: while (*addrp++) ! 521: i++; ! 522: naddrp = nhp->h_addr_list = (char **) ! 523: malloc(i*sizeof(char *)); ! 524: if (naddrp == NULL) ! 525: goto err; ! 526: addrp = hp->h_addr_list; ! 527: while (*addrp) { ! 528: *naddrp = (char *) ! 529: malloc(hp->h_length); ! 530: if (*naddrp == NULL) ! 531: goto err; ! 532: bcopy(*addrp, *naddrp, ! 533: hp->h_length); ! 534: addrp++; ! 535: naddrp++; ! 536: } ! 537: *naddrp = (char *)0; ! 538: grp->gr_next = ep->ex_groups; ! 539: ep->ex_groups = grp; ! 540: } ! 541: } ! 542: cp = endcp; ! 543: *cp = savedc; ! 544: nextfield(&cp, &endcp); ! 545: len = endcp-cp; ! 546: } ! 547: if (fep == NULL) { ! 548: args.fspec = 0; ! 549: args.exflags = exflags; ! 550: args.exroot = rootuid; ! 551: cp = (char *)0; ! 552: while (mount(MOUNT_UFS, ep->ex_dirp, MNT_UPDATE, &args) < 0) { ! 553: if (cp == NULL) ! 554: cp = ep->ex_dirp + dirplen - 1; ! 555: else ! 556: *cp = savedc; ! 557: /* back up over the last component */ ! 558: while (*cp == '/' && cp > ep->ex_dirp) ! 559: cp--; ! 560: while (*(cp - 1) != '/' && cp > ep->ex_dirp) ! 561: cp--; ! 562: if (cp == ep->ex_dirp) { ! 563: syslog(LOG_WARNING, ! 564: "Can't export %s", ep->ex_dirp); ! 565: free_exp(ep); ! 566: goto nextline; ! 567: } ! 568: savedc = *cp; ! 569: *cp = '\0'; ! 570: } ! 571: if (cp) ! 572: *cp = savedc; ! 573: ep->ex_rootuid = rootuid; ! 574: ep->ex_exflags = exflags; ! 575: } else { ! 576: ep->ex_rootuid = fep->ex_rootuid; ! 577: ep->ex_exflags = fep->ex_exflags; ! 578: } ! 579: ep->ex_dev = sb.st_dev; ! 580: ep->ex_next = exphead.ex_next; ! 581: ep->ex_prev = &exphead; ! 582: if (ep->ex_next != NULL) ! 583: ep->ex_next->ex_prev = ep; ! 584: exphead.ex_next = ep; ! 585: nextline: ! 586: ; ! 587: } ! 588: fclose(inf); ! 589: return; ! 590: err: ! 591: syslog(LOG_ERR, "Bad Exports File, mountd Failed"); ! 592: exit(2); ! 593: } ! 594: ! 595: /* ! 596: * Parse out the next white space separated field ! 597: */ ! 598: nextfield(cp, endcp) ! 599: char **cp; ! 600: char **endcp; ! 601: { ! 602: register char *p; ! 603: ! 604: p = *cp; ! 605: while (*p == ' ' || *p == '\t') ! 606: p++; ! 607: if (*p == '\n' || *p == '\0') { ! 608: *cp = *endcp = p; ! 609: return; ! 610: } ! 611: *cp = p++; ! 612: while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') ! 613: p++; ! 614: *endcp = p; ! 615: } ! 616: ! 617: /* ! 618: * Parse the option string ! 619: */ ! 620: do_opt(cpopt, fep, ep, exflagsp, rootuidp) ! 621: register char *cpopt; ! 622: struct exportlist *fep, *ep; ! 623: int *exflagsp, *rootuidp; ! 624: { ! 625: register char *cpoptarg, *cpoptend; ! 626: ! 627: while (cpopt && *cpopt) { ! 628: if (cpoptend = index(cpopt, ',')) ! 629: *cpoptend++ = '\0'; ! 630: if (cpoptarg = index(cpopt, '=')) ! 631: *cpoptarg++ = '\0'; ! 632: if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) { ! 633: if (fep && (fep->ex_exflags & MNT_EXRDONLY) == 0) ! 634: syslog(LOG_WARNING, "ro failed for %s", ! 635: ep->ex_dirp); ! 636: else ! 637: *exflagsp |= MNT_EXRDONLY; ! 638: } else if (!strcmp(cpopt, "root") || !strcmp(cpopt, "r")) { ! 639: if (cpoptarg && isdigit(*cpoptarg)) { ! 640: *rootuidp = atoi(cpoptarg); ! 641: if (fep && fep->ex_rootuid != *rootuidp) ! 642: syslog(LOG_WARNING, ! 643: "uid failed for %s", ! 644: ep->ex_dirp); ! 645: } else ! 646: syslog(LOG_WARNING, ! 647: "uid failed for %s", ! 648: ep->ex_dirp); ! 649: } else ! 650: syslog(LOG_WARNING, "opt %s ignored for %s", cpopt, ! 651: ep->ex_dirp); ! 652: cpopt = cpoptend; ! 653: } ! 654: } ! 655: ! 656: #define STRSIZ (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50) ! 657: /* ! 658: * Routines that maintain the remote mounttab ! 659: */ ! 660: void get_mountlist() ! 661: { ! 662: register struct mountlist *mlp, **mlpp; ! 663: register char *eos, *dirp; ! 664: int len; ! 665: char str[STRSIZ]; ! 666: FILE *mlfile; ! 667: ! 668: if (((mlfile = fopen(_PATH_RMOUNTLIST, "r")) == NULL) && ! 669: ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL)) { ! 670: syslog(LOG_WARNING, "Can't open %s", _PATH_RMOUNTLIST); ! 671: return; ! 672: } ! 673: mlpp = &mlhead; ! 674: while (fgets(str, STRSIZ, mlfile) != NULL) { ! 675: if ((dirp = index(str, '\t')) == NULL && ! 676: (dirp = index(str, ' ')) == NULL) ! 677: continue; ! 678: mlp = (struct mountlist *)malloc(sizeof (*mlp)); ! 679: len = dirp-str; ! 680: if (len > RPCMNT_NAMELEN) ! 681: len = RPCMNT_NAMELEN; ! 682: bcopy(str, mlp->ml_host, len); ! 683: mlp->ml_host[len] = '\0'; ! 684: while (*dirp == '\t' || *dirp == ' ') ! 685: dirp++; ! 686: if ((eos = index(dirp, '\t')) == NULL && ! 687: (eos = index(dirp, ' ')) == NULL && ! 688: (eos = index(dirp, '\n')) == NULL) ! 689: len = strlen(dirp); ! 690: else ! 691: len = eos-dirp; ! 692: if (len > RPCMNT_PATHLEN) ! 693: len = RPCMNT_PATHLEN; ! 694: bcopy(dirp, mlp->ml_dirp, len); ! 695: mlp->ml_dirp[len] = '\0'; ! 696: mlp->ml_next = (struct mountlist *)0; ! 697: *mlpp = mlp; ! 698: mlpp = &mlp->ml_next; ! 699: } ! 700: fclose(mlfile); ! 701: } ! 702: ! 703: void del_mlist(hostp, dirp) ! 704: register char *hostp, *dirp; ! 705: { ! 706: register struct mountlist *mlp, **mlpp; ! 707: FILE *mlfile; ! 708: int fnd = 0; ! 709: ! 710: mlpp = &mlhead; ! 711: mlp = mlhead; ! 712: while (mlp) { ! 713: if (!strcmp(mlp->ml_host, hostp) && ! 714: (!dirp || !strcmp(mlp->ml_dirp, dirp))) { ! 715: fnd = 1; ! 716: *mlpp = mlp->ml_next; ! 717: free((caddr_t)mlp); ! 718: } ! 719: mlpp = &mlp->ml_next; ! 720: mlp = mlp->ml_next; ! 721: } ! 722: if (fnd) { ! 723: if ((mlfile = fopen(_PATH_RMOUNTLIST, "w")) == NULL) { ! 724: syslog(LOG_WARNING, "Can't update %s", _PATH_RMOUNTLIST); ! 725: return; ! 726: } ! 727: mlp = mlhead; ! 728: while (mlp) { ! 729: fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp); ! 730: mlp = mlp->ml_next; ! 731: } ! 732: fclose(mlfile); ! 733: } ! 734: } ! 735: ! 736: void add_mlist(hostp, dirp) ! 737: register char *hostp, *dirp; ! 738: { ! 739: register struct mountlist *mlp, **mlpp; ! 740: FILE *mlfile; ! 741: ! 742: mlpp = &mlhead; ! 743: mlp = mlhead; ! 744: while (mlp) { ! 745: if (!strcmp(mlp->ml_host, hostp) && !strcmp(mlp->ml_dirp, dirp)) ! 746: return; ! 747: mlpp = &mlp->ml_next; ! 748: mlp = mlp->ml_next; ! 749: } ! 750: mlp = (struct mountlist *)malloc(sizeof (*mlp)); ! 751: strncpy(mlp->ml_host, hostp, RPCMNT_NAMELEN); ! 752: mlp->ml_host[RPCMNT_NAMELEN] = '\0'; ! 753: strncpy(mlp->ml_dirp, dirp, RPCMNT_PATHLEN); ! 754: mlp->ml_dirp[RPCMNT_PATHLEN] = '\0'; ! 755: mlp->ml_next = (struct mountlist *)0; ! 756: *mlpp = mlp; ! 757: if ((mlfile = fopen(_PATH_RMOUNTLIST, "a")) == NULL) { ! 758: syslog(LOG_WARNING, "Can't update %s", _PATH_RMOUNTLIST); ! 759: return; ! 760: } ! 761: fprintf(mlfile, "%s %s\n", mlp->ml_host, mlp->ml_dirp); ! 762: fclose(mlfile); ! 763: } ! 764: ! 765: /* ! 766: * This function is called via. SIGTERM when the system is going down. ! 767: * It sends a broadcast RPCMNT_UMNTALL. ! 768: */ ! 769: send_umntall() ! 770: { ! 771: (void) clnt_broadcast(RPCPROG_MNT, RPCMNT_VER1, RPCMNT_UMNTALL, ! 772: xdr_void, (caddr_t)0, xdr_void, (caddr_t)0, umntall_each); ! 773: exit(); ! 774: } ! 775: ! 776: umntall_each(resultsp, raddr) ! 777: caddr_t resultsp; ! 778: struct sockaddr_in *raddr; ! 779: { ! 780: return (1); ! 781: } ! 782: ! 783: /* ! 784: * Free up an exports list component ! 785: */ ! 786: free_exp(ep) ! 787: register struct exportlist *ep; ! 788: { ! 789: register struct grouplist *grp; ! 790: register char **addrp; ! 791: struct grouplist *grp2; ! 792: ! 793: grp = ep->ex_groups; ! 794: while (grp != NULL) { ! 795: addrp = grp->gr_hp->h_addr_list; ! 796: while (*addrp) ! 797: free(*addrp++); ! 798: free((caddr_t)grp->gr_hp->h_addr_list); ! 799: free(grp->gr_hp->h_name); ! 800: free((caddr_t)grp->gr_hp); ! 801: grp2 = grp; ! 802: grp = grp->gr_next; ! 803: free((caddr_t)grp2); ! 804: } ! 805: free((caddr_t)ep); ! 806: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.