From f44d3a4bc1d086012171cf68d4e198c7b4f184f8 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 20 May 1997 19:57:13 +0000 Subject: Tue May 20 15:35:39 1997 Thomas Bushnell, n/BSG * 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. --- nfs/ChangeLog | 9 +++++++++ nfs/nfs.c | 13 ++++++++----- nfs/nfs.h | 4 ++-- nfs/ops.c | 41 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 55 insertions(+), 12 deletions(-) (limited to 'nfs') 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 + + * 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 * 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; -- cgit v1.2.3