summaryrefslogtreecommitdiff
path: root/libdiskfs/node-create.c
diff options
context:
space:
mode:
authorMarcus Brinkmann <marcus@gnu.org>2002-05-01 03:00:44 +0000
committerMarcus Brinkmann <marcus@gnu.org>2002-05-01 03:00:44 +0000
commitd74586f4e6d0688dfce0b662df60ee443c1cb91e (patch)
tree2d5592e60674b2ad89f9deb8b6ecd46068f3aa77 /libdiskfs/node-create.c
parentf8417e16aac161415a64bfd4593253ccedab94ef (diff)
2002-04-30 Marcus Brinkmann <marcus@gnu.org>
* priv.h: Add OPT_NO_INHERIT_DIR_GROUP and OPT_INHERIT_DIR_GROUP. (_diskfs_no_inherit_dir_group): New declaration. * node-create.c (_diskfs_no_inherit_dir_group): New variable. (diskfs_create_node): Implement SysV group behaviour. * opts-common.c (diskfs_common_options): Add --no-inherit-dir-group (--nogrpdir, --sysvgroups) and --inherit-dir-group (--grpdir, --bsdgroups). * opts-append-std.c (diskfs_append_std_options): Add --no-inherit-dir-group if set. * opts-std-startup.c (parse_startup_opt): Add toggle for _diskfs_no_inherit_dir_group. * opts-std-runtime.c (struct parse_hook): Add noinheritdirgroup. (set_opts): Handle H->noinheritdirgroup. (parse_opt): Initialize H->noinheritdirgroup. Handle OPT_NO_INHERIT_DIR_GROUP and OPT_INHERIT_DIR_GROUP.
Diffstat (limited to 'libdiskfs/node-create.c')
-rw-r--r--libdiskfs/node-create.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c
index 7cbdade1..4a7d108d 100644
--- a/libdiskfs/node-create.c
+++ b/libdiskfs/node-create.c
@@ -17,6 +17,11 @@
#include "priv.h"
+/* This enables SysV style group behaviour. New nodes inherit the GID
+ of the user creating them unless the SGID bit is set of the parent
+ directory. */
+int _diskfs_no_inherit_dir_group;
+
/* Create a new node. Give it MODE; if that includes IFDIR, also
initialize `.' and `..' in the new directory. Return the node in NPP.
CRED identifies the user responsible for the call. If NAME is nonzero,
@@ -70,9 +75,40 @@ diskfs_create_node (struct node *dir,
if (np->author_tracks_uid)
np->dn_stat.st_author = newuid;
- newgid = dir->dn_stat.st_gid;
- if (!idvec_contains (cred->user->gids, newgid))
- mode &= ~S_ISGID;
+ if (!_diskfs_no_inherit_dir_group)
+ {
+ newgid = dir->dn_stat.st_gid;
+ if (!idvec_contains (cred->user->gids, newgid))
+ mode &= ~S_ISGID;
+ }
+ else
+ {
+ if (dir->dn_stat.st_mode & S_ISGID)
+ {
+ /* If the parent dir has the sgid bit set, inherit its gid.
+ If the new node is a directory, also inherit the sgid bit
+ set. */
+ newgid = dir->dn_stat.st_gid;
+ if (S_ISDIR (mode))
+ mode |= S_ISGID;
+ else
+ {
+ if (!idvec_contains (cred->user->gids, newgid))
+ mode &= ~S_ISGID;
+ }
+ }
+ else
+ {
+ if (cred->user->gids->num)
+ newgid = cred->user->gids->ids[0];
+ else
+ {
+ newgid = dir->dn_stat.st_gid;
+ mode &= ~S_ISGID;
+ }
+ }
+ }
+
err = diskfs_validate_group_change (np, newgid);
if (err)
goto change_err;