-#define OLD_NTDOMAIN 1
-
/*
Unix SMB/Netbios implementation.
Version 1.9.
result |= lp_force_create_mode(SNUM(conn));
}
}
+
+ DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result ));
return(result);
}
********************************************************************/
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st)
{
- SMB_STRUCT_STAT st1;
- int mask=0;
- mode_t tmp;
- mode_t unixmode;
-
- if (!st) {
- st = &st1;
- if (vfs_stat(conn,fname,st)) return(-1);
- }
+ SMB_STRUCT_STAT st1;
+ int mask=0;
+ mode_t tmp;
+ mode_t unixmode;
+ int ret = -1;
- if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
+ if (!st) {
+ st = &st1;
+ if (vfs_stat(conn,fname,st))
+ return(-1);
+ }
- if (dos_mode(conn,fname,st) == dosmode) return(0);
+ if (S_ISDIR(st->st_mode))
+ dosmode |= aDIR;
- unixmode = unix_mode(conn,dosmode,fname);
+ if (dos_mode(conn,fname,st) == dosmode)
+ return(0);
- /* preserve the s bits */
- mask |= (S_ISUID | S_ISGID);
+ unixmode = unix_mode(conn,dosmode,fname);
- /* preserve the t bit */
+ /* preserve the s bits */
+ mask |= (S_ISUID | S_ISGID);
+
+ /* preserve the t bit */
#ifdef S_ISVTX
- mask |= S_ISVTX;
+ mask |= S_ISVTX;
#endif
- /* possibly preserve the x bits */
- if (!MAP_ARCHIVE(conn)) mask |= S_IXUSR;
- if (!MAP_SYSTEM(conn)) mask |= S_IXGRP;
- if (!MAP_HIDDEN(conn)) mask |= S_IXOTH;
-
- unixmode |= (st->st_mode & mask);
-
- /* 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;
- }
-
- /* if we previously had any w bits set then leave them alone
- whilst adding in the new w bits, if the new mode is not rdonly */
- if (!IS_DOS_READONLY(dosmode)) {
- unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
- }
-
- return(vfs_chmod(conn,fname,unixmode));
+ /* possibly preserve the x bits */
+ if (!MAP_ARCHIVE(conn))
+ mask |= S_IXUSR;
+ if (!MAP_SYSTEM(conn))
+ mask |= S_IXGRP;
+ if (!MAP_HIDDEN(conn))
+ mask |= S_IXOTH;
+
+ unixmode |= (st->st_mode & mask);
+
+ /* 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;
+ }
+
+ /* if we previously had any w bits set then leave them alone
+ whilst adding in the new w bits, if the new mode is not rdonly */
+ if (!IS_DOS_READONLY(dosmode)) {
+ unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
+ }
+
+ if ((ret = vfs_chmod(conn,fname,unixmode)) == 0)
+ return 0;
+
+ if((errno != EPERM) && (errno != EACCES))
+ return -1;
+
+ if(!lp_dos_filemode(SNUM(conn)))
+ return -1;
+
+ /* We want DOS semantics, ie allow non owner with write permission to change the
+ bits on a file. Just like file_utime below.
+ */
+
+ /* Check if we have write access. */
+ if (CAN_WRITE(conn)) {
+ /*
+ * We need to open the file with write access whilst
+ * still in our current user context. This ensures we
+ * are not violating security in doing the fchmod.
+ * This file open does *not* break any oplocks we are
+ * holding. We need to review this.... may need to
+ * break batch oplocks open by others. JRA.
+ */
+ files_struct *fsp = open_file_fchmod(conn,fname,st);
+ if (!fsp)
+ return -1;
+ become_root();
+ ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode);
+ unbecome_root();
+ close_file_fchmod(fsp);
+ }
+
+ return( ret );
}
errno = 0;
- if(conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times) == 0)
+ if(conn->vfs_ops.utime(conn,fname, times) == 0)
return 0;
if((errno != EPERM) && (errno != EACCES))
current_user.ngroups,current_user.groups)))) {
/* We are allowed to become root and change the filetime. */
become_root();
- ret = conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times);
+ ret = conn->vfs_ops.utime(conn,fname, times);
unbecome_root();
}
}
return(True);
}
-
-#undef OLD_NTDOMAIN