home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / unfsd / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-05-24  |  46.3 KB

  1. Path: bbn.com!bbn!husc6!mailrus!ames!lll-lcc!pyramid!munnari!bogus-address
  2. From: shand@cad.jmrc.eecs.unsw.oz (Mark Shand)
  3. Newsgroups: comp.sources.unix
  4. Subject: v15i002:  unfsd - user level NFS server, Part02/02
  5. Keywords: nfs sunrpc
  6. Message-ID: <2144@munnari.oz>
  7. Date: 25 May 88 01:12:08 GMT
  8. Sender: kre@munnari.oz
  9. Lines: 2014
  10. Approved: kre@munnari.oz.au
  11.  
  12. Submitted by: shand@cad.jmrc.eecs.unsw.oz (Mark Shand)
  13. Posting-number: Volume 15, Issue 2
  14. Archive-name: unfsd/Part02
  15.  
  16.  
  17.  
  18.  
  19. UNFSD - USER-LEVEL NFS SERVER
  20. =============================
  21.  
  22. This package implements a simple user level NFS server based on the
  23. sunrpc3.9 package that was posted to the net a few months ago.  The
  24. current version only provides read access from the clients.  It has
  25. been tested between a VAX11/780 running 4.3BSD (the server) and several
  26. diskful SUN3/60 running SunOS 3.4 (the clients) and on a diskless
  27. SUN3/50 running SunOS 3.2 remounting its own root at a lower level of
  28. its file hierarchy.
  29.  
  30. #--------------------------------CUT HERE-------------------------------------
  31. #! /bin/sh
  32. #
  33. # This is a shell archive.  Save this into a file, edit it
  34. # and delete all lines above this comment.  Then give this
  35. # file to sh by executing the command "sh file".  The files
  36. # will be extracted into the current directory owned by
  37. # you with default permissions.
  38. #
  39. # The files contained herein are:
  40. #
  41. # -rw-rw-r--  1 shand        7684 May 16 02:24 nfs_prot.x
  42. # -rw-r--r--  1 shand         304 May 16 02:24 ugid.x
  43. # -rw-r--r--  1 shand        6206 May 17 02:25 ugid_map.c
  44. # -rw-r--r--  1 shand         863 May 16 02:23 ugidd.8
  45. # -rw-rw-r--  1 shand        3087 May 17 02:25 ugidd.c
  46. # -rw-r--r--  1 shand        1653 May 17 02:02 unfsd.8
  47. # -rw-r--r--  1 shand       12912 May 17 02:25 unfsd.c
  48. # -rw-r--r--  1 shand        1399 May 17 02:25 unfsd.h
  49. # -rw-r--r--  1 shand        2421 May 16 02:23 unfsd_exports.5
  50. # -rw-rw-r--  1 shand        3616 May 17 02:25 unfsmntd.c
  51. #
  52. echo 'x - nfs_prot.x'
  53. if test -f nfs_prot.x; then echo 'shar: not overwriting nfs_prot.x'; else
  54. sed 's/^X//' << '________This_Is_The_END________' > nfs_prot.x
  55. X/* @(#)nfs_prot.x    1.2 87/11/12 3.9 RPCSRC */
  56. X
  57. X/*
  58. X * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  59. X * unrestricted use provided that this legend is included on all tape
  60. X * media and as a part of the software program in whole or part.  Users
  61. X * may copy or modify Sun RPC without charge, but are not authorized
  62. X * to license or distribute it to anyone else except as part of a product or
  63. X * program developed by the user.
  64. X * 
  65. X * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  66. X * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  67. X * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  68. X * 
  69. X * Sun RPC is provided with no support and without any obligation on the
  70. X * part of Sun Microsystems, Inc. to assist in its use, correction,
  71. X * modification or enhancement.
  72. X * 
  73. X * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  74. X * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  75. X * OR ANY PART THEREOF.
  76. X * 
  77. X * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  78. X * or profits or other special, indirect and consequential damages, even if
  79. X * Sun has been advised of the possibility of such damages.
  80. X * 
  81. X * Sun Microsystems, Inc.
  82. X * 2550 Garcia Avenue
  83. X * Mountain View, California  94043
  84. X */
  85. X
  86. X/*
  87. X * nfs_prot.x 1.2 87/10/12
  88. X * Copyright 1987 Sun Microsystems, Inc.
  89. X */
  90. Xconst NFS_PORT          = 2049;
  91. Xconst NFS_MAXDATA       = 8192;
  92. Xconst NFS_MAXPATHLEN    = 1024;
  93. Xconst NFS_MAXNAMLEN    = 255;
  94. Xconst NFS_FHSIZE    = 32;
  95. Xconst NFS_COOKIESIZE    = 4;
  96. Xconst NFS_FIFO_DEV    = -1;    /* size kludge for named pipes */
  97. X
  98. X/*
  99. X * File types
  100. X */
  101. Xconst NFSMODE_FMT  = 0170000;    /* type of file */
  102. Xconst NFSMODE_DIR  = 0040000;    /* directory */
  103. Xconst NFSMODE_CHR  = 0020000;    /* character special */
  104. Xconst NFSMODE_BLK  = 0060000;    /* block special */
  105. Xconst NFSMODE_REG  = 0100000;    /* regular */
  106. Xconst NFSMODE_LNK  = 0120000;    /* symbolic link */
  107. Xconst NFSMODE_SOCK = 0140000;    /* socket */
  108. Xconst NFSMODE_FIFO = 0010000;    /* fifo */
  109. X
  110. X/*
  111. X * Error status
  112. X */
  113. Xenum nfsstat {
  114. X    NFS_OK= 0,        /* no error */
  115. X    NFSERR_PERM=1,        /* Not owner */
  116. X    NFSERR_NOENT=2,        /* No such file or directory */
  117. X    NFSERR_IO=5,        /* I/O error */
  118. X    NFSERR_NXIO=6,        /* No such device or address */
  119. X    NFSERR_ACCES=13,    /* Permission denied */
  120. X    NFSERR_EXIST=17,    /* File exists */
  121. X    NFSERR_NODEV=19,    /* No such device */
  122. X    NFSERR_NOTDIR=20,    /* Not a directory*/
  123. X    NFSERR_ISDIR=21,    /* Is a directory */
  124. X    NFSERR_FBIG=27,        /* File too large */
  125. X    NFSERR_NOSPC=28,    /* No space left on device */
  126. X    NFSERR_ROFS=30,        /* Read-only file system */
  127. X    NFSERR_NAMETOOLONG=63,    /* File name too long */
  128. X    NFSERR_NOTEMPTY=66,    /* Directory not empty */
  129. X    NFSERR_DQUOT=69,    /* Disc quota exceeded */
  130. X    NFSERR_STALE=70,    /* Stale NFS file handle */
  131. X    NFSERR_WFLUSH=99    /* write cache flushed */
  132. X};
  133. X
  134. X/*
  135. X * File types
  136. X */
  137. Xenum ftype {
  138. X    NFNON = 0,    /* non-file */
  139. X    NFREG = 1,    /* regular file */
  140. X    NFDIR = 2,    /* directory */
  141. X    NFBLK = 3,    /* block special */
  142. X    NFCHR = 4,    /* character special */
  143. X    NFLNK = 5,    /* symbolic link */
  144. X    NFSOCK = 6,    /* unix domain sockets */
  145. X    NFBAD = 7,    /* unused */
  146. X    NFFIFO = 8     /* named pipe */
  147. X};
  148. X
  149. X/*
  150. X * File access handle
  151. X */
  152. Xstruct nfs_fh {
  153. X    opaque data[NFS_FHSIZE];
  154. X};
  155. X
  156. X/* 
  157. X * Timeval
  158. X */
  159. Xstruct nfstime {
  160. X    unsigned seconds;
  161. X    unsigned useconds;
  162. X};
  163. X
  164. X
  165. X/*
  166. X * File attributes
  167. X */
  168. Xstruct fattr {
  169. X    ftype type;        /* file type */
  170. X    unsigned mode;        /* protection mode bits */
  171. X    unsigned nlink;        /* # hard links */
  172. X    unsigned uid;        /* owner user id */
  173. X    unsigned gid;        /* owner group id */
  174. X    unsigned size;        /* file size in bytes */
  175. X    unsigned blocksize;    /* prefered block size */
  176. X    unsigned rdev;        /* special device # */
  177. X    unsigned blocks;    /* Kb of disk used by file */
  178. X    unsigned fsid;        /* device # */
  179. X    unsigned fileid;    /* inode # */
  180. X    nfstime    atime;        /* time of last access */
  181. X    nfstime    mtime;        /* time of last modification */
  182. X    nfstime    ctime;        /* time of last change */
  183. X};
  184. X
  185. X/*
  186. X * File attributes which can be set
  187. X */
  188. Xstruct sattr {
  189. X    unsigned mode;    /* protection mode bits */
  190. X    unsigned uid;    /* owner user id */
  191. X    unsigned gid;    /* owner group id */
  192. X    unsigned size;    /* file size in bytes */
  193. X    nfstime    atime;    /* time of last access */
  194. X    nfstime    mtime;    /* time of last modification */
  195. X};
  196. X
  197. X
  198. Xtypedef string filename<NFS_MAXNAMLEN>; 
  199. Xtypedef string nfspath<NFS_MAXPATHLEN>;
  200. X
  201. X/*
  202. X * Reply status with file attributes
  203. X */
  204. Xunion attrstat switch (nfsstat status) {
  205. Xcase NFS_OK:
  206. X    fattr attributes;
  207. Xdefault:
  208. X    void;
  209. X};
  210. X
  211. Xstruct sattrargs {
  212. X    nfs_fh file;
  213. X    sattr attributes;
  214. X};
  215. X
  216. X/*
  217. X * Arguments for directory operations
  218. X */
  219. Xstruct diropargs {
  220. X    nfs_fh    dir;    /* directory file handle */
  221. X    filename name;        /* name (up to NFS_MAXNAMLEN bytes) */
  222. X};
  223. X
  224. Xstruct diropokres {
  225. X    nfs_fh file;
  226. X    fattr attributes;
  227. X};
  228. X
  229. X/*
  230. X * Results from directory operation
  231. X */
  232. Xunion diropres switch (nfsstat status) {
  233. Xcase NFS_OK:
  234. X    diropokres diropres;
  235. Xdefault:
  236. X    void;
  237. X};
  238. X
  239. Xunion readlinkres switch (nfsstat status) {
  240. Xcase NFS_OK:
  241. X    nfspath data;
  242. Xdefault:
  243. X    void;
  244. X};
  245. X
  246. X/*
  247. X * Arguments to remote read
  248. X */
  249. Xstruct readargs {
  250. X    nfs_fh file;        /* handle for file */
  251. X    unsigned offset;    /* byte offset in file */
  252. X    unsigned count;        /* immediate read count */
  253. X    unsigned totalcount;    /* total read count (from this offset)*/
  254. X};
  255. X
  256. X/*
  257. X * Status OK portion of remote read reply
  258. X */
  259. Xstruct readokres {
  260. X    fattr    attributes;    /* attributes, need for pagin*/
  261. X    opaque data<NFS_MAXDATA>;
  262. X};
  263. X
  264. Xunion readres switch (nfsstat status) {
  265. Xcase NFS_OK:
  266. X    readokres reply;
  267. Xdefault:
  268. X    void;
  269. X};
  270. X
  271. X/*
  272. X * Arguments to remote write 
  273. X */
  274. Xstruct writeargs {
  275. X    nfs_fh    file;        /* handle for file */
  276. X    unsigned beginoffset;    /* beginning byte offset in file */
  277. X    unsigned offset;    /* current byte offset in file */
  278. X    unsigned totalcount;    /* total write count (to this offset)*/
  279. X    opaque data<NFS_MAXDATA>;
  280. X};
  281. X
  282. Xstruct createargs {
  283. X    diropargs where;
  284. X    sattr attributes;
  285. X};
  286. X
  287. Xstruct renameargs {
  288. X    diropargs from;
  289. X    diropargs to;
  290. X};
  291. X
  292. Xstruct linkargs {
  293. X    nfs_fh from;
  294. X    diropargs to;
  295. X};
  296. X
  297. Xstruct symlinkargs {
  298. X    diropargs from;
  299. X    nfspath to;
  300. X    sattr attributes;
  301. X};
  302. X
  303. X
  304. Xtypedef opaque nfscookie[NFS_COOKIESIZE];
  305. X
  306. X/*
  307. X * Arguments to readdir
  308. X */
  309. Xstruct readdirargs {
  310. X    nfs_fh dir;        /* directory handle */
  311. X    nfscookie cookie;
  312. X    unsigned count;        /* number of directory bytes to read */
  313. X};
  314. X
  315. Xstruct entry {
  316. X    unsigned fileid;
  317. X    filename name;
  318. X    nfscookie cookie;
  319. X    entry *nextentry;
  320. X};
  321. X
  322. Xstruct dirlist {
  323. X    entry *entries;
  324. X    bool eof;
  325. X};
  326. X
  327. Xunion readdirres switch (nfsstat status) {
  328. Xcase NFS_OK:
  329. X    dirlist reply;
  330. Xdefault:
  331. X    void;
  332. X};
  333. X
  334. Xstruct statfsokres {
  335. X    unsigned tsize;    /* preferred transfer size in bytes */
  336. X    unsigned bsize;    /* fundamental file system block size */
  337. X    unsigned blocks;    /* total blocks in file system */
  338. X    unsigned bfree;    /* free blocks in fs */
  339. X    unsigned bavail;    /* free blocks avail to non-superuser */
  340. X};
  341. X
  342. Xunion statfsres switch (nfsstat status) {
  343. Xcase NFS_OK:
  344. X    statfsokres reply;
  345. Xdefault:
  346. X    void;
  347. X};
  348. X
  349. X/*
  350. X * Remote file service routines
  351. X */
  352. Xprogram NFS_PROGRAM {
  353. X    version NFS_VERSION {
  354. X        void 
  355. X        NFSPROC_NULL(void) = 0;
  356. X
  357. X        attrstat 
  358. X        NFSPROC_GETATTR(nfs_fh) =    1;
  359. X
  360. X        attrstat 
  361. X        NFSPROC_SETATTR(sattrargs) = 2;
  362. X
  363. X        void 
  364. X        NFSPROC_ROOT(void) = 3;
  365. X
  366. X        diropres 
  367. X        NFSPROC_LOOKUP(diropargs) = 4;
  368. X
  369. X        readlinkres 
  370. X        NFSPROC_READLINK(nfs_fh) = 5;
  371. X
  372. X        readres 
  373. X        NFSPROC_READ(readargs) = 6;
  374. X
  375. X        void 
  376. X        NFSPROC_WRITECACHE(void) = 7;
  377. X
  378. X        attrstat
  379. X        NFSPROC_WRITE(writeargs) = 8;
  380. X
  381. X        diropres
  382. X        NFSPROC_CREATE(createargs) = 9;
  383. X
  384. X        nfsstat
  385. X        NFSPROC_REMOVE(diropargs) = 10;
  386. X
  387. X        nfsstat
  388. X        NFSPROC_RENAME(renameargs) = 11;
  389. X
  390. X        nfsstat
  391. X        NFSPROC_LINK(linkargs) = 12;
  392. X
  393. X        nfsstat
  394. X        NFSPROC_SYMLINK(symlinkargs) = 13;
  395. X
  396. X        diropres
  397. X        NFSPROC_MKDIR(createargs) = 14;
  398. X
  399. X        nfsstat
  400. X        NFSPROC_RMDIR(diropargs) = 15;
  401. X
  402. X        readdirres
  403. X        NFSPROC_READDIR(readdirargs) = 16;
  404. X
  405. X        statfsres
  406. X        NFSPROC_STATFS(nfs_fh) = 17;
  407. X    } = 2;
  408. X} = 100003;
  409. X
  410. ________This_Is_The_END________
  411. if test `wc -l < nfs_prot.x` -ne 355; then
  412.     echo 'shar: nfs_prot.x was damaged during transit (should have been 355 bytes)'
  413. fi
  414. fi        ; : end of overwriting check
  415. echo 'x - ugid.x'
  416. if test -f ugid.x; then echo 'shar: not overwriting ugid.x'; else
  417. sed 's/^X//' << '________This_Is_The_END________' > ugid.x
  418. Xconst MAXUGLEN = 64;
  419. Xconst NOBODY = -2;
  420. Xconst WILDCARD = -1;
  421. Xtypedef string ugname<MAXUGLEN>;
  422. X
  423. Xprogram UGIDPROG {
  424. X    version UGIDVERS {
  425. X    int AUTHENTICATE(int) = 1;
  426. X    int NAME_UID(ugname) = 2;
  427. X    int GROUP_GID(ugname) = 3;
  428. X    ugname UID_NAME(int) = 4; 
  429. X    ugname GID_GROUP(int) = 5; 
  430. X    } = 1;
  431. X} = 0x2084e581;
  432. ________This_Is_The_END________
  433. if test `wc -l < ugid.x` -ne 14; then
  434.     echo 'shar: ugid.x was damaged during transit (should have been 14 bytes)'
  435. fi
  436. fi        ; : end of overwriting check
  437. echo 'x - ugid_map.c'
  438. if test -f ugid_map.c; then echo 'shar: not overwriting ugid_map.c'; else
  439. sed 's/^X//' << '________This_Is_The_END________' > ugid_map.c
  440. X/* UNFSD - copyright Mark A Shand, May 1988.
  441. X * This software maybe be used for any purpose provided
  442. X * the above copyright notice is retained.  It is supplied
  443. X * as is, with no warranty expressed or implied.
  444. X */
  445. X
  446. X#include <pwd.h>
  447. X#include <grp.h>
  448. X#include <fcntl.h>
  449. X#include "unfsd.h"
  450. X
  451. Xtypedef struct mapper {
  452. X    struct in_addr    addr;
  453. X    struct idm {
  454. X        int    *known;
  455. X        int    lim;
  456. X    } uid, gid, rev_uid, rev_gid;
  457. X    struct mapper *next;
  458. X} mapper;
  459. X
  460. Xstatic    mapper    *id_maps = NULL;
  461. X
  462. X#ifdef sun
  463. Xvoid xdr_free() {}
  464. X#endif
  465. X
  466. Xstatic mapper *
  467. Xgetmap(xprt)
  468. XSVCXPRT    *xprt;
  469. X{
  470. X    mapper    **mapp;
  471. X    mapper    *map;
  472. X    struct in_addr    caller;
  473. X    static    mapper mfailed;
  474. X    
  475. X    caller = svc_getcaller(xprt)->sin_addr;
  476. X    for (mapp = &id_maps; *mapp != NULL; mapp = &((*mapp)->next))
  477. X        if ((*mapp)->addr.s_addr == caller.s_addr)
  478. X        {
  479. X            /* move to front */
  480. X            if (*mapp != id_maps)
  481. X            {
  482. X                map = *mapp;
  483. X                *mapp = map->next;
  484. X                map->next = id_maps;
  485. X                id_maps = map;
  486. X            }
  487. X            return id_maps;
  488. X        }
  489. X    if ((map = (mapper *) malloc(sizeof *map)) == NULL)
  490. X        return &mfailed;
  491. X    map->next = id_maps;
  492. X    id_maps = map;
  493. X    map->addr.s_addr = caller.s_addr;
  494. X    map->uid.known = NULL;
  495. X    map->uid.lim = 0;
  496. X    map->gid.known = NULL;
  497. X    map->gid.lim = 0;
  498. X    map->rev_uid.known = NULL;
  499. X    map->rev_uid.lim = 0;
  500. X    map->rev_gid.known = NULL;
  501. X    map->rev_gid.lim = 0;
  502. X    return map;
  503. X}
  504. X
  505. Xstatic int
  506. Xgrow_tab(idmp, sz)
  507. Xstruct    idm    *idmp;
  508. Xint        sz;
  509. X{
  510. X    if (idmp->lim == 0)
  511. X        idmp->known = (int *) malloc((sz+1) * sizeof(int));
  512. X    else
  513. X        idmp->known = (int *) realloc((char *) idmp->known, (sz+1) * sizeof(int));
  514. X    if (idmp->known == NULL)
  515. X        idmp->lim = 0;
  516. X    else
  517. X    {
  518. X        while (idmp->lim <= sz)
  519. X            idmp->known[idmp->lim++] = WILDCARD;
  520. X        idmp->known[0] = 0;
  521. X    }
  522. X    return idmp->lim;
  523. X}
  524. X
  525. Xstatic int
  526. Xrlookup(name, id, map, xprt)
  527. Xchar    *name;
  528. Xint    *id;
  529. Xint    map;
  530. XSVCXPRT    *xprt;
  531. X{
  532. X    struct sockaddr_in    addr, callback;
  533. X    int    cb_fd;
  534. X    int    cb_len;
  535. X    int    cb_port;
  536. X    struct timeval    wait;
  537. X    int        sock;
  538. X    CLIENT        *cl;
  539. X    int        *pi;
  540. X    char        **pc;
  541. X    int    server_trusted = 0;
  542. X
  543. X
  544. X    addr = *svc_getcaller(xprt);
  545. X    addr.sin_port = 0;
  546. X    wait.tv_sec = 10;
  547. X    wait.tv_usec = 0;
  548. X    sock = RPC_ANYSOCK;
  549. X
  550. X    if ((cl = clntudp_create(&addr, UGIDPROG, UGIDVERS, wait, &sock)) == NULL)
  551. X        return 0;
  552. X    if ((cb_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  553. X        goto bad;
  554. X    bzero((char *)&callback, sizeof(callback));
  555. X    callback.sin_port = 0;
  556. X    callback.sin_addr.s_addr = INADDR_ANY;
  557. X    callback.sin_family = AF_INET;
  558. X    if (bind(cb_fd, &callback, sizeof(callback)) < 0)
  559. X        goto bad;
  560. X    cb_len = sizeof callback;
  561. X    if (getsockname(cb_fd, &callback, &cb_len) < 0)
  562. X        goto bad;
  563. X    cb_port = ntohs(callback.sin_port);
  564. X    pi = authenticate_1(&cb_port, cl);
  565. X    if (pi != NULL && *pi == 0)
  566. X    {
  567. X        struct sockaddr_in    serv;
  568. X        int    x;
  569. X        int    serv_len;
  570. X        struct timeval    timeout;
  571. X        fd_set    rset;
  572. X
  573. X        serv_len = sizeof serv;
  574. X        timeout.tv_sec = 5;
  575. X        timeout.tv_usec = 0;
  576. X#ifndef    FD_ZERO
  577. X#define FD_ZERO(p)    bzero((char *) (p), sizeof *(p));
  578. X#define FD_SETSIZE    32
  579. X#define FD_SET(n,p)    ((*(int *)(p)) |= 1 << n)
  580. X#endif
  581. X        FD_ZERO(&rset);
  582. X        FD_SET(cb_fd, &rset);
  583. X        if (select(FD_SETSIZE, &rset, NULL, NULL, &timeout) > 0)
  584. X        {
  585. X            recvfrom(cb_fd, &x, sizeof x, 0, &serv, &serv_len);
  586. X            server_trusted = ntohs(serv.sin_port) < IPPORT_RESERVED;
  587. X        }
  588. X    }
  589. X    if (!server_trusted)
  590. X        goto bad;
  591. X    switch (map)
  592. X    {
  593. X        case NAME_UID:
  594. X            pi = name_uid_1(&name, cl);
  595. X            if (pi != NULL)
  596. X                *id = *pi;
  597. X            break;
  598. X        case GROUP_GID:
  599. X            pi = group_gid_1(&name, cl);
  600. X            if (pi != NULL)
  601. X                *id = *pi;
  602. X            break;
  603. X        case UID_NAME:
  604. X            pc = uid_name_1(id, cl);
  605. X            if ((pi = (int *) pc) != NULL)
  606. X                strcpy(name, *pc);
  607. X            break;
  608. X        case GID_GROUP:
  609. X            pc = uid_name_1(id, cl);
  610. X            if ((pi = (int *) pc) != NULL)
  611. X                strcpy(name, *pc);
  612. X            break;
  613. X        default:
  614. X            pi = NULL;
  615. X            break;
  616. X    }
  617. X    clnt_destroy(cl);
  618. X    close(cb_fd);
  619. X    return (pi != NULL);
  620. X    bad:
  621. X    clnt_destroy(cl);
  622. X    close(cb_fd);
  623. X    return 0;
  624. X}
  625. X
  626. Xruid(uid, cp, xprt)
  627. Xint        uid;
  628. Xclnt_param    *cp;
  629. XSVCXPRT        *xprt;
  630. X{
  631. X    struct passwd    *pw;
  632. X    mapper    *m;
  633. X
  634. X    if (uid < 0)
  635. X        return (uid != WILDCARD) ? NOBODY : WILDCARD;
  636. X    if (uid == 0 && cp->o.root_squash)
  637. X        return NOBODY;
  638. X    if (cp->o.uidmap == identity)
  639. X        return uid;
  640. X    m = getmap(xprt);
  641. X    if ((uid < m->uid.lim || grow_tab(&(m->uid), uid))
  642. X        && m->uid.known[uid] == WILDCARD)
  643. X    {
  644. X        if ((pw = getpwuid(uid)) == NULL)
  645. X            m->uid.known[uid] = NOBODY;
  646. X        else if (!rlookup(pw->pw_name, &(m->uid.known[uid]), NAME_UID, xprt))
  647. X            m->uid.known[uid] = NOBODY;
  648. X    }
  649. X    return (m->uid.lim == 0) ? NOBODY : m->uid.known[uid];
  650. X}
  651. X
  652. Xrgid(gid, cp, xprt)
  653. Xint        gid;
  654. Xclnt_param    *cp;
  655. XSVCXPRT        *xprt;
  656. X{
  657. X    struct group    *gr;
  658. X    mapper    *m;
  659. X
  660. X    if (gid < 0)
  661. X        return (gid != WILDCARD) ? NOBODY : WILDCARD;
  662. X    if (cp->o.uidmap == identity)
  663. X        return gid;
  664. X    m = getmap(xprt);
  665. X    if ((gid < m->gid.lim || grow_tab(&(m->gid), gid))
  666. X        && m->gid.known[gid] == WILDCARD)
  667. X    {
  668. X        if ((gr = getgrgid(gid)) == NULL)
  669. X            m->gid.known[gid] = NOBODY;
  670. X        else if (!rlookup(gr->gr_name, &(m->gid.known[gid]), GROUP_GID, xprt))
  671. X            m->gid.known[gid] = NOBODY;
  672. X    }
  673. X    return (m->gid.lim == 0) ? NOBODY : m->gid.known[gid];
  674. X}
  675. X
  676. Xluid(uid, cp, xprt)
  677. Xint        uid;
  678. Xclnt_param    *cp;
  679. XSVCXPRT        *xprt;
  680. X{
  681. X    struct passwd    *pw;
  682. X    mapper    *m;
  683. X    char    namebuf[MAXUGLEN];
  684. X
  685. X    if (uid < 0)
  686. X        return (uid != WILDCARD) ? NOBODY : WILDCARD;
  687. X    if (uid == 0 && cp->o.root_squash)
  688. X        return NOBODY;
  689. X    if (cp->o.uidmap == identity)
  690. X        return uid;
  691. X    m = getmap(xprt);
  692. X    if ((uid < m->rev_uid.lim || grow_tab(&(m->rev_uid), uid))
  693. X        && m->rev_uid.known[uid] == WILDCARD)
  694. X    {
  695. X        if (!rlookup(namebuf, &uid, UID_NAME, xprt))
  696. X            m->rev_uid.known[uid] = NOBODY;
  697. X        else if ((pw = getpwnam(namebuf)) == NULL)
  698. X            m->rev_uid.known[uid] = NOBODY;
  699. X        else
  700. X            m->rev_uid.known[uid] = pw->pw_uid;
  701. X    }
  702. X    return (m->rev_uid.lim == 0) ? NOBODY : m->rev_uid.known[uid];
  703. X}
  704. X
  705. Xlgid(gid, cp, xprt)
  706. Xint        gid;
  707. Xclnt_param    *cp;
  708. XSVCXPRT        *xprt;
  709. X{
  710. X    struct group    *gr;
  711. X    mapper    *m;
  712. X    char    namebuf[MAXUGLEN]; 
  713. X
  714. X    if (gid < 0)
  715. X        return (gid != WILDCARD) ? NOBODY : WILDCARD;
  716. X    if (cp->o.uidmap == identity)
  717. X        return gid;
  718. X    m = getmap(xprt);
  719. X    if ((gid < m->rev_gid.lim || grow_tab(&(m->rev_gid), gid))
  720. X        && m->rev_gid.known[gid] == WILDCARD)
  721. X    {
  722. X        if (!rlookup(namebuf, &gid, GID_GROUP, xprt)) 
  723. X            m->rev_gid.known[gid] = NOBODY;
  724. X        else if ((gr = getgrnam(namebuf)) == NULL)
  725. X            m->rev_gid.known[gid] = NOBODY;
  726. X        else
  727. X            m->rev_gid.known[gid] = gr->gr_gid;
  728. X    }
  729. X    return (m->rev_gid.lim == 0) ? NOBODY : m->rev_gid.known[gid];
  730. X}
  731. ________This_Is_The_END________
  732. if test `wc -l < ugid_map.c` -ne 291; then
  733.     echo 'shar: ugid_map.c was damaged during transit (should have been 291 bytes)'
  734. fi
  735. fi        ; : end of overwriting check
  736. echo 'x - ugidd.8'
  737. if test -f ugidd.8; then echo 'shar: not overwriting ugidd.8'; else
  738. sed 's/^X//' << '________This_Is_The_END________' > ugidd.8
  739. X.TH UGIDD 8 "11 May 1988"
  740. X.SH NAME
  741. Xugidd \- uid/gid mapping daemons
  742. X.SH SYNOPSIS
  743. X.nf
  744. X.B /etc/ugidd -d
  745. X.LP
  746. Xor from SunOS inetd(8):
  747. X.B rpc udp /usr/etc/rpc.ugidd 545580417 1
  748. X.fi
  749. X.SH DESCRIPTION
  750. X.IX  "uid/gid mapping daemons"  "ugidd daemon"  ""  "\fLugidd\fP daemon"
  751. X.I ugidd
  752. Xstarts a
  753. Xdaemon that handles rpc requests to map uid/gids to string names and vice versa.
  754. XIt is called by a unfsd(8) server when the client and server do not share
  755. Xthe same passwd file.
  756. X.LP
  757. XThe
  758. X.B -d
  759. Xflag to run as a standalone server.
  760. XOtherwise it assumes it has been started from inetd(8) and communicates on
  761. Xfile descriptor 0.
  762. XWhen started from inetd, the daemon exits after 5 minutes of inactivity.
  763. X.SH "SEE ALSO"
  764. Xunfsd_exports(5)
  765. Xinetd(8)
  766. X.SH BUGS
  767. XThe rpc program number is legal in that it lies in the 0x20000000
  768. Xto 0x3fffffff ``Defined by user'' range, but is completely arbitrary.
  769. ________This_Is_The_END________
  770. if test `wc -l < ugidd.8` -ne 30; then
  771.     echo 'shar: ugidd.8 was damaged during transit (should have been 30 bytes)'
  772. fi
  773. fi        ; : end of overwriting check
  774. echo 'x - ugidd.c'
  775. if test -f ugidd.c; then echo 'shar: not overwriting ugidd.c'; else
  776. sed 's/^X//' << '________This_Is_The_END________' > ugidd.c
  777. X/* UNFSD - copyright Mark A Shand, May 1988.
  778. X * This software maybe be used for any purpose provided
  779. X * the above copyright notice is retained.  It is supplied
  780. X * as is, with no warranty expressed or implied.
  781. X */
  782. X
  783. X#include <rpc/rpc.h>
  784. X#include <sys/types.h>
  785. X#include <sys/socket.h>
  786. X#include <sys/time.h>
  787. X#include <sys/errno.h>
  788. X#include <sys/ioctl.h>
  789. X#include <netinet/in.h>
  790. X#include <pwd.h>
  791. X#include <grp.h>
  792. X#include <signal.h>
  793. X#include "ugid.h"
  794. X
  795. Xstatic struct timeval TIMEOUT = { 25, 0 };
  796. X
  797. X#define    DAEMON_IDLE_LIMIT    (5*60)
  798. X
  799. Xstatic int    idle_limit = 0;
  800. Xextern    int    errno;
  801. X
  802. Xint
  803. Xrun_mode_from_args(argc, argv)
  804. Xint    argc;
  805. Xchar    **argv;
  806. X{
  807. X    int    i;
  808. X
  809. X    for (i = 1; i < argc && argv[i][0] == '-'; i++)
  810. X        if (argv[i][1] == 'd')
  811. X        {
  812. X#ifndef DEBUG
  813. X            int fd;
  814. X
  815. X            if (fork())
  816. X                exit(0);
  817. X            close(0);
  818. X            close(1);
  819. X            close(2);
  820. X            if ((fd = open("/dev/tty", 2)) >= 0)
  821. X            {
  822. X                ioctl(fd, TIOCNOTTY, (char *)0);
  823. X                (void) close(fd);
  824. X            }
  825. X#endif DEBUG
  826. X            return RPC_ANYSOCK;
  827. X        }
  828. X    /* assume run from inetd */
  829. X    idle_limit = DAEMON_IDLE_LIMIT;
  830. X    alarm(idle_limit);
  831. X    return 0;
  832. X}
  833. X
  834. Xint *
  835. Xauthenticate_1(argp, rqstp)
  836. X    int *argp;
  837. X    struct svc_req *rqstp;
  838. X{
  839. X    static int res;
  840. X    int    s;
  841. X    struct sockaddr_in    sendaddr, destaddr;
  842. X    int    da_len;
  843. X    int    dummy;
  844. X    short    lport;
  845. X
  846. X    bzero(&res, sizeof res);
  847. X    destaddr = *svc_getcaller(rqstp->rq_xprt);
  848. X    destaddr.sin_port = htons(*argp);
  849. X    if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  850. X        goto bad;
  851. X    setsockopt(s, SOL_SOCKET, SO_LINGER, 0, 0);
  852. X    bzero((char *) &sendaddr, sizeof sendaddr);
  853. X    /* find a reserved port */
  854. X    lport = IPPORT_RESERVED - 1;
  855. X    sendaddr.sin_family = AF_INET;
  856. X    sendaddr.sin_addr.s_addr = INADDR_ANY;
  857. X    for (;;)
  858. X    {
  859. X        sendaddr.sin_port = htons((u_short)lport);
  860. X        if (bind(s, &sendaddr, sizeof sendaddr) >= 0)
  861. X            break;
  862. X        if (errno != EADDRINUSE && EADDRNOTAVAIL)
  863. X            goto bad;
  864. X        lport--;
  865. X        if (lport <= IPPORT_RESERVED / 2)
  866. X            /* give up */
  867. X            break;
  868. X    }
  869. X    if (sendto(s, &dummy, sizeof dummy, 0, &destaddr, sizeof destaddr) < 0)
  870. X        goto bad;
  871. X
  872. X    close(s);
  873. X    res = 0;
  874. X    return (&res);
  875. X    bad:
  876. X    close(s);
  877. X    res = errno == 0 ? -1 : errno;
  878. X    return (&res);
  879. X}
  880. X
  881. Xint *
  882. Xname_uid_1(argp, rqstp)
  883. X    ugname *argp;
  884. X    struct svc_req *rqstp;
  885. X{
  886. X    static int res;
  887. X    struct passwd    *pw;
  888. X
  889. X    bzero(&res, sizeof(res));
  890. X    alarm(idle_limit);
  891. X    if ((pw = getpwnam(*argp)) == NULL)
  892. X        res = NOBODY;
  893. X    else
  894. X        res = pw->pw_uid;
  895. X
  896. X    return (&res);
  897. X}
  898. X
  899. X
  900. Xint *
  901. Xgroup_gid_1(argp, rqstp)
  902. X    ugname *argp;
  903. X    struct svc_req *rqstp;
  904. X{
  905. X    static int res;
  906. X    struct group    *gr;
  907. X
  908. X    bzero(&res, sizeof(res));
  909. X    alarm(idle_limit);
  910. X    if ((gr = getgrnam(*argp)) == NULL)
  911. X        res = NOBODY;
  912. X    else
  913. X        res = gr->gr_gid;
  914. X
  915. X    return (&res);
  916. X}
  917. X
  918. X
  919. Xugname *
  920. Xuid_name_1(argp, rqstp)
  921. X    int *argp;
  922. X    struct svc_req *rqstp;
  923. X{
  924. X    static ugname res;
  925. X    struct passwd    *pw;
  926. X
  927. X    bzero(&res, sizeof(res));
  928. X    alarm(idle_limit);
  929. X    if ((pw = getpwuid(*argp)) == NULL)
  930. X        res = NULL;
  931. X    else
  932. X        res = pw->pw_name;
  933. X
  934. X    return (&res);
  935. X}
  936. X
  937. X
  938. Xugname *
  939. Xgid_group_1(argp, rqstp)
  940. X    int *argp;
  941. X    struct svc_req *rqstp;
  942. X{
  943. X    static ugname res;
  944. X    struct group    *gr;
  945. X
  946. X    bzero(&res, sizeof(res));
  947. X    alarm(idle_limit);
  948. X    if ((gr = getgrgid(*argp)) == NULL)
  949. X        res = NULL;
  950. X    else
  951. X        res = gr->gr_name;
  952. X
  953. X    return (&res);
  954. X}
  955. ________This_Is_The_END________
  956. if test `wc -l < ugidd.c` -ne 178; then
  957.     echo 'shar: ugidd.c was damaged during transit (should have been 178 bytes)'
  958. fi
  959. fi        ; : end of overwriting check
  960. echo 'x - unfsd.8'
  961. if test -f unfsd.8; then echo 'shar: not overwriting unfsd.8'; else
  962. sed 's/^X//' << '________This_Is_The_END________' > unfsd.8
  963. X.TH UNFSD 8 "11 May 1988"
  964. X.SH NAME
  965. Xunfsd, unfsmntd \- user-level NFS daemons
  966. X.SH SYNOPSIS
  967. X.nf
  968. X.B /etc/unfsd [-f exports-file] [-p] [-o option-string]
  969. X.LP
  970. X.ft B
  971. X.B /etc/unfsmntd
  972. X.fi
  973. X.SH DESCRIPTION
  974. X.IX  "user-level network file system"  "unfsd daemon"  ""  "\fLunfsd\fP daemon"
  975. X.IX  "user-level network file system"  "unfsmntd daemon"  ""  "\fLunfsmntd\fP daemon"
  976. X.IX  "user-level unfsd daemon"  ""  "\fLunfsd\fP daemon"
  977. X.IX  "unfsmntd daemon"  ""  "\fLunfsmntd\fP daemon"
  978. X.IX  "daemons"  "unfsd daemon"  ""  "\fLunfsd\fP daemon"
  979. X.IX  "daemons"  "unfsmntd daemon"  ""  "\fLunfsmntd\fP daemon"
  980. X.I unfsd
  981. Xstarts a
  982. Xdaemon that handles client filesystem requests.
  983. XUnlike nfsd(8), unfsd operates as a normal user-level process and can be run
  984. Xon standard 4.3BSD systems.
  985. XThe server also differs from nfsd(8) in that it mounts an entire file
  986. Xhierarchy, not limited by the boundaries of physical file-systems.
  987. XThe currently implementation only allows the clients read access to the
  988. Xfile hierarchy of the server machine.
  989. X.LP
  990. X.I unfsmntd
  991. Xstarts
  992. Xan ancillary user-level mount daemon.
  993. X.LP
  994. X.IR Options .
  995. XThe
  996. X.B -f
  997. Xoption specifies the exports file, listing the clients that this server
  998. Xis prepared to serve and parameters to apply to each such mount (see
  999. Xunfsd_exports(5)).
  1000. XBy defualt exports are read from
  1001. X.IR /etc/unfsd_exports .
  1002. XThe
  1003. X.B -p
  1004. Xoption puts the server into promiscuous mode where it will serve any host
  1005. Xon the network.
  1006. XThe
  1007. X.B -o
  1008. Xoption specifies default mount parameters in the same format as those appearing
  1009. Xin the
  1010. X.I unfsd_exports
  1011. Xfile.
  1012. X.SH "SEE ALSO"
  1013. Xunfsd_exports(5)
  1014. Xugidd(8C)
  1015. X.BUGS
  1016. XThe current implementation only allows read access to file-systems.
  1017. ________This_Is_The_END________
  1018. if test `wc -l < unfsd.8` -ne 54; then
  1019.     echo 'shar: unfsd.8 was damaged during transit (should have been 54 bytes)'
  1020. fi
  1021. fi        ; : end of overwriting check
  1022. echo 'x - unfsd.c'
  1023. if test -f unfsd.c; then echo 'shar: not overwriting unfsd.c'; else
  1024. sed 's/^X//' << '________This_Is_The_END________' > unfsd.c
  1025. X/* UNFSD - copyright Mark A Shand, May 1988.
  1026. X * This software maybe be used for any purpose provided
  1027. X * the above copyright notice is retained.  It is supplied
  1028. X * as is, with no warranty expressed or implied.
  1029. X */
  1030. X
  1031. X#include "unfsd.h"
  1032. X
  1033. Xstatic struct timeval TIMEOUT = { 25, 0 };
  1034. X
  1035. X/* ====================================================================== */
  1036. X#ifdef DEBUG
  1037. XFILE *debuglog = NULL;
  1038. Xstatic char *pname = "unfsd";
  1039. Xstatic char argbuf[1024];
  1040. X
  1041. Xlogcall(name, arg, rqstp)
  1042. Xchar    *name;
  1043. Xchar    *arg;
  1044. Xstruct svc_req    *rqstp;
  1045. X{
  1046. X    int    i;
  1047. X
  1048. X    if (debuglog == NULL)
  1049. X    {
  1050. X        unsigned long tloc;
  1051. X        if ((debuglog = fopen("/tmp/unfsd.log", "w")) == NULL)
  1052. X            return;
  1053. X        setlinebuf(debuglog);
  1054. X        time(&tloc);
  1055. X        fprintf(debuglog, "\n\nstarting %s at %s\n", pname, ctime(&tloc));
  1056. X    }
  1057. X    fprintf(debuglog, "%s [%d ", name, rqstp->rq_cred.oa_flavor);
  1058. X    if (rqstp->rq_cred.oa_flavor == AUTH_UNIX)
  1059. X    {
  1060. X        struct authunix_parms *unix_cred;
  1061. X        struct tm *tm;
  1062. X        unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
  1063. X        tm = localtime(&unix_cred->aup_time);
  1064. X        fprintf(debuglog, "%d/%d/%d %02d:%02d:%02d %s %d.%d",
  1065. X            tm->tm_year, tm->tm_mon+1, tm->tm_mday,
  1066. X            tm->tm_hour, tm->tm_min, tm->tm_sec,
  1067. X            unix_cred->aup_machname,
  1068. X            unix_cred->aup_uid,
  1069. X            unix_cred->aup_gid);
  1070. X        if (unix_cred->aup_len > 0)
  1071. X        {
  1072. X            fprintf(debuglog, "+%d", unix_cred->aup_gids[0]);
  1073. X            for (i = 1; i < unix_cred->aup_len; i++)
  1074. X                fprintf(debuglog, ",%d",unix_cred->aup_gids[i]);
  1075. X        }
  1076. X    }
  1077. X    fprintf(debuglog, "]\n\t%s\n", arg);
  1078. X}
  1079. X
  1080. X#else
  1081. X#define logcall(name, arg, client)
  1082. X#define fh_pr(x)    ""
  1083. X#endif DEBUG
  1084. X/* ====================================================================== */
  1085. X
  1086. Xextern int errno;
  1087. X#ifdef DEBUG
  1088. Xextern char *sys_errlist[];
  1089. X#endif DEBUG
  1090. X
  1091. Xextern char    *malloc();
  1092. X
  1093. X
  1094. X
  1095. X/* ====================================================================== */
  1096. X
  1097. Xvoid *
  1098. Xnfsproc_null_2(argp, rqstp)
  1099. X    void *argp;
  1100. X    struct svc_req *rqstp;
  1101. X{
  1102. X    static char res;
  1103. X
  1104. X    bzero(&res, sizeof(res));
  1105. X    logcall("nfsproc_null", "", rqstp);
  1106. X    return ((void *)&res);
  1107. X}
  1108. X
  1109. X
  1110. Xstatic void
  1111. Xinner_getattr(fh, status, attr, stat_optimize, cp, rqstp)
  1112. X    nfs_fh        *fh;
  1113. X    nfsstat        *status;
  1114. X    fattr        *attr;
  1115. X    struct stat    *stat_optimize;
  1116. X    clnt_param    *cp;
  1117. X    struct svc_req    *rqstp;
  1118. X{
  1119. X    char    *path;
  1120. X    struct stat *s;
  1121. X    struct stat sbuf;
  1122. X
  1123. X#ifdef DEBUG
  1124. X    if (debuglog)
  1125. X        fprintf(debuglog, " inner_getattr");
  1126. X#endif
  1127. X    if ((path = fh_path(fh, status)) != 0)
  1128. X    {
  1129. X        if (stat_optimize != NULL)
  1130. X            s = stat_optimize;
  1131. X        else
  1132. X        {
  1133. X            s = &sbuf;
  1134. X            if (lstat(path, s) < 0)
  1135. X                *status = (nfsstat) errno;
  1136. X        }
  1137. X            
  1138. X        attr->type = ft_map[ft_extr(s->st_mode)];
  1139. X        attr->mode = s->st_mode;
  1140. X        attr->nlink = s->st_nlink;
  1141. X        attr->uid = ruid(s->st_uid, cp, rqstp->rq_xprt);
  1142. X        attr->gid = rgid(s->st_gid, cp, rqstp->rq_xprt);
  1143. X        attr->size = s->st_size;
  1144. X        attr->blocksize = s->st_blksize;
  1145. X        attr->rdev = s->st_rdev;
  1146. X        attr->blocks = s->st_blocks;
  1147. X        attr->fsid = 1;
  1148. X        attr->fileid = fh_psi(fh);
  1149. X        attr->atime.seconds = s->st_atime;
  1150. X        attr->mtime.seconds = s->st_mtime;
  1151. X        attr->ctime.seconds = s->st_ctime;
  1152. X#ifdef DEBUG
  1153. X        if (debuglog)
  1154. X        {
  1155. X            if (*status == NFS_OK)
  1156. X            {
  1157. X                fprintf(debuglog, " t=%d, m=%o, lk=%d, u/g=%d/%d, sz=%d, bsz=%d",
  1158. X                    attr->type, attr->mode, attr->nlink,
  1159. X                    attr->uid, attr->gid, attr->size,
  1160. X                    attr->blocksize);
  1161. X                if (attr->type == NFCHR || attr->type == NFBLK)
  1162. X                    fprintf(debuglog, " rdev=%d/%d",
  1163. X                        (attr->rdev>>8)&0xff, attr->rdev&0xff);
  1164. X                fprintf(debuglog, "\n  blks=%d, fsid=%d, psi=%d, at=%d, mt=%d, ct=%d\n",
  1165. X                    attr->blocks, attr->fsid, attr->fileid,
  1166. X                    attr->atime.seconds,
  1167. X                    attr->mtime.seconds,
  1168. X                    attr->ctime.seconds);
  1169. X            }
  1170. X            else
  1171. X                fprintf(debuglog, " >>> %s\n", sys_errlist[(int) *status]);
  1172. X        }
  1173. X#endif
  1174. X    }
  1175. X#ifdef DEBUG
  1176. X    else if (debuglog)
  1177. X        fprintf(debuglog, " failed!\n");
  1178. X#endif
  1179. X}
  1180. X
  1181. X
  1182. Xattrstat *
  1183. Xnfsproc_getattr_2(argp, rqstp)
  1184. X    nfs_fh *argp;
  1185. X    struct svc_req *rqstp;
  1186. X{
  1187. X    static attrstat res;
  1188. X    clnt_param    *cp;
  1189. X
  1190. X    bzero(&res, sizeof(res));
  1191. X    logcall("nfsproc_getattr", fh_pr(argp), rqstp);
  1192. X    if ((cp = knownclient(rqstp)) == NULL)
  1193. X    {
  1194. X        res.status = NFSERR_ACCES;
  1195. X        return (&res);
  1196. X    }
  1197. X    inner_getattr(argp, &(res.status),
  1198. X        &(res.attrstat_u.attributes), NULL, cp, rqstp);
  1199. X    return (&res);
  1200. X}
  1201. X
  1202. X
  1203. Xattrstat *
  1204. Xnfsproc_setattr_2(argp, rqstp)
  1205. X    sattrargs *argp;
  1206. X    struct svc_req *rqstp;
  1207. X{
  1208. X    static attrstat res;
  1209. X
  1210. X    bzero(&res, sizeof(res));
  1211. X    logcall("nfsproc_setattr", "", rqstp);
  1212. X    if (knownclient(rqstp) == NULL)
  1213. X    {
  1214. X        res.status = NFSERR_ACCES;
  1215. X        return (&res);
  1216. X    }
  1217. X#ifdef READ_ONLY
  1218. X    res.status = NFSERR_ROFS;
  1219. X#else
  1220. X    not implemented
  1221. X#endif
  1222. X    return (&res);
  1223. X}
  1224. X
  1225. X
  1226. Xvoid *
  1227. Xnfsproc_root_2(argp, rqstp)
  1228. X    void *argp;
  1229. X    struct svc_req *rqstp;
  1230. X{
  1231. X    static char res;
  1232. X
  1233. X    bzero(&res, sizeof(res));
  1234. X    logcall("nfsproc_root", "", rqstp);
  1235. X    return ((void *)&res);
  1236. X}
  1237. X
  1238. X
  1239. Xdiropres *
  1240. Xnfsproc_lookup_2(argp, rqstp)
  1241. X    diropargs *argp;
  1242. X    struct svc_req *rqstp;
  1243. X{
  1244. X    static diropres res;
  1245. X    clnt_param    *cp;
  1246. X    struct stat    sbuf;
  1247. X    struct stat    *sbp = &sbuf;
  1248. X
  1249. X    bzero(&res, sizeof(res));
  1250. X    logcall("nfsproc_lookup", sprintf(argbuf, "fh=%s n=%s", fh_pr(&(argp->dir)), argp->name), rqstp);
  1251. X    if ((cp = knownclient(rqstp)) == NULL)
  1252. X    {
  1253. X        res.status = NFSERR_ACCES;
  1254. X        return (&res);
  1255. X    }
  1256. X    res.status = fh_compose(argp, &(res.diropres_u.diropres.file), &sbp);
  1257. X    if (res.status == NFS_OK)
  1258. X    {
  1259. X        inner_getattr(&(res.diropres_u.diropres.file), &(res.status),
  1260. X            &(res.diropres_u.diropres.attributes), sbp, cp,rqstp);
  1261. X#ifdef DEBUG
  1262. X        if (debuglog && res.status == NFS_OK)
  1263. X            fprintf(debuglog, "\tnew_fh = %s\n", fh_pr(&(res.diropres_u.diropres.file)));
  1264. X#endif /* DEBUG */
  1265. X    }
  1266. X    return (&res);
  1267. X}
  1268. X
  1269. X
  1270. Xreadlinkres *
  1271. Xnfsproc_readlink_2(argp, rqstp)
  1272. X    nfs_fh *argp;
  1273. X    struct svc_req *rqstp;
  1274. X{
  1275. X    static readlinkres res;
  1276. X    clnt_param    *cp;
  1277. X    char    *path;
  1278. X
  1279. X    bzero(&res, sizeof(res));
  1280. X    logcall("nfsproc_readlink", fh_pr(argp), rqstp);
  1281. X    if ((cp = knownclient(rqstp)) == NULL)
  1282. X    {
  1283. X        res.status = NFSERR_ACCES;
  1284. X        return (&res);
  1285. X    }
  1286. X    if ((path = fh_path(argp, &(res.status))) != 0)
  1287. X    {
  1288. X        int    cc;
  1289. X        static char    linkbuf[NFS_MAXPATHLEN];
  1290. X
  1291. X        errno = 0;
  1292. X        if ((cc = readlink(path, linkbuf, NFS_MAXPATHLEN)) < 0)
  1293. X            res.status = (nfsstat) errno;
  1294. X        else
  1295. X        {
  1296. X            res.status = NFS_OK;
  1297. X            linkbuf[cc] = '\0';
  1298. X            res.readlinkres_u.data = linkbuf;
  1299. X            if (cp->o.link_relative && linkbuf[0] == '/')
  1300. X            {
  1301. X                /* prepend ../ sequence.  Note: relies that
  1302. X                 * fh_path returns a path containing real
  1303. X                 * directories.
  1304. X                 */
  1305. X                int    slash_cnt = 0;
  1306. X                char    *p, *q;
  1307. X                for (p = index(path+1, '/'); p != NULL; p = index(p+1, '/'))
  1308. X                    slash_cnt++;
  1309. X                p = linkbuf + strlen(linkbuf);
  1310. X                q = p + 3 * slash_cnt - 1;
  1311. X                if (q >= linkbuf + NFS_MAXPATHLEN)
  1312. X                    res.status = NFSERR_NAMETOOLONG;
  1313. X                else
  1314. X                {
  1315. X                    while (p >= linkbuf)
  1316. X                        *q-- = *p--;
  1317. X                    p = linkbuf;
  1318. X                    while (slash_cnt-- > 0)
  1319. X                    {
  1320. X                        *p++ = '.';    
  1321. X                        *p++ = '.';    
  1322. X                        *p++ = '/';    
  1323. X                    }
  1324. X                }
  1325. X            }
  1326. X        }
  1327. X    }
  1328. X#ifdef DEBUG
  1329. X    if (debuglog)
  1330. X    {
  1331. X        if (res.status != NFS_OK)
  1332. X            fprintf(debuglog, " >>> %s\n", sys_errlist[(int) res.status]);
  1333. X        else
  1334. X            fprintf(debuglog, " %s\n", res.readlinkres_u.data);
  1335. X    }
  1336. X#endif /* DEBUG */
  1337. X    return (&res);
  1338. X}
  1339. X
  1340. X
  1341. Xstatic char iobuf[NFS_MAXDATA];
  1342. X
  1343. Xreadres *
  1344. Xnfsproc_read_2(argp, rqstp)
  1345. X    readargs *argp;
  1346. X    struct svc_req *rqstp;
  1347. X{
  1348. X    static readres res;
  1349. X    clnt_param    *cp;
  1350. X    int    fd;
  1351. X
  1352. X    bzero(&res, sizeof(res));
  1353. X    logcall("nfsproc_read", sprintf(argbuf, "%s @%d for %d", fh_pr(&(argp->file)), argp->offset, argp->count), rqstp);
  1354. X    if ((cp = knownclient(rqstp)) == NULL)
  1355. X    {
  1356. X        res.status = NFSERR_ACCES;
  1357. X        return (&res);
  1358. X    }
  1359. X    if ((fd = fh_fd(&(argp->file), &(res.status), O_RDONLY)) >= 0)
  1360. X    {
  1361. X        errno = 0;
  1362. X        lseek(fd, (long) argp->offset, L_SET);
  1363. X        res.readres_u.reply.data.data_val = iobuf;
  1364. X        if (!errno)
  1365. X            res.readres_u.reply.data.data_len =
  1366. X                read(fd, res.readres_u.reply.data.data_val, argp->count);
  1367. X        fd_idle(fd);
  1368. X        res.status = (nfsstat) errno;
  1369. X        if (!errno)
  1370. X            inner_getattr(&(argp->file), &(res.status),
  1371. X                &(res.readres_u.reply.attributes), NULL, cp, rqstp);
  1372. X    }
  1373. X    return (&res);
  1374. X}
  1375. X
  1376. X
  1377. Xvoid *
  1378. Xnfsproc_writecache_2(argp, rqstp)
  1379. X    void *argp;
  1380. X    struct svc_req *rqstp;
  1381. X{
  1382. X    static char res;
  1383. X
  1384. X    bzero(&res, sizeof(res));
  1385. X    logcall("nfsproc_writecache", "", rqstp);
  1386. X    return ((void *)&res);
  1387. X}
  1388. X
  1389. X
  1390. Xattrstat *
  1391. Xnfsproc_write_2(argp, rqstp)
  1392. X    writeargs *argp;
  1393. X    struct svc_req *rqstp;
  1394. X{
  1395. X    static attrstat res;
  1396. X
  1397. X    bzero(&res, sizeof(res));
  1398. X    logcall("nfsproc_write", sprintf(argbuf, "%s @%d for %d", fh_pr(&(argp->file)), argp->offset, argp->data.data_len), rqstp);
  1399. X    if (knownclient(rqstp) == NULL)
  1400. X    {
  1401. X        res.status = NFSERR_ACCES;
  1402. X        return (&res);
  1403. X    }
  1404. X#ifdef READ_ONLY
  1405. X    res.status = NFSERR_ROFS;
  1406. X#else /* READ_ONLY */
  1407. X    not implemented
  1408. X#endif /* READ_ONLY */
  1409. X    return (&res);
  1410. X}
  1411. X
  1412. X
  1413. Xdiropres *
  1414. Xnfsproc_create_2(argp, rqstp)
  1415. X    createargs *argp;
  1416. X    struct svc_req *rqstp;
  1417. X{
  1418. X    static diropres res;
  1419. X
  1420. X    bzero(&res, sizeof(res));
  1421. X    logcall("nfsproc_create", sprintf(argbuf, "fh=%s n=%s m=%0o u/g=%d/%d sz=%d", fh_pr(&(argp->where.dir)), argp->where.name, argp->attributes.mode, argp->attributes.uid, argp->attributes.gid, argp->attributes.size), rqstp);
  1422. X    if (knownclient(rqstp) == NULL)
  1423. X    {
  1424. X        res.status = NFSERR_ACCES;
  1425. X        return (&res);
  1426. X    }
  1427. X#ifdef READ_ONLY
  1428. X    res.status = NFSERR_ROFS;
  1429. X#else /* READ_ONLY */
  1430. X    not implemented
  1431. X#endif /* READ_ONLY */
  1432. X    return (&res);
  1433. X}
  1434. X
  1435. X
  1436. Xnfsstat *
  1437. Xnfsproc_remove_2(argp, rqstp)
  1438. X    diropargs *argp;
  1439. X    struct svc_req *rqstp;
  1440. X{
  1441. X    static nfsstat res;
  1442. X
  1443. X    bzero(&res, sizeof(res));
  1444. X    logcall("nfsproc_remove", "", rqstp);
  1445. X    if (!knownclient(rqstp))
  1446. X    {
  1447. X        res = NFSERR_ACCES;
  1448. X        return (&res);
  1449. X    }
  1450. X    res = NFSERR_ROFS;
  1451. X    return (&res);
  1452. X}
  1453. X
  1454. X
  1455. Xnfsstat *
  1456. Xnfsproc_rename_2(argp, rqstp)
  1457. X    renameargs *argp;
  1458. X    struct svc_req *rqstp;
  1459. X{
  1460. X    static nfsstat res;
  1461. X
  1462. X    bzero(&res, sizeof(res));
  1463. X    logcall("nfsproc_rename", "", rqstp);
  1464. X    if (!knownclient(rqstp))
  1465. X    {
  1466. X        res = NFSERR_ACCES;
  1467. X        return (&res);
  1468. X    }
  1469. X    res = NFSERR_ROFS;
  1470. X    return (&res);
  1471. X}
  1472. X
  1473. X
  1474. Xnfsstat *
  1475. Xnfsproc_link_2(argp, rqstp)
  1476. X    linkargs *argp;
  1477. X    struct svc_req *rqstp;
  1478. X{
  1479. X    static nfsstat res;
  1480. X
  1481. X    bzero(&res, sizeof(res));
  1482. X    logcall("nfsproc_link", "", rqstp);
  1483. X    if (!knownclient(rqstp))
  1484. X    {
  1485. X        res = NFSERR_ACCES;
  1486. X        return (&res);
  1487. X    }
  1488. X    res = NFSERR_ROFS;
  1489. X    return (&res);
  1490. X}
  1491. X
  1492. X
  1493. Xnfsstat *
  1494. Xnfsproc_symlink_2(argp, rqstp)
  1495. X    symlinkargs *argp;
  1496. X    struct svc_req *rqstp;
  1497. X{
  1498. X    static nfsstat res;
  1499. X
  1500. X    bzero(&res, sizeof(res));
  1501. X    logcall("nfsproc_symlink", "", rqstp);
  1502. X    if (!knownclient(rqstp))
  1503. X    {
  1504. X        res = NFSERR_ACCES;
  1505. X        return (&res);
  1506. X    }
  1507. X    res = NFSERR_ROFS;
  1508. X    return (&res);
  1509. X}
  1510. X
  1511. X
  1512. Xdiropres *
  1513. Xnfsproc_mkdir_2(argp, rqstp)
  1514. X    createargs *argp;
  1515. X    struct svc_req *rqstp;
  1516. X{
  1517. X    static diropres res;
  1518. X
  1519. X    bzero(&res, sizeof(res));
  1520. X    logcall("nfsproc_mkdir", "", rqstp);
  1521. X    if (!knownclient(rqstp))
  1522. X    {
  1523. X        res.status = NFSERR_ACCES;
  1524. X        return (&res);
  1525. X    }
  1526. X    res.status = NFSERR_ROFS;
  1527. X    return (&res);
  1528. X}
  1529. X
  1530. X
  1531. Xnfsstat *
  1532. Xnfsproc_rmdir_2(argp, rqstp)
  1533. X    diropargs *argp;
  1534. X    struct svc_req *rqstp;
  1535. X{
  1536. X    static nfsstat res;
  1537. X
  1538. X    bzero(&res, sizeof(res));
  1539. X    logcall("nfsproc_rmdir", "", rqstp);
  1540. X    if (!knownclient(rqstp))
  1541. X    {
  1542. X        res = NFSERR_ACCES;
  1543. X        return (&res);
  1544. X    }
  1545. X    res = NFSERR_ROFS;
  1546. X    return (&res);
  1547. X}
  1548. X
  1549. Xstatic int
  1550. Xdpsize(dp)
  1551. Xstruct direct *dp;
  1552. X{
  1553. X#define DP_SLOP    16
  1554. X#define MAX_E_SIZE sizeof(entry) + MAXNAMLEN + DP_SLOP
  1555. X    return sizeof(entry) + strlen(dp->d_name) + DP_SLOP;
  1556. X}
  1557. X
  1558. Xreaddirres *
  1559. Xnfsproc_readdir_2(argp, rqstp)
  1560. X    readdirargs *argp;
  1561. X    struct svc_req *rqstp;
  1562. X{
  1563. X    static readdirres res;
  1564. X    entry **e;
  1565. X    char    *path;
  1566. X
  1567. X    /*
  1568. X     * Free previous result
  1569. X     */
  1570. X    xdr_free(xdr_readdirres, &res);
  1571. X
  1572. X    bzero(&res, sizeof(res));
  1573. X    logcall("nfsproc_readdir", fh_pr(&(argp->dir)), rqstp);
  1574. X    if (!knownclient(rqstp))
  1575. X    {
  1576. X        res.status = NFSERR_ACCES;
  1577. X        return (&res);
  1578. X    }
  1579. X    if ((path = fh_path(argp, &(res.status))) != 0)
  1580. X    {
  1581. X        long    dloc;
  1582. X        DIR    *dirp;
  1583. X        struct direct *dp;
  1584. X        struct    stat    sbuf;
  1585. X
  1586. X        errno = 0;
  1587. X        stat(path, &sbuf);
  1588. X        if ((dirp = opendir(path)) == NULL)
  1589. X        {
  1590. X            if (errno != 0)
  1591. X                res.status = (nfsstat) errno;
  1592. X            else
  1593. X                res.status = NFSERR_NAMETOOLONG;
  1594. X        }
  1595. X        else
  1596. X        {
  1597. X            int    res_size = 0;
  1598. X
  1599. X            res.status = NFS_OK;
  1600. X            bcopy(argp->cookie, &dloc, sizeof(dloc));
  1601. X            if (dloc != 0)
  1602. X                seekdir(dirp, dloc);
  1603. X            e = &(res.readdirres_u.reply.entries);
  1604. X            while (((res_size + MAX_E_SIZE) < argp->count
  1605. X                     || e == &(res.readdirres_u.reply.entries))
  1606. X                 && (dp = readdir(dirp)) != NULL)
  1607. X            {
  1608. X                if ((*e = (entry *) malloc(sizeof(entry))) == NULL)
  1609. X                    mallocfailed();
  1610. X                (*e)->fileid = pseudo_inode(dp->d_ino, sbuf.st_dev);
  1611. X                if (((*e)->name = malloc(strlen(dp->d_name)+1)) == NULL)
  1612. X                    mallocfailed();
  1613. X                strcpy((*e)->name, dp->d_name);
  1614. X                dloc = telldir(dirp);
  1615. X                bcopy(&dloc, ((*e)->cookie), sizeof(nfscookie));
  1616. X                e = &((*e)->nextentry);
  1617. X                res_size += dpsize(dp);
  1618. X            }
  1619. X            *e = NULL;
  1620. X            res.readdirres_u.reply.eof = (dp == NULL);
  1621. X            closedir(dirp);
  1622. X        }
  1623. X    }
  1624. X    return (&res);
  1625. X}
  1626. X
  1627. X
  1628. Xstatfsres *
  1629. Xnfsproc_statfs_2(argp, rqstp)
  1630. X    nfs_fh *argp;
  1631. X    struct svc_req *rqstp;
  1632. X{
  1633. X    static statfsres res;
  1634. X
  1635. X    bzero(&res, sizeof(res));
  1636. X    logcall("nfsproc_statfs", fh_pr(argp), rqstp);
  1637. X    if (!knownclient(rqstp))
  1638. X    {
  1639. X        res.status = NFSERR_ACCES;
  1640. X        return (&res);
  1641. X    }
  1642. X    /* no easy way to do this */
  1643. X    res.status = NFS_OK;
  1644. X    res.statfsres_u.reply.tsize = 4096;
  1645. X    res.statfsres_u.reply.bsize = 4096;
  1646. X    res.statfsres_u.reply.blocks = 100000;
  1647. X    res.statfsres_u.reply.bfree = 80000;
  1648. X    res.statfsres_u.reply.bavail = 71000;
  1649. X    return (&res);
  1650. X}
  1651. ________This_Is_The_END________
  1652. if test `wc -l < unfsd.c` -ne 626; then
  1653.     echo 'shar: unfsd.c was damaged during transit (should have been 626 bytes)'
  1654. fi
  1655. fi        ; : end of overwriting check
  1656. echo 'x - unfsd.h'
  1657. if test -f unfsd.h; then echo 'shar: not overwriting unfsd.h'; else
  1658. sed 's/^X//' << '________This_Is_The_END________' > unfsd.h
  1659. X/* UNFSD - copyright Mark A Shand, May 1988.
  1660. X * This software maybe be used for any purpose provided
  1661. X * the above copyright notice is retained.  It is supplied
  1662. X * as is, with no warranty expressed or implied.
  1663. X */
  1664. X
  1665. X#include <stdio.h>
  1666. X#include <ctype.h>
  1667. X#include <sys/param.h>
  1668. X#include <sys/types.h>
  1669. X#include <sys/file.h>
  1670. X#include <sys/dir.h>
  1671. X#include <rpc/rpc.h>
  1672. X#include <sys/time.h>
  1673. X#include <sys/stat.h>
  1674. X#include <sys/socket.h>
  1675. X#include <sys/ioctl.h>
  1676. X#include <netdb.h>
  1677. X#include <strings.h>
  1678. X#include <syslog.h>
  1679. X
  1680. X/* mask SUNOS/BSD4.3 syslog incompatibilities */
  1681. X#ifndef LOG_DAEMON
  1682. X#define    LOG_DAEMON    0
  1683. X#endif /* LOG_DAEMON */
  1684. X#ifndef LOG_TIME
  1685. X#define    LOG_TIME    0
  1686. X#endif /* LOG_TIME */
  1687. X
  1688. X#include "nfs_prot.h"
  1689. X#include "ugid.h"
  1690. X#include "fh.h"
  1691. X
  1692. Xtypedef struct options
  1693. X{
  1694. X    /* uid/gid mapping functions */
  1695. X    enum {map_daemon, identity}    uidmap;
  1696. X    int    root_squash;
  1697. X    /* client options */
  1698. X    int    secure_port;
  1699. X    int    read_only;
  1700. X    int    link_relative;
  1701. X}
  1702. X    options;
  1703. X
  1704. Xtypedef struct clnt_param
  1705. X{
  1706. X    struct clnt_param    *next;
  1707. X
  1708. X    struct in_addr    clnt_addr;
  1709. X    char    *clnt_name;
  1710. X    char    *mount_point;
  1711. X    options    o;
  1712. X}
  1713. X    clnt_param;
  1714. X
  1715. Xextern ftype ft_map[16];
  1716. Xextern int svc_euid;
  1717. Xextern int svc_egid;
  1718. Xextern int cur_gid;
  1719. Xextern int svc_ngids;
  1720. Xextern int svc_gids[NGROUPS+2];
  1721. X
  1722. X#define ft_extr(x)    ((x & S_IFMT) >> 12)
  1723. X#define in_gid_set(gid)    ((gid) == cur_gid || _in_gid_set(gid))
  1724. X
  1725. Xextern int _in_gid_set();
  1726. Xextern clnt_param *knownclient();
  1727. ________This_Is_The_END________
  1728. if test `wc -l < unfsd.h` -ne 68; then
  1729.     echo 'shar: unfsd.h was damaged during transit (should have been 68 bytes)'
  1730. fi
  1731. fi        ; : end of overwriting check
  1732. echo 'x - unfsd_exports.5'
  1733. if test -f unfsd_exports.5; then echo 'shar: not overwriting unfsd_exports.5'; else
  1734. sed 's/^X//' << '________This_Is_The_END________' > unfsd_exports.5
  1735. X.\" @(#)exports.5 1.3 86/08/02 SMI;
  1736. X.TH UNFSD_EXPORTS 5 "11 April 1988"
  1737. X.SH NAME
  1738. Xunfsd_exports \- NFS file systems being exported by user-level NFS server
  1739. X.SH SYNOPSIS
  1740. X.B /etc/unfsd_exports
  1741. X.SH DESCRIPTION
  1742. X.IX  "NFS exported file systems"  ""  "NFS exported file systems \(em \fLexports\fP"
  1743. XThe file
  1744. X.I /etc/unfsd_exports
  1745. Xdescribes the file systems which are being exported to 
  1746. Xnfs clients.
  1747. XIt is processed by the
  1748. X.I user-level NFS
  1749. Xdaemon
  1750. X.IR unfsd (8C)
  1751. Xwhen the daemon is started.
  1752. X.PP
  1753. XThe file format is similar to that of the SunOS
  1754. X.I exports
  1755. Xfile.
  1756. XThe file is organized by lines.
  1757. XA # introduces a comment to the end of the line,
  1758. Xa \e preceding a new line disables the line break making the entry of
  1759. Xlong input lines more convenient.
  1760. XEach line consists of a mount point
  1761. Xand list of machine names
  1762. Xallowed to remote mount the server's file hierarchy at that mount point.
  1763. XA machine name is optionally followed by a list of mount parameters
  1764. Xenclosed in parentheses.
  1765. XThese are the parameters that are currently recognized.
  1766. X.ds d " *
  1767. X.ds n " +
  1768. X.TP 20
  1769. Xsecure\*d
  1770. XReject requests that originate on an internet port \(>= IPPORT_RESERVED.
  1771. X.TP 20
  1772. Xinsecure
  1773. XAccept requests originating on any port.
  1774. X.TP 20
  1775. Xroot_squash
  1776. XMap requests from uid 0 on the client to uid -2 on the server.
  1777. X.TP 20
  1778. Xno_root_squash\*d
  1779. XDon't map requests from uid 0.
  1780. X.TP 20
  1781. Xro\*d
  1782. XMount file hierarchy read-only.
  1783. X.TP 20
  1784. Xrw\*n
  1785. XMount file hierarchy read-write.
  1786. X.TP 20
  1787. Xlink_relative\*d
  1788. XConvert symbolic links starting with a slash into relative links
  1789. Xby prepending the necessary number of ../'s to get from the link directory
  1790. Xto the file hierarchy root on the server.
  1791. X.TP 20
  1792. Xlink_absolute
  1793. XLeave symbolic links starting with a slash as they are.
  1794. X.TP 20
  1795. Xmap_identity\*d
  1796. XAssume the client and server share the same uid/gid space.
  1797. X.TP 20
  1798. Xmap_daemon
  1799. XMap local and remote names and numeric ids using a lname/uid map
  1800. Xdaemon on the client from which the NFS
  1801. Xrequest originated, to map between the client and server uid spaces
  1802. X(see ugidd(8)).
  1803. X.PP
  1804. X(\*d indicates defaults,\*n indicates currently unimplemented features)
  1805. X.SH EXAMPLE
  1806. X.PP
  1807. X.ft CW
  1808. X.nf
  1809. X  /     snail whelk(map_identity) tusk(root_squash, map_daemon, ro)
  1810. X  /usr  usage(root_squash, map_daemon, ro)
  1811. X.fi
  1812. X.SH FILES
  1813. X/etc/unfsd_exports
  1814. X.SH SEE ALSO
  1815. Xmountd(8C)
  1816. Xunfsd(8C)
  1817. Xugidd(8C)
  1818. X.SH BUGS
  1819. XThe mount point at the start of each line is currently ignored.
  1820. XAuthorized clients may mount at any point in the server's hierarchy.
  1821. ________This_Is_The_END________
  1822. if test `wc -l < unfsd_exports.5` -ne 86; then
  1823.     echo 'shar: unfsd_exports.5 was damaged during transit (should have been 86 bytes)'
  1824. fi
  1825. fi        ; : end of overwriting check
  1826. echo 'x - unfsmntd.c'
  1827. if test -f unfsmntd.c; then echo 'shar: not overwriting unfsmntd.c'; else
  1828. sed 's/^X//' << '________This_Is_The_END________' > unfsmntd.c
  1829. X/* UNFSD - copyright Mark A Shand, May 1988.
  1830. X * This software maybe be used for any purpose provided
  1831. X * the above copyright notice is retained.  It is supplied
  1832. X * as is, with no warranty expressed or implied.
  1833. X */
  1834. X
  1835. X#include <errno.h>
  1836. X#include <sys/types.h>
  1837. X#include <sys/stat.h>
  1838. X#include <rpc/rpc.h>
  1839. X#include <sys/time.h>
  1840. X#include <sys/ioctl.h>
  1841. X#include "mount.h"
  1842. X
  1843. Xstatic struct timeval TIMEOUT = { 25, 0 };
  1844. X
  1845. X#ifdef DEBUG
  1846. X#include <ctype.h>
  1847. X#include <stdio.h>
  1848. Xstatic FILE *debuglog = NULL;
  1849. Xstatic char *pname = "umountd";
  1850. Xstatic char argbuf[512];
  1851. X
  1852. Xlogcall(name, arg, rqstp)
  1853. Xchar    *name;
  1854. Xchar    *arg;
  1855. Xstruct svc_req    *rqstp;
  1856. X{
  1857. X    int    i;
  1858. X
  1859. X    if (debuglog == NULL)
  1860. X    {
  1861. X        unsigned long tloc;
  1862. X        if ((debuglog = fopen("/tmp/umountd.log", "a+")) == NULL)
  1863. X            return;
  1864. X        time(&tloc);
  1865. X        fprintf(debuglog, "\n\nstarting %s at %s\n", pname, ctime(&tloc));
  1866. X    }
  1867. X    fprintf(debuglog, "%s [ %d %d ",
  1868. X        name,
  1869. X        rqstp->rq_cred.oa_flavor,
  1870. X        rqstp->rq_cred.oa_length);
  1871. X    if (rqstp->rq_cred.oa_flavor == AUTH_UNIX)
  1872. X    {
  1873. X        struct authunix_parms *unix_cred;
  1874. X        unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
  1875. X        fprintf(debuglog, "%.24s %s %d.%d ",
  1876. X            ctime(&unix_cred->aup_time),
  1877. X            unix_cred->aup_machname,
  1878. X            unix_cred->aup_uid,
  1879. X            unix_cred->aup_gid);
  1880. X        if (unix_cred->aup_len > 0)
  1881. X        {
  1882. X            for (i = 0; i < unix_cred->aup_len; i++)
  1883. X                fprintf(debuglog, "%c%d", (i==0?'(':','),
  1884. X                    unix_cred->aup_gids[i]);
  1885. X            fprintf(debuglog, ") ");
  1886. X        }
  1887. X    }
  1888. X    fprintf(debuglog, "]\n\t%s\n", arg);
  1889. X    fflush(debuglog);
  1890. X    return 0;
  1891. X}
  1892. X#else
  1893. X#define logcall(name, arg, client)
  1894. X#endif DEBUG
  1895. X
  1896. Xint
  1897. Xunfsmntd_init()
  1898. X{
  1899. X#ifndef DEBUG
  1900. X    int fd;
  1901. X
  1902. X    if (fork())
  1903. X        exit(0);
  1904. X    close(0);
  1905. X    close(1);
  1906. X    close(2);
  1907. X    if ((fd = open("/dev/tty", 2)) >= 0)
  1908. X    {
  1909. X        ioctl(fd, TIOCNOTTY, (char *)0);
  1910. X        (void) close(fd);
  1911. X    }
  1912. X#endif DEBUG
  1913. X    fh_init();
  1914. X}
  1915. X
  1916. Xvoid *
  1917. Xmountproc_null_1(argp, rqstp)
  1918. X    void *argp;
  1919. X    struct svc_req *rqstp;
  1920. X{
  1921. X    static char res;
  1922. X
  1923. X    bzero(&res, sizeof(res));
  1924. X    logcall("mountproc_null_1", "", rqstp);
  1925. X    return ((void *)&res);
  1926. X}
  1927. X
  1928. X
  1929. Xfhstatus *
  1930. Xmountproc_mnt_1(argp, rqstp)
  1931. X    dirpath *argp;
  1932. X    struct svc_req *rqstp;
  1933. X{
  1934. X    static fhstatus res;
  1935. X    struct stat stbuf;
  1936. X    extern int errno;
  1937. X
  1938. X    bzero(&res, sizeof(res));
  1939. X    logcall("mountproc_mnt_1", sprintf(argbuf, "%s", *argp), rqstp);
  1940. X    if (stat(*argp, &stbuf) < 0)
  1941. X        res.fhs_status = errno;
  1942. X    else if ((stbuf.st_mode & S_IFMT) != S_IFDIR)
  1943. X        res.fhs_status = ENOTDIR;
  1944. X    else
  1945. X    {
  1946. X        res.fhs_status = 0;
  1947. X        res.fhs_status = fh_create(&(res.fhstatus_u.fhs_fhandle),*argp);
  1948. X    }
  1949. X    return (&res);
  1950. X}
  1951. X
  1952. X
  1953. Xmountlist *
  1954. Xmountproc_dump_1(argp, rqstp)
  1955. X    void *argp;
  1956. X    struct svc_req *rqstp;
  1957. X{
  1958. X    static mountlist res;
  1959. X
  1960. X    bzero(&res, sizeof(res));
  1961. X    logcall("mountproc_dump_1", "", rqstp);
  1962. X    return (&res);
  1963. X}
  1964. X
  1965. X
  1966. Xvoid *
  1967. Xmountproc_umnt_1(argp, rqstp)
  1968. X    dirpath *argp;
  1969. X    struct svc_req *rqstp;
  1970. X{
  1971. X    static char res;
  1972. X
  1973. X    bzero(&res, sizeof(res));
  1974. X    logcall("mountproc_umnt_1", sprintf(argbuf, "%s", *argp), rqstp);
  1975. X    return ((void *)&res);
  1976. X}
  1977. X
  1978. X
  1979. Xvoid *
  1980. Xmountproc_umntall_1(argp, rqstp)
  1981. X    void *argp;
  1982. X    struct svc_req *rqstp;
  1983. X{
  1984. X    static char res;
  1985. X
  1986. X    bzero(&res, sizeof(res));
  1987. X    logcall("mountproc_umntall_1", "", rqstp);
  1988. X    return ((void *)&res);
  1989. X}
  1990. X
  1991. X
  1992. Xexports *
  1993. Xmountproc_export_1(argp, rqstp)
  1994. X    void *argp;
  1995. X    struct svc_req *rqstp;
  1996. X{
  1997. X    static exports res;
  1998. X    static groupnode resgr;
  1999. X
  2000. X    bzero(&res, sizeof(res));
  2001. X    logcall("mountproc_export_1", "", rqstp);
  2002. X    res.ex_dir = "/";
  2003. X    res.ex_groups = &resgr;
  2004. X    bzero(&resgr, sizeof(resgr));
  2005. X    resgr.gr_name = "mollusca";
  2006. X    resgr.gr_next = (groups *) 0;
  2007. X    res.ex_next = (exports *) 0;
  2008. X    return (&res);
  2009. X}
  2010. X
  2011. X
  2012. Xexports *
  2013. Xmountproc_exportall_1(argp, rqstp)
  2014. X    void *argp;
  2015. X    struct svc_req *rqstp;
  2016. X{
  2017. X    logcall("mountproc_exportall_1", "", rqstp);
  2018. X    return (mountproc_export_1(argp, rqstp));
  2019. X}
  2020. ________This_Is_The_END________
  2021. if test `wc -l < unfsmntd.c` -ne 191; then
  2022.     echo 'shar: unfsmntd.c was damaged during transit (should have been 191 bytes)'
  2023. fi
  2024. fi        ; : end of overwriting check
  2025. exit 0
  2026.