chmod(2) problem

B.V.Dean B.V.Dean at ukc.ac.uk
Mon Sep 4 12:24:31 GMT 2000


You may remember I raised the issue of the POSIX semantics of chmod(2).
User xxx cannot chnage the mode bits on a file if it is owned by use yyy.

This problem arose when we had multiple authors writing web material to a 
shared folder on a SAMBA server (version 2.0.7) using Macromedia Dreamweaver.

We got (user xxx publishing to area with files owned by yyy):

utime(2) failing as it was not the file owner.
chmod(2) setting mode to 764 failing as it was not the owner.
chmod(2) setting mode to 664 (original setting) failing as it was not the 
owner.

The SAMBA config directive (dos filetimes = yes) fixed the utime(2) problem.
The SAMBA config directive (map archive = no) fixed the first chmod(2).

We still had the last problem. chmod trying to set mode 664, even though the
file was already this mode. I realised that this must be because it was not
doing a "MAP ARCHIVE", so SAMBA did not know it had to ignore it!

I decided to change the SAMBA source, I added a directive:

dos mode = Yes/No - Default of No.

The using the same "do you have write access" tests that appear in file_utime()
changed file_chmod().

The diffs are included below.

Does this look OK? Have I broken security or caused any side affects? The code
now works for me and Dreamweaver works. These changes have also fixed the 
problem that Dreamweaver always tried to update all files, not just those that 
had changed when you syncronised the site.

-----cur here ------ The diffs:

smbd/dosmode.c

*** dosmode.c.orig	Mon Sep  4 11:27:30 2000
--- dosmode.c	Mon Sep  4 09:57:55 2000
***************
*** 187,192 ****
--- 187,196 ----
    mode_t tmp;
    mode_t unixmode;
  
+   SMB_STRUCT_STAT sb;
+   extern struct current_user current_user;
+   int ret = -1;
+ 
    if (!st) {
      st = &st1;
      if (dos_stat(fname,st)) return(-1);
***************
*** 225,231 ****
      unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
    }
  
!   return(dos_chmod(fname,unixmode));
  }
  
  
--- 229,260 ----
      unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
    }
  
!   if(lp_dos_mode(SNUM(conn))) {
!     /* We want DOS semantics, ie allow non owner with write permission to change the
!        bits on a file. Just like file_utime below.
!     */
!     if(dos_stat(fname,&sb) != 0)
!       return -1;
!   
!     /* Check if we have write access. */
!     if (CAN_WRITE(conn)) {
!   	  if (((sb.st_mode & S_IWOTH) ||
!   	       conn->admin_user ||
!   	       ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
!   	       ((sb.st_mode & S_IWGRP) &&
!   		in_group(sb.st_gid,current_user.gid,
!   			 current_user.ngroups,current_user.groups)))) {
!   		  /* We are allowed to become root and change the filetime. */
!   		  become_root(False);
!   		  ret = dos_chmod(fname, unixmode);
!   		  unbecome_root(False);
!   	  }
!     }
!   
!     return( ret );
!   } else {  
!     return(dos_chmod(fname,unixmode));
!   }
  }
  
  
param/loadparm.c

*** loadparm.c.orig	Mon Sep  4 11:27:17 2000
--- loadparm.c	Mon Sep  4 09:50:44 2000
***************
*** 360,365 ****
--- 360,366 ----
    BOOL bDosFiletimes;
    BOOL bDosFiletimeResolution;
    BOOL bFakeDirCreateTimes;
+   BOOL bDosMode;
    BOOL bBlockingLocks;
    BOOL bInheritPerms; 
    char dummy[3]; /* for alignment */
***************
*** 466,471 ****
--- 467,473 ----
    False, /* bDosFiletimes */
    False, /* bDosFiletimeResolution */
    False, /* bFakeDirCreateTimes */
+   False, /* bDosMode */
    True,  /* bBlockingLocks */
    False, /* bInheritPerms */
    ""     /* dummy */
***************
*** 865,870 ****
--- 867,873 ----
    {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution,   NULL,  NULL,  FLAG_SHARE|FLAG_GLOBAL},
    
    {"fake directory create times", P_BOOL,P_LOCAL,  &sDefault.bFakeDirCreateTimes, NULL,   NULL, FLAG_SHARE|FLAG_GLOBAL},
+   {"dos mode", P_BOOL,P_LOCAL,  &sDefault.bDosMode, NULL,   NULL, FLAG_SHARE|FLAG_GLOBAL},
    {"panic action",     P_STRING,  P_GLOBAL, &Globals.szPanicAction,     NULL,   NULL,  0},
  
    {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL,   NULL, 0}
***************
*** 1404,1409 ****
--- 1407,1413 ----
  FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
  FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
  FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
+ FN_LOCAL_BOOL(lp_dos_mode,bDosMode)
  FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
  FN_LOCAL_BOOL(lp_inherit_perms,bInheritPerms)
  


Barry Dean
Senior Computing Officer
http://www.ukc.ac.uk/php/bvd/






More information about the samba-technical mailing list