Subject: [netatalk-admins] SOLVED(?): Shared Trash Problem

From: Neil McAllister <[email-masked]>
Date: Tue, 25 Aug 1998 21:18:15 -0700

OK, earlier today I posted a question about netatalk giving me the "Do you
want to delete this immediately?" message when more than one user tried to
put things into the trash on a shared volume.  I couldn't believe this was
"just the way it was" with netatalk -- such improper behavior! -- but a
quick read of the netatalk-admins archives showed that this problem had
indeed popped up in the past, and that nobody had yet figured it out.

Bob Smith ([email-masked]) posted the one "fix" I found.  I didn't read his
code and what he changed, but his fix involved patching afpd, and then
going in and manually creating all the "Trash Can #?" folders inside the
Network Trash Can folder, one for each individual user on the system.  I
didn't even bother to look into this any further, cuz with some 40+ users
to support on this machine (and new users coming and going with some
regularity) I knew it would be completely unmanageable, and so esoteric
that nobody but myself would ever be able to figure it out after I leave.
(Hey -- I wanna quit this job sometime, you know!)

Interestingly enough, Bob later said that he believed the eventual fix
would be an easy one, but that he didn't think it was a permissions
problem.  Well -- I'm here to tell you it IS a permissions problem.  I'll
explain, but first I'm going to post my entire fix (see if you like the
look of mine better than Bob's):

CAVEAT:  This "fix" will likely only work in a situation where all of your
netatalk users are in at least one common group, e.g. "macusers".

--------------------------------[cut here]-----------------------------------

NOTE: For purposes of this example, macadmin is any hypothetical user,
while macusers is a hypothetical group which MUST contain all the UIDs
which will be accessing your netatalk share.

1.  Go to [netatalk source dir]/etc/afpd/unix.c and change line 26 to read:

#define DIRBITS    S_ISGID | S_IWGRP

Recompile afpd, and then start up netatalk and afpd as usual.

2.  Go to the netatalk root shared directory where you're having the
problem, and do the following:

rm -rf Network\ Trash\ Folder
mkdir Network\ Trash\ Folder
chown macadmin:macusers Network\ Trash\ Folder
chmod 2777 Network\ Trash\ Folder

------------------------------[cut here]--------------------------------------

Do that -- AND YOU'RE DONE!  Your trash should be functioning properly.  It
should be making the "Trash Can #xx" folders properly for each user, and
deleting them as the users log out of the volume.  (Note that for Bob's
patch, you needed to create a Trash Can folder by hand for each individual
user, and then leave it lying around all the time.  Ugly.)

WHY MY HACK WORKS:

Ok, I said that the Network Trash Folder problem was indeed a permissions
problem.  The reason it didn't seem like it, to a lot of people, is because
it's the kind of permissions problem that no Unix admin would likely
imagine.

What seems to be the case, is that for the network trash to operate
properly, the Network Trash Can and the Trash Can Usage maps need to be
world read-writeable.  But the "Trash Can #xx" files are a special case.
Get this -- for whatever reason, in order to interpret those directories
properly, the Appleshare client just needs to see that they are WRITABLE.

Make sure you're clear on that -- it doesn't matter if they're readable.
It doesn't matter if they're executable.  Just writable.  So for Unix
purposes, the user can't actually DO anything with someone else's Trash
Can.  You can't stat it, you can't copy anything to it.  (Am I wrong?)
Still, by making them writable, all the "Do you want to throw it away
immediately?" problems seem to disappear.

I have no explanation for this -- I don't understand the workings of the
Appletalk protocol, or of netatalk for that matter, one bit.  But this is
just the behavior I observed this afternoon/evening.

SO WHAT DID I CHANGE?

Netatalk does a procedure where it does a chmod g+s on each new directory
it creates.  To my mind, at least in the Macintosh file-sharing model, it
doesn't make much sense to create a directory SGID unless it is also
writable.  So I just changed the code in "unix.c" so that whenever afpd
creates a directory, it does a chmod g+ws instead of just g+s.

The downside is that every new directory that's created on a netatalk share
with this hack will be Group Writeable.  But then -- on my system that
seems to always be the case anyway??  If anyone can find fault with this, I
want to hear about it, before I make a big mistake!!!

The other part of it was creating a "clean slate" Network Trash Folder.  If
you create a folder like I show, make it SGID and world
read-write-executable, then the Trash Can Usage Map and the .AppleDouble
folders within will get created with the correct permissions automatically.
If the Trash Can Usage Map isn't world read-writeable, this won't work.

Does it sound good??  I just put in a 12-hour day at the office trying to
figure this bullshit out, so if anyone tells me I've contributed something
useful I'll be really happy.

Cheers!

--
Neil McAllister, Systems Administrator
Primo Angeli Inc., San Francisco, CA, USA
http://www.primo.com  mailto:[email-masked]

---

From: "Tan Chee Weei" <[email-masked]>
Date: Wed, 26 Aug 1998 17:44:38 +0900

As far as my own search through the archives goes, yours has been
the only report of being able to make certain changes that actually
allow the Trash Can ## mechanism to finally begin to work, if indeed
the solution you mentioned does the trick (I have yet to test it out).
That is, without self creating the subdirectories.

This thing has been bugging me for a while and I've been too busy lately
to work on finding out why the server code refuses to create the Trash Can
##
correctly.

Thanks for the insight.  At least it gives some starting point to try
to determine exactly where in afpd things went wrong.  Don't know
whether your fix had to make some compromises in terms of how permissions
are translated on the unix side.  However, its a good start.  Hope
to hear more from the community on this issue and further insights.

CW

---

From: [email-masked] (Bob Smith, Hammett & Edison, Inc.)
Date: Wed, 26 Aug 1998 15:02:51 -0700

>look of mine better than Bob's):
.
.
.
>properly, the Appleshare client just needs to see that they are WRITABLE.

Neil -

Hey, good find!  This is a major clue and actually confirms what I've
suspected all along.  When I said I didn't think it was a "permissions
problem" I was thinking in terms of a problem where the client attempted an
operation and was denied due to permissions on the Unix side.  In fact your
work-around shows the problem is that the client simply "looks" at the
permissions and decides on it's own whether it will be able to do what it
wants, without actually attempting the action.  This explains why debug logs
from afpd never showed what was going on, because there were no actual AFP
errors occurring.  Somewhere in afpd's translation between the actual Unix
permissions and the AppleShare modes reported to the client something is
"lost", and the Trash folders are being mis-represented causing the client to
decide it can't do anything with the Trash.

Tan Chee Weei <[email-masked]> earlier speculated that it has something
to do with setting a folder to gid 0, which means "no group" in AppleShare but
something entirely different in Unix.  If you let afpd create "Trash Can #N"
folders without any attempt to work around the problem, the folders end up
with rwx---rwx, and there is also an attempt by the client to set the folder
to gid 0, which afpd of course refuses to do.  As I understand it, your patch
will force the permissions to be rwx-w-rwx, or maybe rwx-wSrwx, and magically
the Trash works, but only if all users are in the group that the Trash folders
belong to.

So putting the pieces together, it appears that when the client creates a
folder with gid 0 meaning "no group", then later looks at the access
privileges to that folder, it expects to see group writeability regardless of
the actual group of the current user.  But with the normal afpd behavior, the
Trash folders would never be writeable by any group!  So the client would look
at the Trash folders, and not seeing group writeability on them, would decide
it couldn't use the Trash at all (the logic behind that decision is still
obscure, but my guess is that it involves compatibility with previous AFP
versions).

Your solution is a lot simpler than mine, but I am concerned about universally
assigning group write privilege to all new folders.  If you only have shared
volumes that must have group write anyway it's fine.  But I also have afpd
sharing "private" volumes, and if group write were on folders in some of those
volumes it would seriously compromise Unix security.  So in my case your fix
won't work, unless I expand it a bit so that the group write bit is only set
in certain "safe" circumstances, i.e. specifically on any folder called "Trash
Can #[0-9]*".  I think the better long-term solution is to do something about
emulating the gid 0 AppleShare behavior, there has been discussion of that but
it isn't all that easy to accomplish.  Until someone solves it that way, we
now have two different work-arounds one of which is probably suitable for any
particular situation.

Bob Smith
Hammett & Edison, Inc.
[email-masked]