summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdiskfs/ChangeLog18
-rw-r--r--libdiskfs/node-create.c42
-rw-r--r--libdiskfs/opts-append-std.c2
-rw-r--r--libdiskfs/opts-common.c8
-rw-r--r--libdiskfs/opts-std-runtime.c9
-rw-r--r--libdiskfs/opts-std-startup.c2
-rw-r--r--libdiskfs/priv.h7
7 files changed, 83 insertions, 5 deletions
diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog
index 349781c0..dae8a933 100644
--- a/libdiskfs/ChangeLog
+++ b/libdiskfs/ChangeLog
@@ -1,3 +1,21 @@
+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.
+
2002-03-23 James A. Morrison <ja2morri@uwaterloo.ca>
* init-startup.c (_diskfs_init_completed): Use error, not
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;
diff --git a/libdiskfs/opts-append-std.c b/libdiskfs/opts-append-std.c
index 00e858fc..5eaf6cb8 100644
--- a/libdiskfs/opts-append-std.c
+++ b/libdiskfs/opts-append-std.c
@@ -42,6 +42,8 @@ diskfs_append_std_options (char **argz, unsigned *argz_len)
err = argz_add (argz, argz_len, "--no-exec");
if (!err && _diskfs_noatime)
err = argz_add (argz, argz_len, "--no-atime");
+ if (!err && _diskfs_no_inherit_dir_group)
+ err = argz_add (argz, argz_len, "--no-inherit-dir-group");
if (! err)
{
diff --git a/libdiskfs/opts-common.c b/libdiskfs/opts-common.c
index 97d511e0..d37c2868 100644
--- a/libdiskfs/opts-common.c
+++ b/libdiskfs/opts-common.c
@@ -47,5 +47,13 @@ const struct argp_option diskfs_common_options[] =
"Do not update file access times on disk for reads"},
{"noatime", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
{"atime", OPT_ATIME, 0, 0, "Do update file access times for reads normally"},
+ {"no-inherit-dir-group", OPT_NO_INHERIT_DIR_GROUP, 0, 0,
+ "Create new nodes with gid of the process"},
+ {"nogrpid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"sysvgroups", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"inherit-dir-group", OPT_INHERIT_DIR_GROUP, 0, 0,
+ "Create new nodes with gid of parent dir (default)"},
+ {"grpid", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
+ {"bsdgroups", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
{0, 0}
};
diff --git a/libdiskfs/opts-std-runtime.c b/libdiskfs/opts-std-runtime.c
index c619835f..177dfaf6 100644
--- a/libdiskfs/opts-std-runtime.c
+++ b/libdiskfs/opts-std-runtime.c
@@ -32,7 +32,8 @@ std_runtime_options[] =
struct parse_hook
{
- int readonly, sync, sync_interval, remount, nosuid, noexec, noatime;
+ int readonly, sync, sync_interval, remount, nosuid, noexec, noatime,
+ noinheritdirgroup;
};
/* Implement the options in H, and free H. */
@@ -79,6 +80,8 @@ set_opts (struct parse_hook *h)
_diskfs_noexec = h->noexec;
if (h->noatime != -1)
_diskfs_noatime = h->noatime;
+ if (h->noinheritdirgroup != -1)
+ _diskfs_no_inherit_dir_group = h->noinheritdirgroup;
free (h);
@@ -101,6 +104,8 @@ parse_opt (int opt, char *arg, struct argp_state *state)
case OPT_SUID_OK: h->nosuid = 0; break;
case OPT_EXEC_OK: h->noexec = 0; break;
case OPT_ATIME: h->noatime = 0; break;
+ case OPT_NO_INHERIT_DIR_GROUP: h->noinheritdirgroup = 1; break;
+ case OPT_INHERIT_DIR_GROUP: h->noinheritdirgroup = 0; break;
case 'n': h->sync_interval = 0; h->sync = 0; break;
case 's':
if (arg)
@@ -124,7 +129,7 @@ parse_opt (int opt, char *arg, struct argp_state *state)
h->sync = diskfs_synchronous;
h->sync_interval = -1;
h->remount = 0;
- h->nosuid = h->noexec = h->noatime = -1;
+ h->nosuid = h->noexec = h->noatime = h->noinheritdirgroup = -1;
/* We know that we have one child, with which we share our hook. */
state->child_inputs[0] = h;
diff --git a/libdiskfs/opts-std-startup.c b/libdiskfs/opts-std-startup.c
index 384a8231..e0569ef9 100644
--- a/libdiskfs/opts-std-startup.c
+++ b/libdiskfs/opts-std-startup.c
@@ -82,6 +82,8 @@ parse_startup_opt (int opt, char *arg, struct argp_state *state)
TOGGLE (_diskfs_nosuid, 'S', OPT_SUID_OK);
TOGGLE (_diskfs_noexec, 'E', OPT_EXEC_OK);
TOGGLE (_diskfs_noatime, 'A', OPT_ATIME);
+ TOGGLE (_diskfs_no_inherit_dir_group, OPT_INHERIT_DIR_GROUP,
+ OPT_NO_INHERIT_DIR_GROUP);
#undef TOGGLE
case 's':
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index d5ef60c5..a0ff9bbb 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -35,6 +35,11 @@ extern int _diskfs_nosuid, _diskfs_noexec;
/* This relaxes the requirement to set `st_atime'. */
extern int _diskfs_noatime;
+/* 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. */
+extern int _diskfs_no_inherit_dir_group;
+
/* This is the -C argument value. */
extern char *_diskfs_chroot_directory;
@@ -51,6 +56,8 @@ extern const struct argp_option diskfs_common_options[];
#define OPT_SUID_OK 600 /* --suid-ok */
#define OPT_EXEC_OK 601 /* --exec-ok */
#define OPT_ATIME 602 /* --atime */
+#define OPT_NO_INHERIT_DIR_GROUP 603 /* --no-inherit-dir-group */
+#define OPT_INHERIT_DIR_GROUP 604 /* --inherit-dir-group */
/* Common value for diskfs_common_options and diskfs_default_sync_interval. */
#define DEFAULT_SYNC_INTERVAL 5