summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nfs/ChangeLog9
-rw-r--r--nfs/nfs.c13
-rw-r--r--nfs/nfs.h4
-rw-r--r--nfs/ops.c41
4 files changed, 55 insertions, 12 deletions
diff --git a/nfs/ChangeLog b/nfs/ChangeLog
index 3623a990..e32fc40e 100644
--- a/nfs/ChangeLog
+++ b/nfs/ChangeLog
@@ -1,3 +1,12 @@
+Tue May 20 15:35:39 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
+
+ * nfs.c (xdr_encode_create_state): New arg OWNER. Set the owner
+ of the new file to it. All callers changed.
+ * nfs.h (xdr_encode_create_state): Update prototype.
+ * ops.c (netfs_attempt_mkdir): If owner didn't get set correctly
+ (some servers ignore it) then try a chown.
+ (netfs_attempt_create_file): Likewise.
+
Thu Apr 10 13:25:12 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* ops.c (netfs_attempt_set_size): Short circuit EACCES to cover
diff --git a/nfs/nfs.c b/nfs/nfs.c
index ddeeb63e..5ccf7186 100644
--- a/nfs/nfs.c
+++ b/nfs/nfs.c
@@ -1,5 +1,5 @@
/* XDR frobbing and lower level routines for NFS client
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Written by Michael I. Bushnell, p/BSG.
This file is part of the GNU Hurd.
@@ -290,15 +290,17 @@ xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec *mtime)
return p;
}
-/* Encode MODE and a size of 0 into an otherwise empty sattr. */
+/* Encode MODE, a size of zero, and the specified owner into an otherwise
+ empty sattr. */
int *
xdr_encode_create_state (int *p,
- mode_t mode)
+ mode_t mode,
+ uid_t owner)
{
if (protocol_version == 2)
{
*p++ = htonl (hurd_mode_to_nfs_mode (mode));
- *p++ = -1; /* uid */
+ *p++ = htonl (owner); /* uid */
*p++ = -1; /* gid */
*p++ = 0; /* size */
*p++ = -1; /* atime sec */
@@ -310,7 +312,8 @@ xdr_encode_create_state (int *p,
{
*p++ = htonl (1); /* mode */
*p++ = htonl (hurd_mode_to_nfs_mode (mode));
- *p++ = 0; /* no uid */
+ *p++ = htonl (1); /* set uid */
+ *p++ = htonl (owner);
*p++ = 0; /* no gid */
*p++ = htonl (1); /* set size */
p = xdr_encode_64bit (p, 0);
diff --git a/nfs/nfs.h b/nfs/nfs.h
index 2007237c..51cd3e46 100644
--- a/nfs/nfs.h
+++ b/nfs/nfs.h
@@ -1,5 +1,5 @@
/* Data structures and global variables for NFS client
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -157,7 +157,7 @@ int *xdr_encode_sattr_ids (int *, u_int, u_int);
int *xdr_encode_sattr_size (int *, off_t);
int *xdr_encode_sattr_times (int *, struct timespec *, struct timespec *);
int *xdr_encode_sattr_stat (int *, struct stat *);
-int *xdr_encode_create_state (int *, mode_t);
+int *xdr_encode_create_state (int *, mode_t, uid_t);
int *xdr_decode_fattr (int *, struct stat *);
int *xdr_decode_string (int *, char *);
int *nfs_initialize_rpc (int, struct iouser *, size_t, void **,
diff --git a/nfs/ops.c b/nfs/ops.c
index 34c523f9..8b962c70 100644
--- a/nfs/ops.c
+++ b/nfs/ops.c
@@ -618,20 +618,38 @@ netfs_attempt_mkdir (struct iouser *cred, struct node *np,
int *p;
void *rpcbuf;
error_t err;
-
+ uid_t owner;
+ struct node *newnp;
+
+ if (cred->uids->num)
+ owner = cred->uids->ids[0];
+ else
+ {
+ err = netfs_validate_stat (np, cred);
+ owner = err ? 0 : np->nn_stat.st_uid;
+ mode &= ~S_ISUID;
+ }
+
p = nfs_initialize_rpc (NFSPROC_MKDIR (protocol_version),
cred, 0, &rpcbuf, np, -1);
p = xdr_encode_fhandle (p, &np->nn->handle);
p = xdr_encode_string (p, name);
- p = xdr_encode_create_state (p, mode);
+ p = xdr_encode_create_state (p, mode, owner);
err = conduct_rpc (&rpcbuf, &p);
if (!err)
err = nfs_error_trans (ntohl (*p++));
- /* Ignore returned information */
- /* XXX should probably cache it */
+ p = lookup_fhandle (p, &newnp);
+ p = process_returned_stat (newnp, p, 1);
+
+ /* Did we set the owner correctly? If not, try, but ignore failures. */
+ if (!netfs_validate_stat (newnp, cred) && newnp.nn_stat.st_uid != owner)
+ netfs_attempt_chown (cred, newnp, owner, newnp.nn_stat.st_gid);
+ /* We don't actually return this. */
+ netfs_nput (newnp);
+
free (rpcbuf);
return err;
}
@@ -958,6 +976,16 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np,
int *p;
void *rpcbuf;
error_t err;
+ uid_t owner;
+
+ if (cred->uids->num)
+ owner = cred->uids->ids[0];
+ else
+ {
+ err = netfs_validate_stat (np, cred);
+ owner = err ? 0 : np->nn_stat.st_uid;
+ mode &= ~S_ISUID;
+ }
/* RFC 1094 says that create is always exclusive. But Sun doesn't
actually *implement* the spec. No, of course not. So we have to do
@@ -987,7 +1015,7 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np,
p++;
}
else
- p = xdr_encode_create_state (p, mode);
+ p = xdr_encode_create_state (p, mode, owner);
err = conduct_rpc (&rpcbuf, &p);
@@ -1013,6 +1041,9 @@ netfs_attempt_create_file (struct iouser *cred, struct node *np,
if (*newnp)
mutex_lock (&(*newnp)->lock);
}
+
+ if (!netfs_validate_stat (*newnp, cred) && newnp.nn_stat.st_uid != owner)
+ netfs_attempt_chown (cred, newnp, owner, newnp.nn_stat.st_gid);
}
else
*newnp = 0;