Subject: Re: [netatalk-admins] netatalk's handling of file permissions is broken...
From: Jeff Wiegley (jeff@w3-design.com)
Date: Thu Nov 06 1997 - 21:21:10 EST
approx. seven steps ahead of you...
Roland Schulz wrote:
>
> Hi,
>
> > A for instance:
> >
> > I want *all* my directories to have a chmod of 2770.
> > This way any files a user creates inherits the group
> > that the directory belongs to and thus any members of
> > that group can access the files in this directory.
> >
> > and files which are created should get a mode of at
> > least 0660.
> >
>
I've already attacked the source code. and there are several problems
with this approach...
mostly the authors extremely abstracting use of:
int (**afp_switch)() = preauth_switch;
int (*postauth_switch[])() = {
NULL, afp_bytelock, afp_closevol, afp_null,
afp_closefork, afp_copyfile, afp_createdir, afp_createfile, /* 0
- 7 */
afp_delete, afp_enumerate, afp_flush, afp_flushfork,
afp_null, afp_null, afp_getforkparams, afp_null, /* 8
- 15 */
afp_getsrvrparms, afp_getvolparams, afp_login, afp_logincont,
afp_logout, afp_mapid, afp_mapname, afp_moveandrename, /* 16
- 23 */
afp_openvol, afp_null, afp_openfork, afp_read,
afp_rename, afp_setdirparams, afp_setfilparams, afp_setforkparams,
/* 24
- 31 */
afp_null, afp_write, afp_getfildirparams, afp_setfildirparams,
afp_changepw, afp_null, afp_getsrvrmesg, afp_null
/*afp_createid*/, /* 32 - 39 */
afp_null /*afp_deleteid*/, afp_null /*afp_resolveid*/, afp_null
/*afp_exchangefiles*/, afp_null,
afp_null, afp_null, afp_null, afp_null, /* 40
- 47 */
afp_opendt, afp_null, afp_null, afp_geticon,
afp_geticoninfo, afp_addappl, afp_rmvappl, afp_getappl, /* 48
- 55 */
afp_addcomment, afp_rmvcomment, afp_getcomment, NULL,
in etc/afpd/switch.c makes it nearly impossible to figure out what is
being
called which makes tracing what netatalk is trying to do very hard.
but besides that. Taking the high road I've spent all of today trying
exactly
what you mentioned below...
> Then how about patching the source in libatalk/adouble/ad_open.c,
> namely ad_mkdir?
>
> int
> ad_mkdir( path, mode )
> char *path;
> int mode;
> {
> ! return mkdir( path, ad_mode( path, mode ) );
> }
>
> => return mkdir( path, ad_mode( path, mode ) | <yourniftybitsofchoice> );
>
> That wasn't hard at all, agreed? Since afpd does only ad_mkdir(), not mkdir()
> itself you can put anything you like in there and it will be used for all
> calls in afpd. So now about files, this is a bit harder, since ad_open uses
oh yes, very easy ben kanobi...
have you tried this?
as it turns out ad_mkdir is called by afp_createdir() which, if you put
the proper...
stat(...);
syslog(...);
exit(-1);
just before the final return in afp_create not only does stat report
that the
directory just created has st_mode of 042770 when the function (and
therefore
afpd) dies the directory left in your filesystem has the proper mode:
drwxrws---
But!!
something, somewhere (after the call to afp_createdir has run and
completed its
task) is modifying the permissions of the newly created directory.
effectively
wiping out the sgid bit.
I've put syslog calls at every point in the program that either calls
chmod or
chown (the only two system functions I can think of that has the
abilities to
change permissions) and neither of these is called in reference to the
newly
created directory. sever chown/chmod calls are made to the AppleDouble
hierarchy but not the directory you just created.
and As I've mentioned the silly "switch.c" implementation makes it
impossible
to tell what major afp functions are being called next after the
directory
creation has completed.
So I can't find what is responsible for the bits changing after the
completion
of directory creation.
> more than one call to open which can create a file:
>
> if ( adflags & ADFLAGS_DF ) {
> if (( ad->ad_df.adf_fd =
> ! open( path, oflags, ad_mode( path, mode ) )) < 0 ) {
> return( -1 );
> }
>
> => open( path, oflags, ad_mode( path, mode ) | <yourniftybitsofchoice> )) < 0 ) {
>
> and
>
> if ( adflags & ADFLAGS_HF ) {
> ad_p = ad_path( path, adflags );
> ! admode = ad_mode( ad_p, mode );
>
> => admode = ad_mode( ad_p, mode ) | <yourniftybitsofchoice>;
files are not a huge problem. If the directories are modified such that
they
retain the gid bit that they inherit then files will inherit the proper
group
even in subfolders that have been created.
>
> An alternative way would be to patch ad_mode() itself, but then you'd need
> to check from there if it's a file or a directory.
>
> Sorry for the fake patches, this is directly from the source and therefore
> without any tests and guarantees :-)
Oh, I certainly don't mind the fake patches, they make perfect sense.
However
as I mentioned these aren't the places in the code entirely responsible
for
resetting a directories permissions.
>
> Use the source, Luke!
I am Ben but its a lot more complex than this and I'm a little
dissapointed
that the original authors designed netatalk to ignore the importance of
Unix
permission bits. Mac's never had decent file permissions why would you
limit
netatalk to the Mac's crippled implementation?
SAMBA has it right. you have a method of configuring samba to allows
clear
certain bits and always add certain bits to either files or directories.
Anything
not specified by these two masks gets inherited from either the client
or the
parent directory.
If I learn enough about the convolutions that netatalk is going through
when
dealing with permissions I'll write a patch that implements this same
behavior
in netatalk.
>
> Roland Schulz
> fi111@fen.baynet.de
- Jeff Wiegley
This archive was generated by hypermail 2b28 : Sat Dec 18 1999 - 16:28:00 EST