Subject: Re: [netatalk-admins] netatalk and group file permissions

From: [email-masked]
Date: Mon, 5 Jul 1999 11:00:46 +0100

> At 5:33 PM -0500 7/2/99, Buck Huppmann wrote:

> netatalk logs kweiss in, the GID assigned is 100, which is the default
> group in that passwd file, not the cdlstaff group. If I go to that
> directory at the Linux command line and attempt to write files, I get
> 'Permission denied' until I do a 'newgrp cdlstaff'. Then I can write
files.
> That's exactly the behavior I expect.

and Tim Carlson replied

>You shouldn't.. If you are a member of the group, regardless of whether it
>is your primary group, you should be able to write files into that
>directory.

Tim Carlson further said

>I would say that Linux is broken if this is how it does things.. Like what
>if you want to ftp something into a directory that is 775 for a certain
>group that you belong to but it isn't your primary group. Shouldn't you be
>able to write files to that directory?
>SunOS and Solaris have the behavior *I* would expect, but of course that
>is my primary background..

I've a similar background OS wise to Tim, but I'm also a big Linux user and
Linux does the right thing as Tim would have it, and not as described by
Buck in the first extract above. I checked this under Linux 2.0.36 and
2.2.1 and the behaviour is identical, as it should be. I think Buck needs
to check his Linux box. Meanwhile, if he wants the files to be owned by
cdlstaff, he just needs to do a chmod g+s on the directory, as I think
others have pointed out.

---

From: Buck Huppmann <[email-masked]>
Date: Mon, 5 Jul 1999 15:35:39 -0500

> >is my primary background..

Whereupon <[email-masked]> said

> Buck in the first extract above. I checked this under Linux 2.0.36 and
  ^^^^
  ouch. you misattribute. it wasn't me. i pointed to the ``bsdgroups''
  option explanation in the mount(8) man pages included with the linux
  distribution on this machine (redhat 6), wherein it says default
  file-creation behavior is to create files with gid of the calling
  process, unless bsd semantics are requested at mount time

> cdlstaff, he just needs to do a chmod g+s on the directory, as I think

Here's the kernel code excerpt from 2.0.36 (as destributed by Debian on
this other Linux box I'm using right now), from linux/fs/ext2/:

---
ialloc.c: in function
	struct inode * ext2_new_inode (const struct inode * dir, int mode, int * err)

        if (test_opt (sb, GRPID))
                inode->i_gid = dir->i_gid;
        else if (dir->i_mode & S_ISGID) {
                inode->i_gid = dir->i_gid;
                if (S_ISDIR(mode))
                        mode |= S_ISGID;
        } else
                inode->i_gid = current->fsgid;

sb.c: in function
	static int parse_options (char * options, unsigned long * sb_block,
                          unsigned short *resuid, unsigned short * resgid,
                          unsigned long * mount_options)

                else if (!strcmp (this_char, "grpid") ||
                         !strcmp (this_char, "bsdgroups"))
                        set_opt (*mount_options, GRPID);
                else if (!strcmp (this_char, "nogrpid") ||
                         !strcmp (this_char, "sysvgroups"))
                        clear_opt (*mount_options, GRPID);
---

So if you mount the device without electing options along these lines
you *should* get inodes created with inode->i_gid == current->fs_gid,
unless the directory is SGID. (As best i can tell, a call to open()
will not change the current->fsgid; rather, in_group_p() is called
with the gid of the inode of the directory into which a write is
being attempted; viz., from linux/kernel/

---
sys.c:
	int in_group_p(gid_t grp)
	{
		int     i;

		if (grp == current->fsgid)
			return 1;

		for (i = 0; i < NGROUPS; i++) {
			if (current->groups[i] == NOGROUP)
				break;
			if (current->groups[i] == grp)
				return 1;
		}
		return 0;
	}
---

and permission is granted if this returns true.)

With the BSD ``semantics'', inode->i_gid == dir->i_gid

As far as the comparative virtues of other *n*xes in this regard,
SunOS 4 has the same mounting hack support. (See open(2).) FWIW, OTOH,
for OpenBSD 2.5 the open(2) man page says the following:

     When a new file is created it is given the group of the directory which
     contains it.

Kernel excerpts omitted b/c I'm already way out on a limb as far as
stretching my understanding of *n*x/programming and b/c the last thing
I want to do is run afoul of the intellectual property rights of the
Regents of the University of California, having already abused the Linux
kernel hackers' and this message being a follow-up to a message from
someone in the upper echelons of the UC system

As for said someone's problem getting his shell to write into a directory
with ownership different from his process {e,fs}gid, . . . Is there some
evil program calling setgroups() before execve-ing your shell? Or does
your login program not call initgroups() ? I'm afraid that this one's a
mystery to me. Anybody?

As for the netatalk code itself, the only set[re]*uid() call it makes
are in netatalk/etc/afp/auth.c at initial login, as far as i can tell,
so I don't think it's making any heroic efforts to waylay your direc-
tory hierarchies' ownerships

buck