Bug 3429 - Magic appearance of group writable bits
Summary: Magic appearance of group writable bits
Status: RESOLVED WORKSFORME
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: nmbd (show other bugs)
Version: 3.0.21a
Hardware: x64 FreeBSD
: P3 normal
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-01-20 05:38 UTC by Guido van Rooij
Modified: 2006-07-05 13:19 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Guido van Rooij 2006-01-20 05:38:21 UTC
NB: I mantioned nmbd as component, because smbd was not listed.

We are seeing the following problem on a samba installation (on FreebSD5).

Relevant smb.conf settings:
   create mask = 0644
   force create mode = 0664

We create a file on the samba server, form a unix shell:
[~/tmp/test] guido@server> touch test.txt
[~/tmp/test] guido@server> chmod 600 test.txt
[~/tmp/test] guido@server> ls -l
total 2
-rw-------  1 guido  users  6 Jan 20 13:07 test.txt

When we edit this file from a windows machine (using notepad), the
settings are as follows:
-rw--w----  1 guido  users  6 Jan 20 13:07 test.txt

This is due to the following:
In file_set_dosmode(), this happens:
        unixmode = unix_mode(conn,dosmode,fname, creating_file);

unixmode=0644

        /* if we previously had any r bits set then leave them alone */
        if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
                unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
                unixmode |= tmp;
        }
unixmode=0620

        if (!IS_DOS_READONLY(dosmode)) {
                unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
        }
unixmode still is 0620.

I believe that the current group settings on the file should also
be honoured. This gives the following patch:

--- dosmode.c.orig      Fri Dec  2 20:21:44 2005
+++ dosmode.c   Fri Jan 20 13:14:20 2006
@@ -413,6 +413,10 @@
        if (!IS_DOS_READONLY(dosmode)) {
                unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
        }
+       if ((tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
+               unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
+               unixmode |= tmp;
+       }
 
        if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0)
                return 0;
Comment 1 Simo Sorce 2006-01-25 11:09:03 UTC
(In reply to comment #0)
> NB: I mantioned nmbd as component, because smbd was not listed.
> 
> We are seeing the following problem on a samba installation (on FreebSD5).
> 
> Relevant smb.conf settings:
>    create mask = 0644
>    force create mode = 0664

Can you provide the global section as well the specific share section in full?

> We create a file on the samba server, form a unix shell:
> [~/tmp/test] guido@server> touch test.txt
> [~/tmp/test] guido@server> chmod 600 test.txt
> [~/tmp/test] guido@server> ls -l
> total 2
> -rw-------  1 guido  users  6 Jan 20 13:07 test.txt
> 
> When we edit this file from a windows machine (using notepad), the
> settings are as follows:
> -rw--w----  1 guido  users  6 Jan 20 13:07 test.txt
> 
> This is due to the following:
> In file_set_dosmode(), this happens:
>         unixmode = unix_mode(conn,dosmode,fname, creating_file);
> 
> unixmode=0644
> 
>         /* if we previously had any r bits set then leave them alone */
>         if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
>                 unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
>                 unixmode |= tmp;
>         }
> unixmode=0620

I do not see how these snippet of code can change the unixmode in this way
Have you seen that using a debugger?

I suppose st->st_mode is 600 in this case following the code we should have:
1. tmp = 600 & 444 == 400   == get all r in tmp
2. unixmode =  644 & ~(444) == 644 & 333 == 200  == remove all r from unixmode 
3. unixmode =  200 | tmp == 200 | 600 == 600  == add back all r to unixmode

no w bit is manipulated here.

>         if (!IS_DOS_READONLY(dosmode)) {
>                 unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
>         }
> unixmode still is 0620.
> 
> I believe that the current group settings on the file should also
> be honoured. This gives the following patch:
> 
> --- dosmode.c.orig      Fri Dec  2 20:21:44 2005
> +++ dosmode.c   Fri Jan 20 13:14:20 2006
> @@ -413,6 +413,10 @@
>         if (!IS_DOS_READONLY(dosmode)) {
>                 unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));

unixmode = unixmode | (st_mode & 222) == take all w from st_mode and add them in unixmode

in our case:
unixmode = 600 | (600 & 222)  == 600 

>         }
> +       if ((tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
> +               unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
> +               unixmode |= tmp;
> +       }

this makes it:
tmp = 600 & 222 == 200
unixmode = 600 & ~(222) == 600 & 555 == 400
unixmode = 400 | 200 == 600

which is basically the same result as above with a longer sequence as far as I can see.
 
>         if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0)
>                 return 0;
> 

Comment 2 Gerald (Jerry) Carter (dead mail address) 2006-07-05 13:19:37 UTC
closing.  no feedback.