summaryrefslogtreecommitdiff
path: root/nfsd/cache.c
diff options
context:
space:
mode:
authorThomas Bushnell <thomas@gnu.org>1996-08-07 19:03:53 +0000
committerThomas Bushnell <thomas@gnu.org>1996-08-07 19:03:53 +0000
commit19d0f00234b0884a31c8bd4b806c6d512baae9be (patch)
treeb1fbd27e19126286009ba2486e1fc49886b8d8d7 /nfsd/cache.c
parentfeecb48f23f7e3cff12f14a579a56b8b8143b275 (diff)
*** empty log message ***
Diffstat (limited to 'nfsd/cache.c')
-rw-r--r--nfsd/cache.c93
1 files changed, 64 insertions, 29 deletions
diff --git a/nfsd/cache.c b/nfsd/cache.c
index 745a7c8e..8b1ee134 100644
--- a/nfsd/cache.c
+++ b/nfsd/cache.c
@@ -23,6 +23,8 @@
#include <hurd/fsys.h>
#include <assert.h>
#include <string.h>
+#include <hurd/io.h>
+#include <hurd/auth.h>
#include "nfsd.h"
@@ -136,35 +138,40 @@ process_cred (int *p, struct idspec **credp)
{
int size = ntohl (*p++);
*credp = idspec_lookup (0, 0, 0, 0);
- return p + INTSIZE (size);
+ p += INTSIZE (size);
+ }
+ else
+ {
+ p++; /* skip size */
+ p++; /* skip seconds */
+ len = ntohl (*p++);
+ p += INTSIZE (len); /* skip hostname */
+
+ uid = p++; /* remember loc of uid */
+ *uid = ntohl (*uid);
+
+ firstgid = *p++; /* remember first gid */
+ gids = p; /* here's where the array will start */
+ ngids = ntohl (*p++);
+
+ /* Now swap the first gid to be the first element of the array */
+ *gids = firstgid;
+ ngids++; /* and count it */
+
+ /* And byteswap the gids */
+ for (i = 0; i < ngids; i++)
+ gids[i] = ntohl (gids[i]);
+
+ p += ngids - 1;
+
+ *credp = idspec_lookup (1, ngids, uid, gids);
}
-
- p++; /* skip size */
- p++; /* skip seconds */
- len = ntohl (*p++);
- p += INTSIZE (len); /* skip hostname */
-
- uid = p++; /* remember loc of uid */
- *uid = ntohl (*uid);
-
- firstgid = *p++; /* remember first gid */
- gids = p; /* here's where the array will start */
- ngids = ntohl (*p++);
-
- /* Now swap the first gid to be the first element of the array */
- *gids = firstgid;
- ngids++; /* and count it */
-
- /* And byteswap the gids */
- for (i = 1; i < ngids; i++)
- gids[i] = ntohl (gids[i]);
/* Next is the verf field; skip it entirely */
p++; /* skip id */
len = htonl (*p++);
p += INTSIZE (len);
- *credp = idspec_lookup (1, ngids, uid, gids);
return p;
}
@@ -239,7 +246,7 @@ fh_hash (char *fhandle, struct idspec *i)
for (n = 0; n < NFS_FHSIZE; n++)
hash += fhandle[n];
hash += (int) i >> 6;
- return hash;
+ return hash % FHHASH_TABLE_SIZE;
}
int *
@@ -342,7 +349,7 @@ scan_fhs ()
}
struct cache_handle *
-create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
+create_cached_handle (int fs, struct cache_handle *credc, file_t userport)
{
char fhandle[NFS_FHSIZE];
error_t err;
@@ -350,20 +357,35 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
int hash;
char *bp = fhandle + sizeof (int);
size_t handlelen = NFS_FHSIZE - sizeof (int);
+ mach_port_t newport, ref;
+ /* Authenticate USERPORT so that we can call file_getfh on it. */
+ ref = mach_reply_port ();
+ if (io_reauthenticate (userport, ref, MACH_MSG_TYPE_MAKE_SEND)
+ || auth_user_authenticate (authserver, ref, MACH_MSG_TYPE_MAKE_SEND,
+ &newport))
+ {
+ /* Reauthentication has failed, but maybe the filesystem will let
+ us call file_getfh anyway. */
+ newport = userport;
+ }
+ else
+ mach_port_deallocate (mach_task_self (), userport);
+ mach_port_destroy (mach_task_self (), ref);
+
+ /* Fetch the file handle */
*(int *)fhandle = fs;
err = file_getfh (newport, &bp, &handlelen);
+ mach_port_deallocate (mach_task_self (), newport);
if (err || handlelen != NFS_FHSIZE - sizeof (int))
- {
- mach_port_deallocate (mach_task_self (), newport);
- return 0;
- }
+ return 0;
if (bp != fhandle + sizeof (int))
{
bcopy (bp, fhandle + sizeof (int), NFS_FHSIZE - sizeof (int));
vm_deallocate (mach_task_self (), (vm_address_t) bp, handlelen);
}
+ /* Cache it */
hash = fh_hash (fhandle, credc->ids);
mutex_lock (&fhhashlock);
for (c = fhhashtable[hash]; c; c = c->next)
@@ -374,9 +396,22 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport)
nfreefh--;
c->references++;
mutex_unlock (&fhhashlock);
- mach_port_deallocate (mach_task_self (), newport);
return c;
}
+
+ /* Always call fsys_getfile so that we don't depend on the
+ particular open modes of the port passed in. */
+
+ err = fsys_getfile (lookup_filesystem (fs),
+ credc->ids->uids, credc->ids->nuids,
+ credc->ids->gids, credc->ids->ngids,
+ fhandle + sizeof (int), NFS_FHSIZE - sizeof (int),
+ &newport);
+ if (err)
+ {
+ mutex_unlock (&fhhashlock);
+ return 0;
+ }
/* Create it anew */
c = malloc (sizeof (struct cache_handle));