From 0922615405838af7430ef39490ee578711866320 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 07:40:06 +0000 Subject: more splitting of server.c created dosmode.c and filename.c (This used to be commit 534a90ca44641417c21f6ed6d4b94b1de60f808d) --- source3/smbd/dosmode.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 source3/smbd/dosmode.c (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c new file mode 100644 index 0000000000..c1af18d80b --- /dev/null +++ b/source3/smbd/dosmode.c @@ -0,0 +1,202 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + dos mode handling functions + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + +/**************************************************************************** + change a dos mode to a unix mode + base permission for files: + everybody gets read bit set + dos readonly is represented in unix by removing everyone's write bit + dos archive is represented in unix by the user's execute bit + dos system is represented in unix by the group's execute bit + dos hidden is represented in unix by the other's execute bit + Then apply create mask, + then add force bits. + base permission for directories: + dos directory is represented in unix by unix's dir bit and the exec bit + Then apply create mask, + then add force bits. +****************************************************************************/ +mode_t unix_mode(connection_struct *conn,int dosmode) +{ + mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); + + if ( !IS_DOS_READONLY(dosmode) ) + result |= (S_IWUSR | S_IWGRP | S_IWOTH); + + if (IS_DOS_DIR(dosmode)) { + /* We never make directories read only for the owner as under DOS a user + can always create a file in a read-only directory. */ + result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR); + /* Apply directory mask */ + result &= lp_dir_mode(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_dir_mode(SNUM(conn)); + } else { + if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) + result |= S_IXUSR; + + if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) + result |= S_IXGRP; + + if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) + result |= S_IXOTH; + + /* Apply mode mask */ + result &= lp_create_mode(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_create_mode(SNUM(conn)); + } + return(result); +} + + +/**************************************************************************** + change a unix mode to a dos mode +****************************************************************************/ +int dos_mode(connection_struct *conn,char *path,struct stat *sbuf) +{ + int result = 0; + extern struct current_user current_user; + + DEBUG(8,("dos_mode: %s\n", path)); + + if (CAN_WRITE(conn) && !lp_alternate_permissions(SNUM(conn))) { + if (!((sbuf->st_mode & S_IWOTH) || + conn->admin_user || + ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) || + ((sbuf->st_mode & S_IWGRP) && + in_group(sbuf->st_gid,current_user.gid, + current_user.ngroups,current_user.groups)))) + result |= aRONLY; + } else { + if ((sbuf->st_mode & S_IWUSR) == 0) + result |= aRONLY; + } + + if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) + result |= aARCH; + + if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) + result |= aSYSTEM; + + if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) + result |= aHIDDEN; + + if (S_ISDIR(sbuf->st_mode)) + result = aDIR | (result & aRONLY); + +#ifdef S_ISLNK +#if LINKS_READ_ONLY + if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) + result |= aRONLY; +#endif +#endif + + /* hide files with a name starting with a . */ + if (lp_hide_dot_files(SNUM(conn))) + { + char *p = strrchr(path,'/'); + if (p) + p++; + else + p = path; + + if (p[0] == '.' && p[1] != '.' && p[1] != 0) + result |= aHIDDEN; + } + + /* Optimization : Only call is_hidden_path if it's not already + hidden. */ + if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) + { + result |= aHIDDEN; + } + + DEBUG(8,("dos_mode returning ")); + + if (result & aHIDDEN) DEBUG(8, ("h")); + if (result & aRONLY ) DEBUG(8, ("r")); + if (result & aSYSTEM) DEBUG(8, ("s")); + if (result & aDIR ) DEBUG(8, ("d")); + if (result & aARCH ) DEBUG(8, ("a")); + + DEBUG(8,("\n")); + + return(result); +} + +/******************************************************************* +chmod a file - but preserve some bits +********************************************************************/ +int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) +{ + struct stat st1; + int mask=0; + int tmp; + int unixmode; + + if (!st) { + st = &st1; + if (sys_stat(fname,st)) return(-1); + } + + if (S_ISDIR(st->st_mode)) dosmode |= aDIR; + + if (dos_mode(conn,fname,st) == dosmode) return(0); + + unixmode = unix_mode(conn,dosmode); + + /* preserve the s bits */ + mask |= (S_ISUID | S_ISGID); + + /* preserve the t bit */ +#ifdef 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 + if the new mode is not rdonly */ + if (!IS_DOS_READONLY(dosmode) && + (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) { + unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH); + unixmode |= tmp; + } + + return(sys_chmod(fname,unixmode)); +} + -- cgit From c3effa8b599a6a0a2fe05487edc3a0d13e83d427 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 13:11:34 +0000 Subject: this completes the splitup of server.c. the splitup was done with an axe, not a scalpel, so there are some rough edges. I mostly wanted to get the general form right with fine tuning of what goes where to come later. Still, this is better than what we had before where server.c was a general repository for anything that didn't fit elsewhere. (This used to be commit a6d194886a4a5f7507fa37289ff96c1be56f14a6) --- source3/smbd/dosmode.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index c1af18d80b..9db3e208b5 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -200,3 +200,71 @@ int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) return(sys_chmod(fname,unixmode)); } + +/******************************************************************* +Wrapper around sys_utime that possibly allows DOS semantics rather +than POSIX. +*******************************************************************/ +int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) +{ + extern struct current_user current_user; + struct stat sb; + int ret = -1; + + errno = 0; + + if(sys_utime(fname, times) == 0) + return 0; + + if((errno != EPERM) && (errno != EACCES)) + return -1; + + if(!lp_dos_filetimes(SNUM(conn))) + return -1; + + /* We have permission (given by the Samba admin) to + break POSIX semantics and allow a user to change + the time on a file they don't own but can write to + (as DOS does). + */ + + if(sys_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 = sys_utime(fname, times); + unbecome_root(False); + } + } + + return ret; +} + +/******************************************************************* +Change a filetime - possibly allowing DOS semantics. +*******************************************************************/ +BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) +{ + struct utimbuf times; + + if (null_mtime(mtime)) return(True); + + times.modtime = times.actime = mtime; + + if (file_utime(conn, fname, ×)) { + DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + } + + return(True); +} + + -- cgit From 2c065107b149797e2a42a6c119f883d30be411eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Aug 1998 06:40:42 +0000 Subject: changed the default permissions code to do this: if ((sbuf->st_mode & S_IWUSR) == 0) result |= aRONLY; rather than the very complex user/group permissions checks we do currently. This is equivalent ot setting "alternate permissions = yes" in the old code. The change is motivated by three main reasons: 1) it's basically impossible to second guess whether a file is writeable without trying to open it for writing. ACLs, root squash etc just make it too hard. 2) setting it not RONLY if the owner can write is closer to what NT does (eg. look at a cdrom - files are not marked read only). 3) it prevents the silly problem of copying files from a read only share to a writeable share and then finding you can't write to them as windows preserves the RONLY flag. Lots of people get bitten by this when they drag a folder from a Samba drive. It also hurts some install programs. I have also added a new flag type for loadparm.c called FLAG_DEPRECATED which I've set for "alternate permissions". I'll soon add code to testparm to give a warning about deprecated options. (This used to be commit c4363a12fdc0be329ca2bfeb1d7b89bfe90031dc) --- source3/smbd/dosmode.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9db3e208b5..da7fdfb973 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -78,22 +78,11 @@ mode_t unix_mode(connection_struct *conn,int dosmode) int dos_mode(connection_struct *conn,char *path,struct stat *sbuf) { int result = 0; - extern struct current_user current_user; DEBUG(8,("dos_mode: %s\n", path)); - if (CAN_WRITE(conn) && !lp_alternate_permissions(SNUM(conn))) { - if (!((sbuf->st_mode & S_IWOTH) || - conn->admin_user || - ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) || - ((sbuf->st_mode & S_IWGRP) && - in_group(sbuf->st_gid,current_user.gid, - current_user.ngroups,current_user.groups)))) - result |= aRONLY; - } else { - if ((sbuf->st_mode & S_IWUSR) == 0) + if ((sbuf->st_mode & S_IWUSR) == 0) result |= aRONLY; - } if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; -- cgit From 18556274139cc5a00593471bd745354d98a35303 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Sep 1998 20:11:54 +0000 Subject: More abstraction of file system data types, to move to a 64 bit file interface for the NT SMB's. Created a new define, SMB_STRUCT_STAT that currently is defined to be struct stat - this wil change to a user defined type containing 64 bit info when the correct wrappers are written for 64 bit stat(), fstat() and lstat() calls. Also changed all sys_xxxx() calls that were previously just wrappers to the same call prefixed by a dos_to_unix() call into dos_xxxx() calls. This makes it explicit when a pathname translation is being done, and when it is not. Now, all sys_xxx() calls are meant to be wrappers to mask OS differences, and not silently converting filenames on the fly. Jeremy. (This used to be commit 28aa182dbffaa4ffd86047e608400de4b26e80eb) --- source3/smbd/dosmode.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index da7fdfb973..1336e27281 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -75,7 +75,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode) /**************************************************************************** change a unix mode to a dos mode ****************************************************************************/ -int dos_mode(connection_struct *conn,char *path,struct stat *sbuf) +int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) { int result = 0; @@ -139,16 +139,16 @@ int dos_mode(connection_struct *conn,char *path,struct stat *sbuf) /******************************************************************* chmod a file - but preserve some bits ********************************************************************/ -int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) +int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st) { - struct stat st1; + SMB_STRUCT_STAT st1; int mask=0; int tmp; int unixmode; if (!st) { st = &st1; - if (sys_stat(fname,st)) return(-1); + if (dos_stat(fname,st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -186,23 +186,23 @@ int dos_chmod(connection_struct *conn,char *fname,int dosmode,struct stat *st) unixmode |= tmp; } - return(sys_chmod(fname,unixmode)); + return(dos_chmod(fname,unixmode)); } /******************************************************************* -Wrapper around sys_utime that possibly allows DOS semantics rather +Wrapper around dos_utime that possibly allows DOS semantics rather than POSIX. *******************************************************************/ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) { extern struct current_user current_user; - struct stat sb; + SMB_STRUCT_STAT sb; int ret = -1; errno = 0; - if(sys_utime(fname, times) == 0) + if(dos_utime(fname, times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -217,7 +217,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(sys_stat(fname,&sb) != 0) + if(dos_stat(fname,&sb) != 0) return -1; /* Check if we have write access. */ @@ -230,7 +230,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(False); - ret = sys_utime(fname, times); + ret = dos_utime(fname, times); unbecome_root(False); } } -- cgit From ac9b687cc2496409e1c8d86393812faf94ec7550 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Sep 1998 19:16:12 +0000 Subject: configure configure.in: Added tests for fseek64 and ftell64. config.h.in: Added fseek64 and ftell64. includes.h: Added definition of SMB_BIG_INTEGER. smb.h: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. access.c: Tidyup of dbug statement. system.c: Added sys_fseek and sys_ftell. Changed mode calls to use mode_t. asyncdns.c: Tidyup of comment. loadparm.c: Tidyup of set_default_server_announce_type() function definition. ldap.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. nispass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. smbpass.c: Changed (*getsmbpwpos) and (*setsmbpwpos) to use SMB_BIG_INTEGER. smbpassfile.c: Use sys_fseek(). chgpasswd.c: Tidyup of debug statement. dosmode.c: Changed mode calls to use mode_t. ipc.c: Removal of dead code. nttrans.c: Changed mode calls to use mode_t. open.c: Changed mode calls to use mode_t. pipes.c: Removal of dead code. reply.c: Removal of dead code. trans2.c: Removal of dead code. Changed mode calls to use mode_t. Jeremy. (This used to be commit c381d32e3dc23fe887408016cae821aceb30da2c) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 1336e27281..c2c9cc2373 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -144,7 +144,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * SMB_STRUCT_STAT st1; int mask=0; int tmp; - int unixmode; + mode_t unixmode; if (!st) { st = &st1; -- cgit From b8b67f4fab4a6fd686c5796c2701882197a7bd9d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Sep 1998 23:06:57 +0000 Subject: configure configure.in: Added checks for statvfs64. Last bit of 64 bit widening (I hope :-). include/config.h.in: Added #undef STAT_STATVFS64. include/includes.h: Added SMB_STRUCT_STATVFS type, Changed SMB_BIG_INTEGER to SMB_BIG_UINT and SMB_BIG_INT types. include/smb.h: Added flag defines from CIFS spec. lib/debug.c: Fixed one more mode_t issue. lib/system.c: Added sys_statvfs wrapper. lib/util.c: Changed trim_string to use size_t. param/loadparm.c: Moved "blocking locks" into locking section. Alphabetised locking options. Question - shuld we do this for all options ? passdb/ldap.c: Changed SMB_BIG_INTEGER to SMB_BIG_UINT. passdb/nispass.c: Changed SMB_BIG_INTEGER to SMB_BIG_UINT. passdb/smbpass.c: Changed SMB_BIG_INTEGER to SMB_BIG_UINT. smbd/dfree.c: Changed to use 64 bit types if available. Moved to use unsigned types. smbd/dosmode.c: Fixed one more mode_t issue. smbd/negprot.c: Changed literals to be FLAG_ #defines. smbd/nttrans.c: Removed dead code. smbd/open.c: Changed disk_free call. smbd/process.c: Changed literals to be FLAG_ #defines. smbd/reply.c: Changed disk_free call. smbd/trans2.c: Fixed but in SMB_QUERY_FS_VOLUME_INFO call. Was using UNICODE - should use ascii. tests/summary.c: Added STAT_STATVFS64 check. Jeremy. (This used to be commit c512b1b91fb7f2a7a93b9033a33e06d966daadb4) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index c2c9cc2373..b74e11e643 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -143,7 +143,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * { SMB_STRUCT_STAT st1; int mask=0; - int tmp; + mode_t tmp; mode_t unixmode; if (!st) { -- cgit From 6d5ef2e92995df1cbf5cd3d7c6a33fe55cedb311 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 4 Apr 1999 06:25:13 +0000 Subject: Use VFS operations for file I/O. (This used to be commit cfddbdb62485256a947a30e04c753200451cbe1c) --- source3/smbd/dosmode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index b74e11e643..e6f1dc7206 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -148,7 +148,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (!st) { st = &st1; - if (dos_stat(fname,st)) return(-1); + if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -186,7 +186,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= tmp; } - return(dos_chmod(fname,unixmode)); + return(conn->vfs_ops.chmod(fname,unixmode)); } @@ -202,7 +202,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(dos_utime(fname, times) == 0) + if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -217,7 +217,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(dos_stat(fname,&sb) != 0) + if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0) return -1; /* Check if we have write access. */ @@ -230,7 +230,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(False); - ret = dos_utime(fname, times); + ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); unbecome_root(False); } } -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/dosmode.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index e6f1dc7206..27393fe1c6 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -50,7 +50,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode) can always create a file in a read-only directory. */ result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR); /* Apply directory mask */ - result &= lp_dir_mode(SNUM(conn)); + result &= lp_dir_mask(SNUM(conn)); /* Add in force bits */ result |= lp_force_dir_mode(SNUM(conn)); } else { @@ -64,7 +64,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode) result |= S_IXOTH; /* Apply mode mask */ - result &= lp_create_mode(SNUM(conn)); + result &= lp_create_mask(SNUM(conn)); /* Add in force bits */ result |= lp_force_create_mode(SNUM(conn)); } @@ -148,7 +148,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (!st) { st = &st1; - if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1); + if (dos_stat(fname,st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -179,14 +179,12 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * } /* if we previously had any w bits set then leave them alone - if the new mode is not rdonly */ - if (!IS_DOS_READONLY(dosmode) && - (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) { - unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH); - unixmode |= tmp; + 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(conn->vfs_ops.chmod(fname,unixmode)); + return(dos_chmod(fname,unixmode)); } @@ -202,7 +200,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0) + if(dos_utime(fname, times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -217,7 +215,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0) + if(dos_stat(fname,&sb) != 0) return -1; /* Check if we have write access. */ @@ -230,7 +228,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(False); - ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); + ret = dos_utime(fname, times); unbecome_root(False); } } @@ -251,9 +249,8 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) if (file_utime(conn, fname, ×)) { DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + return False; } return(True); } - - -- cgit From 3a6c2069d77176bfa2b379ef711034396c477791 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jan 2000 01:41:04 +0000 Subject: Added "inherit permissions" patch. Fixed locking bug found by Andrew. Jeremy. (This used to be commit 38dffd360dc2e44bfc9e751f017e24f81ff0f2fa) --- source3/smbd/dosmode.c | 77 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 18 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 27393fe1c6..9690f115c4 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -26,33 +26,68 @@ extern int DEBUGLEVEL; /**************************************************************************** change a dos mode to a unix mode base permission for files: - everybody gets read bit set + if inheriting + apply read/write bits from parent directory. + else + everybody gets read bit set dos readonly is represented in unix by removing everyone's write bit dos archive is represented in unix by the user's execute bit dos system is represented in unix by the group's execute bit dos hidden is represented in unix by the other's execute bit - Then apply create mask, - then add force bits. + if !inheriting { + Then apply create mask, + then add force bits. + } base permission for directories: dos directory is represented in unix by unix's dir bit and the exec bit - Then apply create mask, - then add force bits. + if !inheriting { + Then apply create mask, + then add force bits. + } ****************************************************************************/ -mode_t unix_mode(connection_struct *conn,int dosmode) +mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); + mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ if ( !IS_DOS_READONLY(dosmode) ) result |= (S_IWUSR | S_IWGRP | S_IWOTH); - + + if (fname && lp_inherit_perms(SNUM(conn))) { + char *dname; + SMB_STRUCT_STAT sbuf; + + dname = parent_dirname(fname); + DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); + if (dos_stat(dname,&sbuf) != 0) { + DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); + return(0); /* *** shouldn't happen! *** */ + } + + /* Save for later - but explicitly remove setuid bit for safety. */ + dir_mode = sbuf.st_mode & ~S_ISUID; + DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); + /* Clear "result" */ + result = 0; + } + if (IS_DOS_DIR(dosmode)) { /* We never make directories read only for the owner as under DOS a user can always create a file in a read-only directory. */ - result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR); - /* Apply directory mask */ - result &= lp_dir_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_dir_mode(SNUM(conn)); + result |= (S_IFDIR | S_IWUSR); + + if (dir_mode) { + /* Inherit mode of parent directory. */ + result |= dir_mode; + } else { + /* Provisionally add all 'x' bits */ + result |= (S_IXUSR | S_IXGRP | S_IXOTH); + + /* Apply directory mask */ + result &= lp_dir_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_dir_mode(SNUM(conn)); + } } else { if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) result |= S_IXUSR; @@ -62,11 +97,17 @@ mode_t unix_mode(connection_struct *conn,int dosmode) if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) result |= S_IXOTH; - - /* Apply mode mask */ - result &= lp_create_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_create_mode(SNUM(conn)); + + if (dir_mode) { + /* Inherit 666 component of parent directory mode */ + result |= dir_mode + & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); + } else { + /* Apply mode mask */ + result &= lp_create_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_create_mode(SNUM(conn)); + } } return(result); } @@ -155,7 +196,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (dos_mode(conn,fname,st) == dosmode) return(0); - unixmode = unix_mode(conn,dosmode); + unixmode = unix_mode(conn,dosmode,fname); /* preserve the s bits */ mask |= (S_ISUID | S_ISGID); -- cgit From 16bb009dbbe6302febf3848cee61e9927eeb0fb5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 05:17:25 +0000 Subject: Mega-VFS merge. Yeah baby! Synopsis: change every disk access function to work through a vfs_ops structure contained in the connection_struct. (This used to be commit 3aad500c0fb61232ed3431ff4b743b5d18ec852f) --- source3/smbd/dosmode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9690f115c4..1ae1e7e2cb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -189,7 +189,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (!st) { st = &st1; - if (dos_stat(fname,st)) return(-1); + if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -225,7 +225,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - return(dos_chmod(fname,unixmode)); + return(conn->vfs_ops.chmod(fname,unixmode)); } @@ -241,7 +241,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(dos_utime(fname, times) == 0) + if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -256,7 +256,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(dos_stat(fname,&sb) != 0) + if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0) return -1; /* Check if we have write access. */ @@ -269,7 +269,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(False); - ret = dos_utime(fname, times); + ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); unbecome_root(False); } } -- cgit From ae7696117e81bb469fa71f9bc880f6b5aac0724e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 23:08:24 +0000 Subject: Put back lots of missing calls to dos_to_unix(). Thanks to aono@cc.osaka-kyoiku.ac.jp (Tomoki AONO) (This used to be commit 176c405d2702a4245561ff56c8eac3c754a0dea3) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 1ae1e7e2cb..278a4ab5e3 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -225,7 +225,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - return(conn->vfs_ops.chmod(fname,unixmode)); + return(conn->vfs_ops.chmod(dos_to_unix(fname,False),unixmode)); } -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/dosmode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 278a4ab5e3..26fd2aff14 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -1,3 +1,5 @@ +#define OLD_NTDOMAIN 1 + /* Unix SMB/Netbios implementation. Version 1.9. @@ -295,3 +297,5 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) return(True); } + +#undef OLD_NTDOMAIN -- cgit From 651946153e41354769839fa6cbcfd36fd320efbe Mon Sep 17 00:00:00 2001 From: Shirish Kalele Date: Tue, 16 May 2000 01:13:16 +0000 Subject: The new msdfs implementation that uses symlinks to point to other servers. Very intuitive. Removed the dfs map parsing code and tdb maintenance code (files msdfs/parse_dfs_map.c & msdfs/msdfs_tdb.c), dfs map loading and unloading calls (param/loadparm.c smbd/server.c). Added code to display msdfs format symlinks as directories in a transact2_findfirst/findnext. (smbd/trans2.c) Modified msdfs/msdfs.c to use the msdfs symlinks to create dfs referrals. Changed msdfs/README to reflect new operability. (This used to be commit 6803d2574fab9e5931786d5c9aa5dc5867bb5f05) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 26fd2aff14..5b077110bb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -138,7 +138,7 @@ int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) if (S_ISDIR(sbuf->st_mode)) result = aDIR | (result & aRONLY); - + #ifdef S_ISLNK #if LINKS_READ_ONLY if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) -- cgit From 2a1dbb0acdc3acd837681e148729899fb0160836 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Jun 2000 05:57:48 +0000 Subject: Delete OriginalDir stuff. (This used to be commit 3d0f1845c8cefccfabcfd35694264c1e5f52c3af) --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 5b077110bb..8e2382ee9f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -270,9 +270,9 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) 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); + become_root(); ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); - unbecome_root(False); + unbecome_root(); } } -- cgit From b43b2e4f8a4be30e3f7aca6f570f5376fd508e3d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Sep 2000 19:09:59 +0000 Subject: Restructuring of the code to remove dos_ChDir/dos_GetWd and re-vector them through the VFS. All file access/directory access code in smbd should now go via the vfs. Added vfs_chown/vfs_chmod calls. Still looking at vfs_get_nt_acl() vfs_set_nt_acl() call API design. Jeremy. (This used to be commit f96625ec124adb6e110dc54632e006b3620a962b) --- source3/smbd/dosmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 8e2382ee9f..269d286517 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -61,7 +61,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) dname = parent_dirname(fname); DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (dos_stat(dname,&sbuf) != 0) { + if (vfs_stat(conn,dname,&sbuf) != 0) { DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); return(0); /* *** shouldn't happen! *** */ } @@ -191,7 +191,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (!st) { st = &st1; - if (conn->vfs_ops.stat(dos_to_unix(fname,False),st)) return(-1); + if (vfs_stat(conn,fname,st)) return(-1); } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; @@ -227,7 +227,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - return(conn->vfs_ops.chmod(dos_to_unix(fname,False),unixmode)); + return(vfs_chmod(conn,fname,unixmode)); } @@ -258,7 +258,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(conn->vfs_ops.stat(dos_to_unix(fname,False),&sb) != 0) + if(vfs_stat(conn,fname,&sb) != 0) return -1; /* Check if we have write access. */ -- cgit From 636f146abf0a75cd3b21a57b50627ee149a635ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 03:21:49 +0000 Subject: Restructuring of vfs layer to include a "this" pointer - can be an fsp or a conn struct depending on the call. We need this to have a clean NT ACL call interface. This will break any existing VFS libraries (that's why this is pre-release code). Andrew gets credit for this one :-) :-). In addition - added Herb's WITH_PROFILE changes - Herb - please examine the changes I've made to the smbd/reply.c code you added. The original code was very ugly and I have replaced it with a START_PROFILE(x)/END_PROFILE(x) pair using the preprocessor. Please check this compiles ok with the --with-profile switch. Jeremy. (This used to be commit b07611f8159b0b3f42e7e02611be9f4d56de96f5) --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 269d286517..377cfbb7cf 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -243,7 +243,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(conn->vfs_ops.utime(dos_to_unix(fname, False), times) == 0) + if(conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -271,7 +271,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = conn->vfs_ops.utime(dos_to_unix(fname, False), times); + ret = conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times); unbecome_root(); } } -- cgit From 615af12cf2171001bc7da716cea25eab57ec3f4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Jan 2001 20:34:37 +0000 Subject: Fix from "B.V.Dean" to add "dos filemode" parameter to allow a chmod to be done if the user has write access to a file, just like Windows allows. Off by default (compare with "dos filetimes" parameter). Jeremy. (This used to be commit 8abdf0e29fdb02a7929aa4395947b5023a7194a0) --- source3/smbd/dosmode.c | 106 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 36 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 377cfbb7cf..89e7c6b766 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -184,50 +184,84 @@ chmod a file - but preserve some bits ********************************************************************/ 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); - } + extern struct current_user current_user; + SMB_STRUCT_STAT st1; + int mask=0; + mode_t tmp; + mode_t unixmode; + int ret = -1; + + if (!st) { + st = &st1; + if (vfs_stat(conn,fname,st)) + return(-1); + } - if (S_ISDIR(st->st_mode)) dosmode |= aDIR; + if (S_ISDIR(st->st_mode)) + dosmode |= aDIR; - if (dos_mode(conn,fname,st) == dosmode) return(0); + if (dos_mode(conn,fname,st) == dosmode) + return(0); - unixmode = unix_mode(conn,dosmode,fname); + unixmode = unix_mode(conn,dosmode,fname); - /* preserve the s bits */ - mask |= (S_ISUID | S_ISGID); + /* preserve the s bits */ + mask |= (S_ISUID | S_ISGID); - /* preserve the t bit */ + /* 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)); + } + + ret = vfs_chmod(conn,fname,unixmode); + + 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)) { + if (((st->st_mode & S_IWOTH) || + conn->admin_user || + ((st->st_mode & S_IWUSR) && current_user.uid==st->st_uid) || + ((st->st_mode & S_IWGRP) && + in_group(st->st_gid,current_user.gid, current_user.ngroups,current_user.groups)))) { + /* We are allowed to become root and change the file mode. */ + become_root(); + ret = vfs_chmod(conn,fname,unixmode); + unbecome_root(); + } + } + + return( ret ); } -- cgit From aa7cd802062e60fa09c60cc396cfbf12fa08b935 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2001 23:41:01 +0000 Subject: Typo in new file_chmod code caused file attribute changes to fail. THIS NEEDS TO BE ADDED TO APPLIANCE-HEAD. Jeremy. (This used to be commit b92ccc0c8e5d066eeb077dfced6e717cd741c7a6) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 89e7c6b766..3a06dfe59a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -237,7 +237,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * ret = vfs_chmod(conn,fname,unixmode); - if((errno != EPERM) && (errno != EACCES)) + if((ret == -1) && (errno != EPERM) && (errno != EACCES)) return -1; if(!lp_dos_filemode(SNUM(conn))) -- cgit From ebee2c6c6d95de7aa5f17173b846c5ada24b6ccc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2001 23:47:08 +0000 Subject: Get the logic right thistime :-(. Jeremy. (This used to be commit 83596034cdecc7b03e35c0b4bb149e6bf9cebc70) --- source3/smbd/dosmode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 3a06dfe59a..31c4fbdf31 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -235,9 +235,10 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - ret = vfs_chmod(conn,fname,unixmode); + if ((ret = vfs_chmod(conn,fname,unixmode)) == 0) + return 0; - if((ret == -1) && (errno != EPERM) && (errno != EACCES)) + if((errno != EPERM) && (errno != EACCES)) return -1; if(!lp_dos_filemode(SNUM(conn))) -- cgit From 62dc55a43295e9e3abd9da13148b322b3aa89917 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Feb 2001 00:24:43 +0000 Subject: configure configure.in smbd/posix_acls.c smbd/dosmode.c: Fix for zero permission W2K profiles. libsmb/cliconnect.c rpc_client/cli_login.c smbd/reply.c: codepage fixes from Tim. Jeremy. (This used to be commit 3ded1e6bd5f79948e437ce5b1799705945f36ad2) --- source3/smbd/dosmode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 31c4fbdf31..a4b4f65ad9 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -111,6 +111,8 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) result |= lp_force_create_mode(SNUM(conn)); } } + + DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result )); return(result); } -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/dosmode.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a4b4f65ad9..8b2c482b0a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -1,5 +1,3 @@ -#define OLD_NTDOMAIN 1 - /* Unix SMB/Netbios implementation. Version 1.9. @@ -334,5 +332,3 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) return(True); } - -#undef OLD_NTDOMAIN -- cgit From 53850c51caf1c4d53ff285b2e5505e0615beeeee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Apr 2001 00:19:12 +0000 Subject: configure: configure.in: include/config.h.in: include/profile.h: smbd/vfs-wrap.c: smbd/vfs.c: Added fchmod and fchown to VFS (sorry Gerald - but we needed them anyway). smbd/dosmode.c: smbd/files.c: printing/printfsp.c: smbd/close.c: smbd/open.c: Fixed "dos filemode" correctly so there are no race conditions. Forces test of open of file O_WRONLY before allowing fchmod as root. Afterwards, calls standard close function that preserves POSIX locks due to POSIX-me-harder braindamage. :-). Andrew please review this code. Also - in removing the tmpdir param in smbrun an extra NULL parameter was missed in each print_run_command() call (which is a varargs fn.). Now fixed. Jeremy. (This used to be commit 32397e5bc6d995ce7ca37c82d6aedc1e5b1b6fbd) --- source3/smbd/dosmode.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 8b2c482b0a..9ec1fa2606 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -184,7 +184,6 @@ chmod a file - but preserve some bits ********************************************************************/ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st) { - extern struct current_user current_user; SMB_STRUCT_STAT st1; int mask=0; mode_t tmp; @@ -250,16 +249,21 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * /* Check if we have write access. */ if (CAN_WRITE(conn)) { - if (((st->st_mode & S_IWOTH) || - conn->admin_user || - ((st->st_mode & S_IWUSR) && current_user.uid==st->st_uid) || - ((st->st_mode & S_IWGRP) && - in_group(st->st_gid,current_user.gid, current_user.ngroups,current_user.groups)))) { - /* We are allowed to become root and change the file mode. */ - become_root(); - ret = vfs_chmod(conn,fname,unixmode); - unbecome_root(); - } + /* + * 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 ); -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9ec1fa2606..89e5b1586c 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -282,7 +282,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) 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)) @@ -310,7 +310,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) 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(); } } -- cgit From 527e824293ee934ca5da0ef5424efe5ab7757248 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:36:09 +0000 Subject: strchr and strrchr are macros when compiling with optimisation in gcc, so we can't redefine them. damn. (This used to be commit c41fc06376d1a2b83690612304e85010b5e5f3cf) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 89e5b1586c..639e365d1b 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -149,7 +149,7 @@ int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) /* hide files with a name starting with a . */ if (lp_hide_dot_files(SNUM(conn))) { - char *p = strrchr(path,'/'); + char *p = strrchr_m(path,'/'); if (p) p++; else -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/dosmode.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 639e365d1b..0f15ef25c2 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -21,8 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /**************************************************************************** change a dos mode to a unix mode base permission for files: -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/dosmode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 0f15ef25c2..6750649eff 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. dos mode handling functions Copyright (C) Andrew Tridgell 1992-1998 -- cgit From 5d1db25abd340c2c689f913788911b3a2f411b38 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 Mar 2002 01:43:50 +0000 Subject: Mask off the aDIR on setfileinfo. Jeremy. (This used to be commit d9cb1bf20ac8a739102b03d9a70e34fe5cb2f0f7) --- source3/smbd/dosmode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6750649eff..dcffe3aa90 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -195,6 +195,8 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT * if (S_ISDIR(st->st_mode)) dosmode |= aDIR; + else + dosmode &= ~aDIR; if (dos_mode(conn,fname,st) == dosmode) return(0); -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/dosmode.c | 92 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index dcffe3aa90..77d8c9cc92 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -115,65 +115,67 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) /**************************************************************************** change a unix mode to a dos mode ****************************************************************************/ -int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) +uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) { - int result = 0; + int result = 0; - DEBUG(8,("dos_mode: %s\n", path)); + DEBUG(8,("dos_mode: %s\n", path)); - if ((sbuf->st_mode & S_IWUSR) == 0) - result |= aRONLY; + if ((sbuf->st_mode & S_IWUSR) == 0) + result |= aRONLY; + + if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) + result |= aARCH; - if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) - result |= aARCH; - - if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) - result |= aSYSTEM; - - if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) - result |= aHIDDEN; + if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) + result |= aSYSTEM; + + if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) + result |= aHIDDEN; - if (S_ISDIR(sbuf->st_mode)) - result = aDIR | (result & aRONLY); + if (S_ISDIR(sbuf->st_mode)) + result = aDIR | (result & aRONLY); + + if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) { + result |= FILE_ATTRIBUTE_SPARSE; + } #ifdef S_ISLNK #if LINKS_READ_ONLY - if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) - result |= aRONLY; + if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) + result |= aRONLY; #endif #endif - /* hide files with a name starting with a . */ - if (lp_hide_dot_files(SNUM(conn))) - { - char *p = strrchr_m(path,'/'); - if (p) - p++; - else - p = path; - - if (p[0] == '.' && p[1] != '.' && p[1] != 0) - result |= aHIDDEN; - } - - /* Optimization : Only call is_hidden_path if it's not already - hidden. */ - if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) - { - result |= aHIDDEN; - } - - DEBUG(8,("dos_mode returning ")); + /* hide files with a name starting with a . */ + if (lp_hide_dot_files(SNUM(conn))) { + char *p = strrchr_m(path,'/'); + if (p) + p++; + else + p = path; + + if (p[0] == '.' && p[1] != '.' && p[1] != 0) + result |= aHIDDEN; + } + + /* Optimization : Only call is_hidden_path if it's not already + hidden. */ + if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { + result |= aHIDDEN; + } - if (result & aHIDDEN) DEBUG(8, ("h")); - if (result & aRONLY ) DEBUG(8, ("r")); - if (result & aSYSTEM) DEBUG(8, ("s")); - if (result & aDIR ) DEBUG(8, ("d")); - if (result & aARCH ) DEBUG(8, ("a")); + DEBUG(8,("dos_mode returning ")); - DEBUG(8,("\n")); + if (result & aHIDDEN) DEBUG(8, ("h")); + if (result & aRONLY ) DEBUG(8, ("r")); + if (result & aSYSTEM) DEBUG(8, ("s")); + if (result & aDIR ) DEBUG(8, ("d")); + if (result & aARCH ) DEBUG(8, ("a")); + + DEBUG(8,("\n")); - return(result); + return(result); } /******************************************************************* -- cgit From 266ec4aac04cb8666234f18baa38ff6387f40cb3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 03:09:08 +0000 Subject: Merge doxygen, signed/unsigned, const and other small fixes from HEAD to 3.0. Andrew Bartlett (This used to be commit 9ef0d40c3f8aef52ab321dc065264c42065bc876) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 77d8c9cc92..6c21dc04d0 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -181,7 +181,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) /******************************************************************* chmod a file - but preserve some bits ********************************************************************/ -int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st) +int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st) { SMB_STRUCT_STAT st1; int mask=0; -- cgit From e7c8c15888454043c73967635deb4d3419a489e9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 11 May 2003 23:34:18 +0000 Subject: Fix VFS layer: 1. Finally work with cascaded modules with private data storage per module 2. Convert VFS API to macro calls to simplify cascading 3. Add quota support to VFS layer (prepare to NT quota support) Patch by Stefan (metze) Metzemacher, with review of Jelmer and me Tested in past few weeks. Documentation to new VFS API for third-party developers to follow (This used to be commit 91984ef5caa2d13c5d52e1f535bd3bbbae1ec978) --- source3/smbd/dosmode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6c21dc04d0..6365db8f1e 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -56,7 +56,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) dname = parent_dirname(fname); DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (vfs_stat(conn,dname,&sbuf) != 0) { + if (VFS_STAT(conn,dname,&sbuf) != 0) { DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); return(0); /* *** shouldn't happen! *** */ } @@ -191,7 +191,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!st) { st = &st1; - if (vfs_stat(conn,fname,st)) + if (VFS_STAT(conn,fname,st)) return(-1); } @@ -235,7 +235,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = vfs_chmod(conn,fname,unixmode)) == 0) + if ((ret = VFS_CHMOD(conn,fname,unixmode)) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -262,7 +262,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!fsp) return -1; become_root(); - ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode); + ret = VFS_FCHMOD(fsp, fsp->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); } @@ -283,7 +283,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(conn->vfs_ops.utime(conn,fname, times) == 0) + if(VFS_UTIME(conn,fname, times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -298,7 +298,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(vfs_stat(conn,fname,&sb) != 0) + if(VFS_STAT(conn,fname,&sb) != 0) return -1; /* Check if we have write access. */ @@ -311,7 +311,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = conn->vfs_ops.utime(conn,fname, times); + ret = VFS_UTIME(conn,fname, times); unbecome_root(); } } -- cgit From bc2a3748e9caa8f60f7c2387e7eecd7fb3fae899 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 14 May 2003 10:59:01 +0000 Subject: Prefix VFS API macros with SMB_ for consistency and to avoid problems with VFS_ macros at system side. We currently have one clash with AIX and its VFS_LOCK. Compiled and tested -- no new functionality or code, just plain rename of macros for yet-unreleased VFS API version. Needs to be done before a24 is out (This used to be commit c2689ed118b490e49497a76ed6a2251262018769) --- source3/smbd/dosmode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6365db8f1e..aaee41b546 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -56,7 +56,7 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) dname = parent_dirname(fname); DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (VFS_STAT(conn,dname,&sbuf) != 0) { + if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) { DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); return(0); /* *** shouldn't happen! *** */ } @@ -191,7 +191,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!st) { st = &st1; - if (VFS_STAT(conn,fname,st)) + if (SMB_VFS_STAT(conn,fname,st)) return(-1); } @@ -235,7 +235,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = VFS_CHMOD(conn,fname,unixmode)) == 0) + if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -262,7 +262,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (!fsp) return -1; become_root(); - ret = VFS_FCHMOD(fsp, fsp->fd, unixmode); + ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); } @@ -283,7 +283,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) errno = 0; - if(VFS_UTIME(conn,fname, times) == 0) + if(SMB_VFS_UTIME(conn,fname, times) == 0) return 0; if((errno != EPERM) && (errno != EACCES)) @@ -298,7 +298,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(VFS_STAT(conn,fname,&sb) != 0) + if(SMB_VFS_STAT(conn,fname,&sb) != 0) return -1; /* Check if we have write access. */ @@ -311,7 +311,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) current_user.ngroups,current_user.groups)))) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = VFS_UTIME(conn,fname, times); + ret = SMB_VFS_UTIME(conn,fname, times); unbecome_root(); } } -- cgit From ec890d5c0fcb0ac9b3680d3c930614c726535d0a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 Oct 2003 03:56:42 +0000 Subject: Enclose usage of st_blksize and st_blocks struct stat members in #ifdef HAVE_STAT_ST_BLKSIZE and #ifdef HAVE_STAT_ST_BLOCKS, respectively. Fixes bug 550 reported by Joachim Schmitz . (This used to be commit 18adfdbe0c6ed79ba8ac07956b1e7abc226556c3) --- source3/smbd/dosmode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index aaee41b546..f88964123e 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -136,9 +136,11 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) if (S_ISDIR(sbuf->st_mode)) result = aDIR | (result & aRONLY); +#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE) if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) { result |= FILE_ATTRIBUTE_SPARSE; } +#endif #ifdef S_ISLNK #if LINKS_READ_ONLY -- cgit From 09a708815625f4c9e656cdbbf148a2ca2de73bc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 23:25:42 +0000 Subject: Patch from Jim McDonough for bug #802. Retrieve the correct ACL group bits if the file has an ACL. Jeremy. (This used to be commit 7bf5ed30ce74ba658ca35059955748c1d8cbd6d2) --- source3/smbd/dosmode.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index f88964123e..fb72a2eafc 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -183,6 +183,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) /******************************************************************* chmod a file - but preserve some bits ********************************************************************/ + int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st) { SMB_STRUCT_STAT st1; @@ -197,6 +198,8 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST return(-1); } + get_acl_group_bits(conn, fname, &st->st_mode); + if (S_ISDIR(st->st_mode)) dosmode |= aDIR; else -- cgit From 7cea655424467770600a7866eb3ac909ddf8fcab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Mar 2004 23:46:48 +0000 Subject: Fix for #1064 - ensure truncate attribute checking is done correctly on "hidden" dot files. Jeremy. (This used to be commit a6045c904fbe7df111c520134581bfd4f1ca67a8) --- source3/smbd/dosmode.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index fb72a2eafc..8353baeb21 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -111,16 +111,14 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) return(result); } - /**************************************************************************** change a unix mode to a dos mode ****************************************************************************/ -uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) + +uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) { int result = 0; - DEBUG(8,("dos_mode: %s\n", path)); - if ((sbuf->st_mode & S_IWUSR) == 0) result |= aRONLY; @@ -149,6 +147,30 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) #endif #endif + DEBUG(8,("dos_mode_from_sbuf returning ")); + + if (result & aHIDDEN) DEBUG(8, ("h")); + if (result & aRONLY ) DEBUG(8, ("r")); + if (result & aSYSTEM) DEBUG(8, ("s")); + if (result & aDIR ) DEBUG(8, ("d")); + if (result & aARCH ) DEBUG(8, ("a")); + + DEBUG(8,("\n")); + return result; +} + +/**************************************************************************** + change a unix mode to a dos mode +****************************************************************************/ +uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) +{ + int result = 0; + + DEBUG(8,("dos_mode: %s\n", path)); + + result = dos_mode_from_sbuf(conn, sbuf); + + /* Now do any modifications that depend on the path name. */ /* hide files with a name starting with a . */ if (lp_hide_dot_files(SNUM(conn))) { char *p = strrchr_m(path,'/'); -- cgit From e86972742066783406acc598cc21661e3b09d78e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 31 Mar 2004 22:46:15 +0000 Subject: Reformat in preparation for EA dosmode attributes. Jeremy (This used to be commit de2f149e9e687fc8cba6870d921341a6a1fd9c13) --- source3/smbd/dosmode.c | 248 +++++++++++++++++++++++++------------------------ 1 file changed, 125 insertions(+), 123 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 8353baeb21..1369c46b2f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -21,8 +21,8 @@ #include "includes.h" /**************************************************************************** - change a dos mode to a unix mode - base permission for files: + Change a dos mode to a unix mode. + Base permission for files: if inheriting apply read/write bits from parent directory. else @@ -35,84 +35,84 @@ Then apply create mask, then add force bits. } - base permission for directories: + Base permission for directories: dos directory is represented in unix by unix's dir bit and the exec bit if !inheriting { Then apply create mask, then add force bits. } ****************************************************************************/ -mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) + +mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname) { - mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); - mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ - - if ( !IS_DOS_READONLY(dosmode) ) - result |= (S_IWUSR | S_IWGRP | S_IWOTH); - - if (fname && lp_inherit_perms(SNUM(conn))) { - char *dname; - SMB_STRUCT_STAT sbuf; - - dname = parent_dirname(fname); - DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) { - DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); - return(0); /* *** shouldn't happen! *** */ - } - - /* Save for later - but explicitly remove setuid bit for safety. */ - dir_mode = sbuf.st_mode & ~S_ISUID; - DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); - /* Clear "result" */ - result = 0; - } - - if (IS_DOS_DIR(dosmode)) { - /* We never make directories read only for the owner as under DOS a user - can always create a file in a read-only directory. */ - result |= (S_IFDIR | S_IWUSR); - - if (dir_mode) { - /* Inherit mode of parent directory. */ - result |= dir_mode; - } else { - /* Provisionally add all 'x' bits */ - result |= (S_IXUSR | S_IXGRP | S_IXOTH); - - /* Apply directory mask */ - result &= lp_dir_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_dir_mode(SNUM(conn)); - } - } else { - if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) - result |= S_IXUSR; - - if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) - result |= S_IXGRP; + mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); + mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ + + if ( !IS_DOS_READONLY(dosmode) ) + result |= (S_IWUSR | S_IWGRP | S_IWOTH); + + if (fname && lp_inherit_perms(SNUM(conn))) { + char *dname; + SMB_STRUCT_STAT sbuf; + + dname = parent_dirname(fname); + DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); + if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) { + DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); + return(0); /* *** shouldn't happen! *** */ + } + + /* Save for later - but explicitly remove setuid bit for safety. */ + dir_mode = sbuf.st_mode & ~S_ISUID; + DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); + /* Clear "result" */ + result = 0; + } + + if (IS_DOS_DIR(dosmode)) { + /* We never make directories read only for the owner as under DOS a user + can always create a file in a read-only directory. */ + result |= (S_IFDIR | S_IWUSR); + + if (dir_mode) { + /* Inherit mode of parent directory. */ + result |= dir_mode; + } else { + /* Provisionally add all 'x' bits */ + result |= (S_IXUSR | S_IXGRP | S_IXOTH); + + /* Apply directory mask */ + result &= lp_dir_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_dir_mode(SNUM(conn)); + } + } else { + if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) + result |= S_IXUSR; + + if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) + result |= S_IXGRP; - if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) - result |= S_IXOTH; - - if (dir_mode) { - /* Inherit 666 component of parent directory mode */ - result |= dir_mode - & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); - } else { - /* Apply mode mask */ - result &= lp_create_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_create_mode(SNUM(conn)); - } - } - - DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result )); - return(result); + if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) + result |= S_IXOTH; + + if (dir_mode) { + /* Inherit 666 component of parent directory mode */ + result |= dir_mode & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); + } else { + /* Apply mode mask */ + result &= lp_create_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_create_mode(SNUM(conn)); + } + } + + DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result )); + return(result); } /**************************************************************************** - change a unix mode to a dos mode + Change a unix mode to a dos mode. ****************************************************************************/ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) @@ -160,8 +160,9 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) } /**************************************************************************** - change a unix mode to a dos mode + Change a unix mode to a dos mode. ****************************************************************************/ + uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) { int result = 0; @@ -203,7 +204,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) } /******************************************************************* -chmod a file - but preserve some bits + chmod a file - but preserve some bits. ********************************************************************/ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st) @@ -297,70 +298,71 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST return( ret ); } - /******************************************************************* -Wrapper around dos_utime that possibly allows DOS semantics rather -than POSIX. + Wrapper around dos_utime that possibly allows DOS semantics rather + than POSIX. *******************************************************************/ + int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) { - extern struct current_user current_user; - SMB_STRUCT_STAT sb; - int ret = -1; - - errno = 0; - - if(SMB_VFS_UTIME(conn,fname, times) == 0) - return 0; - - if((errno != EPERM) && (errno != EACCES)) - return -1; - - if(!lp_dos_filetimes(SNUM(conn))) - return -1; - - /* We have permission (given by the Samba admin) to - break POSIX semantics and allow a user to change - the time on a file they don't own but can write to - (as DOS does). - */ - - if(SMB_VFS_STAT(conn,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(); - ret = SMB_VFS_UTIME(conn,fname, times); - unbecome_root(); - } - } - - return ret; + extern struct current_user current_user; + SMB_STRUCT_STAT sb; + int ret = -1; + + errno = 0; + + if(SMB_VFS_UTIME(conn,fname, times) == 0) + return 0; + + if((errno != EPERM) && (errno != EACCES)) + return -1; + + if(!lp_dos_filetimes(SNUM(conn))) + return -1; + + /* We have permission (given by the Samba admin) to + break POSIX semantics and allow a user to change + the time on a file they don't own but can write to + (as DOS does). + */ + + if(SMB_VFS_STAT(conn,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(); + ret = SMB_VFS_UTIME(conn,fname, times); + unbecome_root(); + } + } + + return ret; } /******************************************************************* -Change a filetime - possibly allowing DOS semantics. + Change a filetime - possibly allowing DOS semantics. *******************************************************************/ + BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) { - struct utimbuf times; + struct utimbuf times; - if (null_mtime(mtime)) return(True); + if (null_mtime(mtime)) + return(True); - times.modtime = times.actime = mtime; + times.modtime = times.actime = mtime; - if (file_utime(conn, fname, ×)) { - DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); - return False; - } + if (file_utime(conn, fname, ×)) { + DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + return False; + } - return(True); + return(True); } -- cgit From 722aa118c66b020c2b9f2b595e1af50429f13986 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Apr 2004 18:46:19 +0000 Subject: Added per-share parameter "store dos attributes". When set, will store dos attributes in an EA. Based on an original patch from tridge, but modified somewhat to cover all cases. Jeremy. (This used to be commit ed653cd468213e0be901bc654aa3748ce5837947) --- source3/smbd/dosmode.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 1369c46b2f..d7dc63bb2f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -45,11 +45,12 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname) { - mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); + mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ - if ( !IS_DOS_READONLY(dosmode) ) - result |= (S_IWUSR | S_IWGRP | S_IWOTH); + if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) { + result &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + } if (fname && lp_inherit_perms(SNUM(conn))) { char *dname; @@ -159,22 +160,130 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) return result; } +/**************************************************************************** + Get DOS attributes from an EA. +****************************************************************************/ + +static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr) +{ + ssize_t sizeret; + fstring attrstr; + unsigned int dosattr; + + if (!lp_store_dos_attributes(SNUM(conn))) { + return False; + } + + *pattr = 0; + + sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr)); + if (sizeret == -1) { +#if defined(ENOTSUP) && defined(ENOATTR) + if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES)) { + DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n", + path, strerror(errno) )); + } +#endif + return False; + } + /* Null terminate string. */ + attrstr[sizeret] = 0; + DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n", path, attrstr)); + + if (sizeret < 2 || attrstr[0] != '0' || attrstr[1] != 'x' || + sscanf(attrstr, "%x", &dosattr) != 1) { + DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on file %s - %s\n", path, attrstr)); + return False; + } + + if (S_ISDIR(sbuf->st_mode)) { + dosattr |= aDIR; + } + *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK); + + DEBUG(8,("get_ea_dos_attribute returning (0x%x)", dosattr)); + + if (dosattr & aHIDDEN) DEBUG(8, ("h")); + if (dosattr & aRONLY ) DEBUG(8, ("r")); + if (dosattr & aSYSTEM) DEBUG(8, ("s")); + if (dosattr & aDIR ) DEBUG(8, ("d")); + if (dosattr & aARCH ) DEBUG(8, ("a")); + + DEBUG(8,("\n")); + + return True; +} + +/**************************************************************************** + Set DOS attributes in an EA. +****************************************************************************/ + +static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode) +{ + fstring attrstr; + files_struct *fsp = NULL; + BOOL ret = False; + + snprintf(attrstr, sizeof(attrstr)-1, "0x%x", dosmode & SAMBA_ATTRIBUTES_MASK); + if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == -1) { + if((errno != EPERM) && (errno != EACCES)) { + return False; + } + + /* 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) || !lp_dos_filemode(SNUM(conn))) + return False; + + /* + * 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 setxattr. + */ + + fsp = open_file_fchmod(conn,path,sbuf); + if (!fsp) + return ret; + become_root(); + if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) { + ret = True; + } + unbecome_root(); + close_file_fchmod(fsp); + return ret; + } + DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path)); + return True; +} + /**************************************************************************** Change a unix mode to a dos mode. ****************************************************************************/ -uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) +uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) { - int result = 0; + uint32 result = 0; DEBUG(8,("dos_mode: %s\n", path)); + if (!VALID_STAT(*sbuf)) { + return 0; + } + + /* Get the DOS attributes from an EA by preference. */ + if (get_ea_dos_attribute(conn, path, sbuf, &result)) { + return result; + } + result = dos_mode_from_sbuf(conn, sbuf); /* Now do any modifications that depend on the path name. */ /* hide files with a name starting with a . */ if (lp_hide_dot_files(SNUM(conn))) { - char *p = strrchr_m(path,'/'); + const char *p = strrchr_m(path,'/'); if (p) p++; else @@ -207,7 +316,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) chmod a file - but preserve some bits. ********************************************************************/ -int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st) +int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st) { SMB_STRUCT_STAT st1; int mask=0; @@ -215,6 +324,7 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST mode_t unixmode; int ret = -1; + DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); if (!st) { st = &st1; if (SMB_VFS_STAT(conn,fname,st)) @@ -231,6 +341,11 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST if (dos_mode(conn,fname,st) == dosmode) return(0); + /* Store the DOS attributes in an EA by preference. */ + if (set_ea_dos_attribute(conn, fname, st, dosmode)) { + return 0; + } + unixmode = unix_mode(conn,dosmode,fname); /* preserve the s bits */ -- cgit From 03d4344432c6aa75d400afc501aec1a14070f35d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Jun 2004 20:43:32 +0000 Subject: r971: Auto remove store dos attributes if underlying filesystem doesn't support EA's. Jeremy. (This used to be commit 9de6b25c9e9abe982e21b0229df520802cafbfd8) --- source3/smbd/dosmode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index d7dc63bb2f..33c75fffd5 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -182,6 +182,7 @@ static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES)) { DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n", path, strerror(errno) )); + set_store_dos_attributes(SNUM(conn), False); } #endif return False; @@ -224,9 +225,21 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ files_struct *fsp = NULL; BOOL ret = False; + if (!lp_store_dos_attributes(SNUM(conn))) { + return False; + } + snprintf(attrstr, sizeof(attrstr)-1, "0x%x", dosmode & SAMBA_ATTRIBUTES_MASK); if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == -1) { if((errno != EPERM) && (errno != EACCES)) { + if (errno == ENOSYS +#if defined(ENOTSUP) + || errno == ENOTSUP) { +#else + ) { +#endif + set_store_dos_attributes(SNUM(conn), False); + } return False; } -- cgit From 8df096a75e59e6b08f3358099ad51a7f52bf28b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Sep 2004 23:57:59 +0000 Subject: r2700: Fix bug where we could incorrectly set sparse attribute. Don't use st_blksize, it isn't what you think.... Jeremy. --his line, and those below, will be ignored-- M source/smbd/dosmode.c (This used to be commit 0a40c1a50f0e4b1b7efc9a53d22ceac14841bccf) --- source3/smbd/dosmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 33c75fffd5..7199b3ebbf 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -135,8 +135,8 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) if (S_ISDIR(sbuf->st_mode)) result = aDIR | (result & aRONLY); -#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE) - if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) { +#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) + if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) { result |= FILE_ATTRIBUTE_SPARSE; } #endif -- cgit From 193e82b0563da1a5b913432953f236d36008ef34 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 3 Nov 2004 00:32:08 +0000 Subject: r3496: Fix calling of get_acl_group_bits(). Guenther (This used to be commit 3acc74eef5dae16d7e2792206640904265c42494) --- source3/smbd/dosmode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 7199b3ebbf..3a3a6e6fdb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -344,7 +344,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, return(-1); } - get_acl_group_bits(conn, fname, &st->st_mode); + if (!get_acl_group_bits(conn, fname, &st->st_mode)) { + return(-1); + } if (S_ISDIR(st->st_mode)) dosmode |= aDIR; -- cgit From c0cad75f09ad393fc12a5e49abfac17d678c8ff2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 10 Nov 2004 23:12:02 +0000 Subject: r3673: Do not fail on setting file attributes with acl support enabled. Rolling back r3496 (close #2015). Guenther (This used to be commit e88ac807847bd016f9c921f01f788708b1564b5c) --- source3/smbd/dosmode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 3a3a6e6fdb..7199b3ebbf 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -344,9 +344,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, return(-1); } - if (!get_acl_group_bits(conn, fname, &st->st_mode)) { - return(-1); - } + get_acl_group_bits(conn, fname, &st->st_mode); if (S_ISDIR(st->st_mode)) dosmode |= aDIR; -- cgit From 46f546571bc2429c4ee6ef86866520c4b5d4bcc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Nov 2004 00:22:04 +0000 Subject: r4007: Fix bug #2088 - ensure inherit permissions is only applied on a new file, not an existing one. Jeremy. (This used to be commit fbbdb72cf1adfe567112556626f26b031747f440) --- source3/smbd/dosmode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 7199b3ebbf..fefcaca09d 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -23,7 +23,7 @@ /**************************************************************************** Change a dos mode to a unix mode. Base permission for files: - if inheriting + if creating file and inheriting apply read/write bits from parent directory. else everybody gets read bit set @@ -43,7 +43,7 @@ } ****************************************************************************/ -mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname) +mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ @@ -52,7 +52,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname) result &= ~(S_IWUSR | S_IWGRP | S_IWOTH); } - if (fname && lp_inherit_perms(SNUM(conn))) { + if (fname && creating_file && lp_inherit_perms(SNUM(conn))) { char *dname; SMB_STRUCT_STAT sbuf; @@ -329,7 +329,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) chmod a file - but preserve some bits. ********************************************************************/ -int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st) +int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file) { SMB_STRUCT_STAT st1; int mask=0; @@ -338,7 +338,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, int ret = -1; DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); - if (!st) { + if (!st || (st && !VALID_STAT(*st))) { st = &st1; if (SMB_VFS_STAT(conn,fname,st)) return(-1); @@ -359,7 +359,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, return 0; } - unixmode = unix_mode(conn,dosmode,fname); + unixmode = unix_mode(conn,dosmode,fname, creating_file); /* preserve the s bits */ mask |= (S_ISUID | S_ISGID); -- cgit From fcfa75b2fc19be9abe9580efa314d4c981f80098 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Mar 2005 22:34:28 +0000 Subject: r6049: Ensure "dos filetime" checks file ACLs correctly. May fix Excel "read-only" issue. Jeremy. (This used to be commit 80e788143a6c3d973d3b8e57d91ca5c4a83605b2) --- source3/smbd/dosmode.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index fefcaca09d..3a0e81e5fe 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -431,10 +431,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, than POSIX. *******************************************************************/ -int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) +int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times) { - extern struct current_user current_user; - SMB_STRUCT_STAT sb; int ret = -1; errno = 0; @@ -454,21 +452,12 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(SMB_VFS_STAT(conn,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(); - ret = SMB_VFS_UTIME(conn,fname, times); - unbecome_root(); - } + if (can_write_to_file(conn, fname)) { + /* We are allowed to become root and change the filetime. */ + become_root(); + ret = SMB_VFS_UTIME(conn,fname, times); + unbecome_root(); } return ret; @@ -478,7 +467,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) Change a filetime - possibly allowing DOS semantics. *******************************************************************/ -BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime) +BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) { struct utimbuf times; -- cgit From bd16770954424d86298a57d6c59aa69d5b42ce07 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 May 2005 23:37:35 +0000 Subject: r6895: Add "acl check permissions" to turn on/off the new behaviour of checking for write access in a directory before delete. Also controls checking for write access before labeling a file read-only if DOS attributes are not being stored in EA's. Docuementation to follow. Jeremy. (This used to be commit dd1a5e6e499dd721c5bb8d56a61810a7454a3449) --- source3/smbd/dosmode.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 3a0e81e5fe..65ea2807e7 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -116,13 +116,18 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c Change a unix mode to a dos mode. ****************************************************************************/ -uint32 dos_mode_from_sbuf(connection_struct *conn, SMB_STRUCT_STAT *sbuf) +uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result = 0; - if ((sbuf->st_mode & S_IWUSR) == 0) + if (lp_acl_check_permissions(SNUM(conn))) { + if (!can_write_to_file(conn, path, sbuf)) { + result |= aRONLY; + } + } else if ((sbuf->st_mode & S_IWUSR) == 0) { result |= aRONLY; - + } + if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; @@ -291,7 +296,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) return result; } - result = dos_mode_from_sbuf(conn, sbuf); + result = dos_mode_from_sbuf(conn, path, sbuf); /* Now do any modifications that depend on the path name. */ /* hide files with a name starting with a . */ @@ -433,9 +438,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times) { + SMB_STRUCT_STAT sbuf; int ret = -1; errno = 0; + ZERO_STRUCT(sbuf); if(SMB_VFS_UTIME(conn,fname, times) == 0) return 0; @@ -453,7 +460,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times */ /* Check if we have write access. */ - if (can_write_to_file(conn, fname)) { + if (can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); ret = SMB_VFS_UTIME(conn,fname, times); -- cgit From 6d39f3bdce5ba8ed7d88a430a2de9f96d4b2c513 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jun 2005 00:31:59 +0000 Subject: r7452: Set sparse flag if needed. Based on code from jpeach@sgi.com. Fixes bug #2774. Jeremy. (This used to be commit 5d366047debed68f36d44d34233ba4670e412d1e) --- source3/smbd/dosmode.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 65ea2807e7..3602e3f908 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -20,6 +20,16 @@ #include "includes.h" +static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) +{ +#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) + if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) { + return FILE_ATTRIBUTE_SPARSE; + } +#endif + return 0; +} + /**************************************************************************** Change a dos mode to a unix mode. Base permission for files: @@ -140,11 +150,7 @@ uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_ if (S_ISDIR(sbuf->st_mode)) result = aDIR | (result & aRONLY); -#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) { - result |= FILE_ATTRIBUTE_SPARSE; - } -#endif + result |= set_sparse_flag(sbuf); #ifdef S_ISLNK #if LINKS_READ_ONLY @@ -293,6 +299,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) /* Get the DOS attributes from an EA by preference. */ if (get_ea_dos_attribute(conn, path, sbuf, &result)) { + result |= set_sparse_flag(sbuf); return result; } -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 3602e3f908..a2bc424b8e 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -430,7 +430,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, if (!fsp) return -1; become_root(); - ret = SMB_VFS_FCHMOD(fsp, fsp->fd, unixmode); + ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); } -- cgit From 20f2305c50dc7eedd3b211a13937b2ed85235971 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Sep 2005 20:06:10 +0000 Subject: r10276: Fix for bug #3104 from Leo Weppelman . Don't update the time on read-only shares. We need this as set_filetime (which can be called on close and other paths) can end up calling this function without the NEED_WRITE protection. Jeremy. (This used to be commit 54eab3828aa0405288b68f6954abba201564c9e7) --- source3/smbd/dosmode.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a2bc424b8e..ee2f1095fa 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -451,6 +451,17 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times errno = 0; ZERO_STRUCT(sbuf); + /* Don't update the time on read-only shares */ + /* We need this as set_filetime (which can be called on + close and other paths) can end up calling this function + without the NEED_WRITE protection. Found by : + Leo Weppelman + */ + + if (!CAN_WRITE(conn)) { + return 0; + } + if(SMB_VFS_UTIME(conn,fname, times) == 0) return 0; -- cgit From 1970294ab3df66d36b713dc8811527ddc8e99bd0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Sep 2005 20:20:51 +0000 Subject: r10359: Ensure that smb.conf requests for hidden files are honored, even when DOS attributes are stored in EA's. Jeremy. (This used to be commit 758b30710e9f84f19b79c39afddc742aef495ebd) --- source3/smbd/dosmode.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ee2f1095fa..efbd5f04cb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -297,27 +297,28 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) return 0; } - /* Get the DOS attributes from an EA by preference. */ - if (get_ea_dos_attribute(conn, path, sbuf, &result)) { - result |= set_sparse_flag(sbuf); - return result; - } - - result = dos_mode_from_sbuf(conn, path, sbuf); - - /* Now do any modifications that depend on the path name. */ + /* First do any modifications that depend on the path name. */ /* hide files with a name starting with a . */ if (lp_hide_dot_files(SNUM(conn))) { const char *p = strrchr_m(path,'/'); - if (p) + if (p) { p++; - else + } else { p = path; + } - if (p[0] == '.' && p[1] != '.' && p[1] != 0) + if (p[0] == '.' && p[1] != '.' && p[1] != 0) { result |= aHIDDEN; + } } + /* Get the DOS attributes from an EA by preference. */ + if (get_ea_dos_attribute(conn, path, sbuf, &result)) { + result |= set_sparse_flag(sbuf); + } else { + result |= dos_mode_from_sbuf(conn, path, sbuf); + } + /* Optimization : Only call is_hidden_path if it's not already hidden. */ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { -- cgit From 3ecf9119d5055b0706c485eeba8df1bd898de4ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Oct 2005 04:25:47 +0000 Subject: r10885: Fix bug where read-only share files are always seen as read-only. Noticed by Andrew Bartlett. Jeremy (This used to be commit a33f4f0d2afe28ca0e3ab6c9ecfcdbaa267a7fbe) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index efbd5f04cb..6aee6ba426 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -479,7 +479,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times */ /* Check if we have write access. */ - if (can_write_to_file(conn, fname, &sbuf)) { + if (CAN_WRITE(conn) && can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); ret = SMB_VFS_UTIME(conn,fname, times); -- cgit From e950ef44c48b7a12247e0000f292ec50e466dfd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Oct 2005 04:28:46 +0000 Subject: r10888: We've already checked 'CAN_WRITE' so we don't need to do it again. Jeremy. (This used to be commit 1c52bf875cfdacb058aa6f54ab27b9f7e2d178dc) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6aee6ba426..efbd5f04cb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -479,7 +479,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times */ /* Check if we have write access. */ - if (CAN_WRITE(conn) && can_write_to_file(conn, fname, &sbuf)) { + if (can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); ret = SMB_VFS_UTIME(conn,fname, times); -- cgit From a1eb5255042c3ff246e27a3cd3cdfd869c5542d3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Oct 2005 01:09:37 +0000 Subject: r10979: After discussions on IRC about profile shares, added new parameter : map readonly = [yes|no|permissions] If yes: map inverse of user "w" bit to mean readonly. If no: never set DOS readonly bit. If permissions: check file permissions for user and set readonly bit if the current user cannot write. If store dos attributes is set to yes then this parameter is ignored. Jeremy. (This used to be commit da4238d18c7a57d1264db8517fb027a10a11baed) --- source3/smbd/dosmode.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index efbd5f04cb..fec148b8e6 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -129,14 +129,19 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result = 0; + enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); - if (lp_acl_check_permissions(SNUM(conn))) { + if (ro_opts == MAP_READONLY_YES) { + /* Original Samba method - map inverse of user "w" bit. */ + if ((sbuf->st_mode & S_IWUSR) == 0) { + result |= aRONLY; + } + } else if (ro_opts == MAP_READONLY_PERMISSIONS) { + /* Check actual permissions for read-only. */ if (!can_write_to_file(conn, path, sbuf)) { result |= aRONLY; } - } else if ((sbuf->st_mode & S_IWUSR) == 0) { - result |= aRONLY; - } + } /* Else never set the readonly bit. */ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; -- cgit From 4c8fc93905e89e2c3efa1002ad8fbc2a78fe51e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Nov 2005 06:29:48 +0000 Subject: r11718: Filter stored DOS attributes by SAMBA_ATTRIBUTES_MASK (0x7f). Jeremy. (This used to be commit 61444049e1543b364eea2ee79743287c75d37db5) --- source3/smbd/dosmode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index fec148b8e6..814d008cbb 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -337,6 +337,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) if (result & aSYSTEM) DEBUG(8, ("s")); if (result & aDIR ) DEBUG(8, ("d")); if (result & aARCH ) DEBUG(8, ("a")); + if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); DEBUG(8,("\n")); @@ -355,6 +356,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, mode_t unixmode; int ret = -1; + /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */ + dosmode &= SAMBA_ATTRIBUTES_MASK; + DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); if (!st || (st && !VALID_STAT(*st))) { st = &st1; -- cgit From 394f87b9146fab2ebf6a635c8bd4d17e4959fc36 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Nov 2005 22:39:00 +0000 Subject: r11767: Doesn't need to be exported. Jeremy. (This used to be commit 52b6f0db2e4a209641187255bd8815c8d03a5315) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 814d008cbb..5dfeddb80a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -126,7 +126,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c Change a unix mode to a dos mode. ****************************************************************************/ -uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result = 0; enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); -- cgit From e5b9a027ff860fd5f34cf91acd14a43f3d6dfbce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Nov 2005 17:03:50 +0000 Subject: r11943: Don't reset attrs to zero in EA get - we are adding to the attr list not resetting it. Jeremy. (This used to be commit 8ee569626be7ebf3b6ebf71e1becdd091b9e893a) --- source3/smbd/dosmode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 5dfeddb80a..7f3bda582d 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -190,7 +190,8 @@ static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S return False; } - *pattr = 0; + /* Don't reset pattr to zero as we may already have filename-based attributes we + need to preserve. */ sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr)); if (sizeret == -1) { -- cgit From 40d0707827ee154bcb03013abe6f72f1026a70c9 Mon Sep 17 00:00:00 2001 From: James Peach Date: Wed, 22 Mar 2006 23:49:09 +0000 Subject: r14668: Set the FILE_STATUS_OFFLINE bit by observing the events a DMAPI-based HSM is interested in. Tested on both IRIX and SLES9. (This used to be commit 514a767c57f8194547e5b708ad2573ab9a0719c6) --- source3/smbd/dosmode.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 7f3bda582d..f376de1343 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. dos mode handling functions Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) James Peach 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,6 +31,31 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) return 0; } +/**************************************************************************** + Work out whether this file is offline +****************************************************************************/ + +#ifndef ISDOT +#define ISDOT(p) (*(p) == '.' && *((p) + 1) == '\0') +#endif /* ISDOT */ + +#ifndef ISDOTDOT +#define ISDOTDOT(p) (*(p) == '.' && *((p) + 1) == '.' && *((p) + 2) == '\0') +#endif /* ISDOTDOT */ + +static uint32 set_offline_flag(connection_struct *conn, const char *const path) +{ + if (ISDOT(path) || ISDOTDOT(path)) { + return 0; + } + + if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) { + return 0; + } + + return dmapi_file_flags(path); +} + /**************************************************************************** Change a dos mode to a unix mode. Base permission for files: @@ -325,6 +351,10 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) result |= dos_mode_from_sbuf(conn, path, sbuf); } + if (S_ISREG(sbuf->st_mode)) { + result |= set_offline_flag(conn, path); + } + /* Optimization : Only call is_hidden_path if it's not already hidden. */ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { -- cgit From c9c502442b40aba97de17456ba948effcdfa3d05 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 8 Apr 2006 05:09:12 +0000 Subject: r14989: Fix from Mathias Dietz . EPERM can be a valid return from getting an xattr. Don't disable if we get it. Jeremy. (This used to be commit 7769b678f22d8ab4aa8aef55966813355bf2ce6d) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index f376de1343..583b3f19e7 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -222,7 +222,7 @@ static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr)); if (sizeret == -1) { #if defined(ENOTSUP) && defined(ENOATTR) - if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES)) { + if ((errno != ENOTSUP) && (errno != ENOATTR) && (errno != EACCES) && (errno != EPERM)) { DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n", path, strerror(errno) )); set_store_dos_attributes(SNUM(conn), False); -- cgit From 192062c4a60d107cd762183b937249bffd9edde7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Jul 2006 21:07:46 +0000 Subject: r16789: Fix bug #3909, when using ea's getting a directory tries to read ea's from an msdfs link. Stop it from doing that. Jerry please merge to 3.0.23. Jeremy. (This used to be commit 95e5ace6b4f348a3244b6a3ea0fd8badf55271f5) --- source3/smbd/dosmode.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 583b3f19e7..61145fde2f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -315,6 +315,57 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ return True; } +/**************************************************************************** + Change a unix mode to a dos mode for an ms dfs link. +****************************************************************************/ + +uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) +{ + uint32 result = 0; + + DEBUG(8,("dos_mode_msdfs: %s\n", path)); + + if (!VALID_STAT(*sbuf)) { + return 0; + } + + /* First do any modifications that depend on the path name. */ + /* hide files with a name starting with a . */ + if (lp_hide_dot_files(SNUM(conn))) { + const char *p = strrchr_m(path,'/'); + if (p) { + p++; + } else { + p = path; + } + + if (p[0] == '.' && p[1] != '.' && p[1] != 0) { + result |= aHIDDEN; + } + } + + result |= dos_mode_from_sbuf(conn, path, sbuf); + + /* Optimization : Only call is_hidden_path if it's not already + hidden. */ + if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { + result |= aHIDDEN; + } + + DEBUG(8,("dos_mode_msdfs returning ")); + + if (result & aHIDDEN) DEBUG(8, ("h")); + if (result & aRONLY ) DEBUG(8, ("r")); + if (result & aSYSTEM) DEBUG(8, ("s")); + if (result & aDIR ) DEBUG(8, ("d")); + if (result & aARCH ) DEBUG(8, ("a")); + if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); + + DEBUG(8,("\n")); + + return(result); +} + /**************************************************************************** Change a unix mode to a dos mode. ****************************************************************************/ -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/dosmode.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 61145fde2f..260a8dadbd 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -300,8 +300,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ * are not violating security in doing the setxattr. */ - fsp = open_file_fchmod(conn,path,sbuf); - if (!fsp) + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,path,sbuf,&fsp))) return ret; become_root(); if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) { @@ -518,8 +517,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, * 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) + files_struct *fsp; + if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp))) return -1; become_root(); ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); -- cgit From 8cd9636458e175d2e1b63a5211423cec04a6ce91 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 27 Dec 2006 10:57:59 +0000 Subject: r20356: Consolidate the calls to parent_dirname() per open to one. This involved passing the dirname as argument to a few routines instead of calling parent_dirname() deep down. Volker (This used to be commit 7977fd78652897bb7d4db1c21c5749043428f911) --- source3/smbd/dosmode.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 260a8dadbd..1172fe3e6b 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -59,7 +59,7 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path) /**************************************************************************** Change a dos mode to a unix mode. Base permission for files: - if creating file and inheriting + if creating file and inheriting (i.e. parent_dir != NULL) apply read/write bits from parent directory. else everybody gets read bit set @@ -79,23 +79,26 @@ static uint32 set_offline_flag(connection_struct *conn, const char *const path) } ****************************************************************************/ -mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file) +mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, + const char *inherit_from_dir) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); - mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ + mode_t dir_mode = 0; /* Mode of the inherit_from directory if + * inheriting. */ if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) { result &= ~(S_IWUSR | S_IWGRP | S_IWOTH); } - if (fname && creating_file && lp_inherit_perms(SNUM(conn))) { - char *dname; + if (fname && (inherit_from_dir != NULL) + && lp_inherit_perms(SNUM(conn))) { SMB_STRUCT_STAT sbuf; - dname = parent_dirname(fname); - DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (SMB_VFS_STAT(conn,dname,&sbuf) != 0) { - DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); + DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname, + inherit_from_dir)); + if (SMB_VFS_STAT(conn, inherit_from_dir, &sbuf) != 0) { + DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname, + inherit_from_dir, strerror(errno))); return(0); /* *** shouldn't happen! *** */ } @@ -429,7 +432,9 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) chmod a file - but preserve some bits. ********************************************************************/ -int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file) +int file_set_dosmode(connection_struct *conn, const char *fname, + uint32 dosmode, SMB_STRUCT_STAT *st, + const char *parent_dir) { SMB_STRUCT_STAT st1; int mask=0; @@ -462,7 +467,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, return 0; } - unixmode = unix_mode(conn,dosmode,fname, creating_file); + unixmode = unix_mode(conn,dosmode,fname, parent_dir); /* preserve the s bits */ mask |= (S_ISUID | S_ISGID); -- cgit From b2efff8fe5cdfd031a7b6f814993a9c234a66ee8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 7 Jan 2007 18:08:50 +0000 Subject: r20597: Survive some of the notify mask tests. (This used to be commit e4a2e63272dc5b20413597179d06b0185c4a6817) --- source3/smbd/dosmode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 1172fe3e6b..a3c46b3275 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -499,8 +499,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) + if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, + NOTIFY_ACTION_MODIFIED); return 0; + } if((errno != EPERM) && (errno != EACCES)) return -1; @@ -529,6 +532,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, + NOTIFY_ACTION_MODIFIED); } return( ret ); @@ -601,6 +606,9 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); return False; } + + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_LAST_WRITE, + NOTIFY_ACTION_MODIFIED); return(True); } -- cgit From 46fdae1b6b1b8e3285447193cb10e5a2a444d431 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Jan 2007 16:12:54 +0000 Subject: r20634: A *LOT* more work is necessary before touching notify remotely starts to make sense. Until then, remove it from the tree to keep the diff between 3_0_24 and 3_0 small. Volker (This used to be commit f146a85e74c84e78a11e616a1cbeaeef4693a0e0) --- source3/smbd/dosmode.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a3c46b3275..1172fe3e6b 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -499,11 +499,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, - NOTIFY_ACTION_MODIFIED); + if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) return 0; - } if((errno != EPERM) && (errno != EACCES)) return -1; @@ -532,8 +529,6 @@ int file_set_dosmode(connection_struct *conn, const char *fname, ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, - NOTIFY_ACTION_MODIFIED); } return( ret ); @@ -606,9 +601,6 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); return False; } - - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_LAST_WRITE, - NOTIFY_ACTION_MODIFIED); return(True); } -- cgit From db0ad252a0622dfac17d44ca646168df4c1c22e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Jan 2007 23:47:16 +0000 Subject: r20718: Sync up the filename path parsing changes from SAMBA_3_0_24. The only difference between the two trees now w.r.t file serving are the changes to smbd/open.c in this branch I need to review. Jeremy. (This used to be commit f4474edf6a0c71001dbd01429ef70bafad6abd74) --- source3/smbd/dosmode.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 1172fe3e6b..ff4291c08c 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -35,14 +35,6 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) Work out whether this file is offline ****************************************************************************/ -#ifndef ISDOT -#define ISDOT(p) (*(p) == '.' && *((p) + 1) == '\0') -#endif /* ISDOT */ - -#ifndef ISDOTDOT -#define ISDOTDOT(p) (*(p) == '.' && *((p) + 1) == '.' && *((p) + 2) == '\0') -#endif /* ISDOTDOT */ - static uint32 set_offline_flag(connection_struct *conn, const char *const path) { if (ISDOT(path) || ISDOTDOT(path)) { -- cgit From 940192ddcc9d23e3bec806b4419d5845eeac0fd0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 17 Jan 2007 16:23:45 +0000 Subject: r20854: Ok, now I think we're at a point where looking at notify starts to make sense again :-) Volker (This used to be commit 5533cdeec1b0cdee39b1d89e2320587dc9281ee6) --- source3/smbd/dosmode.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ff4291c08c..44e637a0ee 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -491,8 +491,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) + if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, + NOTIFY_ACTION_MODIFIED); return 0; + } if((errno != EPERM) && (errno != EACCES)) return -1; @@ -521,6 +524,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, + NOTIFY_ACTION_MODIFIED); } return( ret ); @@ -593,6 +598,9 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); return False; } + + notify_fname(conn, fname, FILE_NOTIFY_CHANGE_LAST_WRITE, + NOTIFY_ACTION_MODIFIED); return(True); } -- cgit From 547f77778abc45bf329dcb53182127d72596c812 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 31 Jan 2007 14:14:57 +0000 Subject: r21087: Make the param list of notify_fname match notify_trigger (This used to be commit defa28f9c3eda85a072b972fffd2d5de8bcf01f7) --- source3/smbd/dosmode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 44e637a0ee..ad79bbacdd 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -492,8 +492,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, } if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, - NOTIFY_ACTION_MODIFIED); + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); return 0; } @@ -524,8 +524,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, - NOTIFY_ACTION_MODIFIED); + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } return( ret ); @@ -599,8 +599,8 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) return False; } - notify_fname(conn, fname, FILE_NOTIFY_CHANGE_LAST_WRITE, - NOTIFY_ACTION_MODIFIED); + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_LAST_WRITE, fname); return(True); } -- cgit From 4952fe368a40b239140b3035db6075427d237bb9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Mar 2007 23:40:03 +0000 Subject: r21714: Change the VFS interface to use struct timespec for utimes - change the call to ntimes. This preserves nsec timestamps we get from stat (if the system supports it) and only maps back down to usec or sec resolution on time set. Looks bigger than it is as I had to move lots of internal code from using time_t and struct utimebuf to struct timespec. Jeremy. (This used to be commit 8f3d530c5a748ea90f42ed8fbe68ae92178d4875) --- source3/smbd/dosmode.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ad79bbacdd..71d4fa179d 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -282,7 +282,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ } /* We want DOS semantics, ie allow non owner with write permission to change the - bits on a file. Just like file_utime below. + bits on a file. Just like file_ntimes below. */ /* Check if we have write access. */ @@ -504,7 +504,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, 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. + bits on a file. Just like file_ntimes below. */ /* Check if we have write access. */ @@ -532,11 +532,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, } /******************************************************************* - Wrapper around dos_utime that possibly allows DOS semantics rather + Wrapper around the VFS ntimes that possibly allows DOS semantics rather than POSIX. *******************************************************************/ -int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times) +int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2]) { SMB_STRUCT_STAT sbuf; int ret = -1; @@ -555,14 +555,17 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times return 0; } - if(SMB_VFS_UTIME(conn,fname, times) == 0) + if(SMB_VFS_NTIMES(conn, fname, ts) == 0) { return 0; + } - if((errno != EPERM) && (errno != EACCES)) + if((errno != EPERM) && (errno != EACCES)) { return -1; + } - if(!lp_dos_filetimes(SNUM(conn))) + if(!lp_dos_filetimes(SNUM(conn))) { return -1; + } /* We have permission (given by the Samba admin) to break POSIX semantics and allow a user to change @@ -574,7 +577,7 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times if (can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = SMB_VFS_UTIME(conn,fname, times); + ret = SMB_VFS_NTIMES(conn, fname, ts); unbecome_root(); } @@ -585,16 +588,19 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times Change a filetime - possibly allowing DOS semantics. *******************************************************************/ -BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) +BOOL set_filetime(connection_struct *conn, const char *fname, + const struct timespec mtime) { - struct utimbuf times; + struct timespec ts[2]; - if (null_mtime(mtime)) + if (null_timespec(mtime)) { return(True); + } - times.modtime = times.actime = mtime; + ts[1] = mtime; /* mtime. */ + ts[0] = ts[1]; /* atime. */ - if (file_utime(conn, fname, ×)) { + if (file_ntimes(conn, fname, ts)) { DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); return False; } @@ -602,5 +608,5 @@ BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime) notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_LAST_WRITE, fname); - return(True); -} + return True; +} -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 71d4fa179d..9efd691682 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/dosmode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9efd691682..b4ab0ca226 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/dosmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index b4ab0ca226..ed622d3730 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -200,7 +200,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_ Get DOS attributes from an EA. ****************************************************************************/ -static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr) +static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf, uint32 *pattr) { ssize_t sizeret; fstring attrstr; @@ -256,11 +256,11 @@ static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S Set DOS attributes in an EA. ****************************************************************************/ -static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode) +static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, uint32 dosmode) { fstring attrstr; files_struct *fsp = NULL; - BOOL ret = False; + bool ret = False; if (!lp_store_dos_attributes(SNUM(conn))) { return False; @@ -587,7 +587,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe Change a filetime - possibly allowing DOS semantics. *******************************************************************/ -BOOL set_filetime(connection_struct *conn, const char *fname, +bool set_filetime(connection_struct *conn, const char *fname, const struct timespec mtime) { struct timespec ts[2]; -- cgit From 8f1f2f04c796a8659d93bafadefca4a98fee00f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 31 Oct 2007 15:45:45 -0700 Subject: Fix some cases where file_set_dosmode was being passed False instead of NULL. Fix more of the notifications to be correct for Samba4 RAW-NOTIFY torture (we had missed one when calling set_ea_dos_attribute(). Jeremy. (This used to be commit 39d265375cf55eedddef2c4faa65398df73d5ed2) --- source3/smbd/dosmode.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ed622d3730..18e6439be4 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -425,7 +425,8 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, - const char *parent_dir) + const char *parent_dir, + bool newfile) { SMB_STRUCT_STAT st1; int mask=0; @@ -455,6 +456,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, /* Store the DOS attributes in an EA by preference. */ if (set_ea_dos_attribute(conn, fname, st, dosmode)) { + if (!newfile) { + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + } return 0; } @@ -491,8 +496,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, } if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + if (!newfile) { + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + } return 0; } @@ -523,8 +530,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); unbecome_root(); close_file_fchmod(fsp); - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + if (!newfile) { + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + } } return( ret ); -- cgit From 0bb1a6ec2d963c2001230142692de8335c540434 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 31 Oct 2007 16:32:48 -0700 Subject: Note when we're setting change time, not write time, and send message accordingly. Apart from not supporting create time we now pass the S4 RAW-NOTIFY torture. Jeremy. (This used to be commit 8a77f520fa03afa60eac2aaeab4babe7dd8db4f0) --- source3/smbd/dosmode.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 18e6439be4..8e3c9b4c91 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -591,7 +591,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe return ret; } - + /******************************************************************* Change a filetime - possibly allowing DOS semantics. *******************************************************************/ @@ -609,12 +609,13 @@ bool set_filetime(connection_struct *conn, const char *fname, ts[0] = ts[1]; /* atime. */ if (file_ntimes(conn, fname, ts)) { - DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + DEBUG(4,("set_filetime(%s) failed: %s\n", + fname,strerror(errno))); return False; } notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fname); - - return True; + FILE_NOTIFY_CHANGE_LAST_WRITE, fname); + + return true; } -- cgit From 33f01360e0a40f6d1fa03035979d816ff9198d85 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 27 Dec 2007 21:31:08 +0100 Subject: Fix setting the initial permission bits This fixes a make test failure on Solaris. When creating a new file, file_set_dosmode() called from open_file_ntcreate calculates a new permission mask, very likely different from what had been calculated in open_file_ntcreate. Further down we overwrote the newly calculated value with SMB_FCHMOD_ACL, ignoring what file_set_dosmode had calculated. Why did Linux not see this? fchmod_acl on a newly created file without acls would not retrieve an acl at all, whereas under Solaris acl(2) returns something even for files with just posix permissions returns something. Jeremy, given that we have very similar code in 3.0.28 this might also explain some of the bug reports that people have concerning ACLs on new files. Volker P.S: This one took a while to find... (This used to be commit 2135dfe91bf1ae114a18c15286b535662200677d) --- source3/smbd/dosmode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 8e3c9b4c91..a96f80ee0e 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -438,12 +438,19 @@ int file_set_dosmode(connection_struct *conn, const char *fname, dosmode &= SAMBA_ATTRIBUTES_MASK; DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); - if (!st || (st && !VALID_STAT(*st))) { + + if (st == NULL) { + SET_STAT_INVALID(st1); st = &st1; + } + + if (!VALID_STAT(*st)) { if (SMB_VFS_STAT(conn,fname,st)) return(-1); } + unixmode = st->st_mode; + get_acl_group_bits(conn, fname, &st->st_mode); if (S_ISDIR(st->st_mode)) @@ -451,8 +458,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, else dosmode &= ~aDIR; - if (dos_mode(conn,fname,st) == dosmode) + if (dos_mode(conn,fname,st) == dosmode) { + st->st_mode = unixmode; return(0); + } /* Store the DOS attributes in an EA by preference. */ if (set_ea_dos_attribute(conn, fname, st, dosmode)) { @@ -460,6 +469,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } + st->st_mode = unixmode; return 0; } @@ -500,6 +510,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } + st->st_mode = unixmode; return 0; } @@ -534,6 +545,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } + if (ret == 0) { + st->st_mode = unixmode; + } } return( ret ); -- cgit From e614dec27f33c932c6c29c806d567fd6015cd5e6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 13:44:37 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FCHMOD(). Michael (This used to be commit a54d5604da556d1250ca9948d4acc4a187a9fede) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a96f80ee0e..d3813f9b41 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -538,7 +538,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp))) return -1; become_root(); - ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode); + ret = SMB_VFS_FCHMOD(fsp, unixmode); unbecome_root(); close_file_fchmod(fsp); if (!newfile) { -- cgit From d86fc3ec8c99aaa5ffaa14a97525154507c39df7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:17:03 +0300 Subject: Add support for offline files support, remote storage, and Async I/O force operations to VFS Offline files support and remote storage are for allowing communication with backup and archiving tools that mark files moved to a tape library as offline. We translate this info into corresponding CIFS offline file attribute and mark an exported volume as remote storage. Async I/O force is to allow selective redirection of I/O operations to asynchronous processing in case it is viable at VFS module discretion. It is needed for proper handling of offline files as performing regular I/O on offline file will block smbd. Signed-off-by: Alexander Bokovoy (This used to be commit 875208724e39564fe81385dfe36e6c963e79e101) --- source3/smbd/dosmode.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index d3813f9b41..2021621dfa 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -30,23 +30,6 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) return 0; } -/**************************************************************************** - Work out whether this file is offline -****************************************************************************/ - -static uint32 set_offline_flag(connection_struct *conn, const char *const path) -{ - if (ISDOT(path) || ISDOTDOT(path)) { - return 0; - } - - if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) { - return 0; - } - - return dmapi_file_flags(path); -} - /**************************************************************************** Change a dos mode to a unix mode. Base permission for files: @@ -366,6 +349,8 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) { uint32 result = 0; + bool offline; + int ret; DEBUG(8,("dos_mode: %s\n", path)); @@ -395,8 +380,10 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) result |= dos_mode_from_sbuf(conn, path, sbuf); } - if (S_ISREG(sbuf->st_mode)) { - result |= set_offline_flag(conn, path); + + ret = SMB_VFS_IS_OFFLINE(conn, path, sbuf, &offline); + if (S_ISREG(sbuf->st_mode) && (ret == 0) && offline) { + result |= FILE_ATTRIBUTE_OFFLINE; } /* Optimization : Only call is_hidden_path if it's not already @@ -432,7 +419,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, int mask=0; mode_t tmp; mode_t unixmode; - int ret = -1; + int ret = -1, lret = -1; /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */ dosmode &= SAMBA_ATTRIBUTES_MASK; @@ -505,10 +492,21 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) { - if (!newfile) { + if (dosmode & FILE_ATTRIBUTE_OFFLINE) { + lret = SMB_VFS_SET_OFFLINE(conn, fname); + if (lret == -1) { + DEBUG(0, ("set_dos_mode: client has asked to set " + "FILE_ATTRIBUTE_OFFLINE to %s/%s but there was " + "an error while setting it or it is not supported.\n", + parent_dir, fname)); + } + } + + ret = SMB_VFS_CHMOD(conn, fname, unixmode); + if (ret == 0) { + if(!newfile || (lret != -1)) { notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); + FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } st->st_mode = unixmode; return 0; -- cgit From 026a66abecea3e3a54cdbfb97129d5e65608e5df Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Thu, 17 Jan 2008 14:57:35 +0300 Subject: Rework of VFS is_offline() function to only return boolean offline/online result for a file. This makes sense as upper levels are only taking returned result of 0 (no error) into consideration when deciding whether to mark file offline/online as returned from is_offline. That means that we simply can move the decision down to VFS module and clean up upper levels so that they always see only file status. If there is an error when trying to identify file status, then VFS module could decide what to return (offline or online) by itself -- after all, it ought to have system-specific knowledge anyway. (This used to be commit 75cc08661473cce62756fa062071bb2bc1fb39ec) --- source3/smbd/dosmode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 2021621dfa..eb18f65fca 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -350,7 +350,6 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) { uint32 result = 0; bool offline; - int ret; DEBUG(8,("dos_mode: %s\n", path)); @@ -381,8 +380,8 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) } - ret = SMB_VFS_IS_OFFLINE(conn, path, sbuf, &offline); - if (S_ISREG(sbuf->st_mode) && (ret == 0) && offline) { + offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf); + if (S_ISREG(sbuf->st_mode) && offline) { result |= FILE_ATTRIBUTE_OFFLINE; } -- cgit From 1ae0f2d02ea5909fbb8cfa7c0d78291048699b9c Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 6 Feb 2008 09:09:23 +0300 Subject: Allow actual call to set file offline Dos mode calculation was masking out FILE_ATTRIBUTE_OFFLINE so that code to set file offline was never called before. Merge from Tridge's v3-0-ctdb git tree. (This used to be commit 9827d5ff416479408b19a8964c2321ea2517aa74) --- source3/smbd/dosmode.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index eb18f65fca..f068f1f655 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -419,9 +419,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, mode_t tmp; mode_t unixmode; int ret = -1, lret = -1; + uint32_t old_mode; /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */ - dosmode &= SAMBA_ATTRIBUTES_MASK; + dosmode &= SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE; DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); @@ -444,7 +445,24 @@ int file_set_dosmode(connection_struct *conn, const char *fname, else dosmode &= ~aDIR; - if (dos_mode(conn,fname,st) == dosmode) { + old_mode = dos_mode(conn,fname,st); + + if (dosmode & FILE_ATTRIBUTE_OFFLINE) { + if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) { + lret = SMB_VFS_SET_OFFLINE(conn, fname); + if (lret == -1) { + DEBUG(0, ("set_dos_mode: client has asked to set " + "FILE_ATTRIBUTE_OFFLINE to %s/%s but there was " + "an error while setting it or it is not supported.\n", + parent_dir, fname)); + } + } + } + + dosmode &= ~FILE_ATTRIBUTE_OFFLINE; + old_mode &= ~FILE_ATTRIBUTE_OFFLINE; + + if (old_mode == dosmode) { st->st_mode = unixmode; return(0); } @@ -491,16 +509,6 @@ int file_set_dosmode(connection_struct *conn, const char *fname, unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } - if (dosmode & FILE_ATTRIBUTE_OFFLINE) { - lret = SMB_VFS_SET_OFFLINE(conn, fname); - if (lret == -1) { - DEBUG(0, ("set_dos_mode: client has asked to set " - "FILE_ATTRIBUTE_OFFLINE to %s/%s but there was " - "an error while setting it or it is not supported.\n", - parent_dir, fname)); - } - } - ret = SMB_VFS_CHMOD(conn, fname, unixmode); if (ret == 0) { if(!newfile || (lret != -1)) { -- cgit From a33236f4aa2d90ca7293c627d9e34d855fea65e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Feb 2008 10:31:22 -0800 Subject: Make operator precedence very clear. Jeremy. (This used to be commit 4f125110cfe25b499eb628b5b08fdb610a5d972c) --- source3/smbd/dosmode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index f068f1f655..a2e617c117 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -422,7 +422,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32_t old_mode; /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */ - dosmode &= SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE; + dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE); DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname)); -- cgit From d03453864ab1bc5fd3b4a3abaf96176a006c102b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 15:39:38 +0100 Subject: smbd: implement the strange write time update logic We now never call file_ntimes() directly, every update is done via smb_set_file_time(). This let samba3 pass the BASE-DELAYWRITE test. The write time is only updated 2 seconds after the first write() on any open handle to the current time (not the time of the first write). Each handle which had write requests updates the write time to the current time on close(). If the write time is set explicit via setfileinfo or setpathinfo the write time is visible directly and a following close on the same handle doesn't update the write time. metze (This used to be commit 2eab212ea2e1bfd8fa716c2c89b2c042f7ba12ea) --- source3/smbd/dosmode.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index a2e617c117..0ac3873275 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -571,6 +571,11 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe errno = 0; ZERO_STRUCT(sbuf); + DEBUG(6, ("file_ntime: actime: %s", + time_to_asc(convert_timespec_to_time_t(ts[0])))); + DEBUG(6, ("file_ntime: modtime: %s", + time_to_asc(convert_timespec_to_time_t(ts[1])))); + /* Don't update the time on read-only shares */ /* We need this as set_filetime (which can be called on close and other paths) can end up calling this function @@ -615,26 +620,35 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe Change a filetime - possibly allowing DOS semantics. *******************************************************************/ -bool set_filetime(connection_struct *conn, const char *fname, - const struct timespec mtime) +bool set_write_time_path(connection_struct *conn, const char *fname, + struct file_id fileid, const struct timespec mtime, + bool overwrite) { - struct timespec ts[2]; - if (null_timespec(mtime)) { - return(True); + return true; } - ts[1] = mtime; /* mtime. */ - ts[0] = ts[1]; /* atime. */ - - if (file_ntimes(conn, fname, ts)) { - DEBUG(4,("set_filetime(%s) failed: %s\n", - fname,strerror(errno))); - return False; + if (!set_write_time(fileid, mtime, overwrite)) { + return false; } - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fname); + /* in the overwrite case the caller should trigger the notify */ + if (!overwrite) { + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_LAST_WRITE, fname); + } return true; } + +bool set_write_time_fsp(struct files_struct *fsp, const struct timespec mtime, + bool overwrite) +{ + if (overwrite) { + fsp->write_time_forced = true; + TALLOC_FREE(fsp->update_write_time_event); + } + + return set_write_time_path(fsp->conn, fsp->fsp_name, fsp->file_id, + mtime, overwrite); +} -- cgit From 405b072431db3f3f8f16e4e0d2f2b1b2f1c71286 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 2008 19:00:48 -0700 Subject: Write times code update. Ok, here's the fix for the write times breakage with the new tests in S4 smbtorture. The key is keeping in the share mode struct the "old_file_time" as the real write time, set by all the write and allocation calls, and the "changed_write_time" as the "sticky" write time - set by the SET_FILE_TIME calls. We can set them independently (although I kept the optimization of not setting the "old_file_time" is a "changed_write_time" was already set, as we'll never see it. This allows us to update the write time immediately on the SMBwrite truncate case, SET_END_OF_FILE and SET_ALLOCATION_SIZE calls, whilst still have the 2 second delay on the "normal" SMBwrite, SMBwriteX calls. I think in a subsequent patch I'd like to change the name of these from "old_file_time" to "write_time" and "changed_write_time" to "sticky_write_time" to make this clearer. I think I also fixed a bug in Metze's original code in that once a write timestamp had been set from a "normal" SMBwriteX call the fsp->update_write_time_triggered variable was set and then never reset - thus meaning the write timestamp would never get updated again on subsequent SMBwriteX's. The new code checks the update_write_time_event event instead, and doesn't update is there's an event already scheduled. Metze especially, please check this over for your understanding. Jeremy. (This used to be commit 6f20585419046c4aca1f7d6c863cf79eb6ae53b0) --- source3/smbd/dosmode.c | 52 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'source3/smbd/dosmode.c') diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 0ac3873275..88c6a51770 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -616,39 +616,51 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe return ret; } -/******************************************************************* - Change a filetime - possibly allowing DOS semantics. -*******************************************************************/ +/****************************************************************** + Force a "sticky" write time on a pathname. This will always be + returned on all future write time queries and set on close. +******************************************************************/ -bool set_write_time_path(connection_struct *conn, const char *fname, - struct file_id fileid, const struct timespec mtime, - bool overwrite) +bool set_sticky_write_time_path(connection_struct *conn, const char *fname, + struct file_id fileid, const struct timespec mtime) { if (null_timespec(mtime)) { return true; } - if (!set_write_time(fileid, mtime, overwrite)) { + if (!set_sticky_write_time(fileid, mtime)) { return false; } - /* in the overwrite case the caller should trigger the notify */ - if (!overwrite) { - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fname); - } - return true; } -bool set_write_time_fsp(struct files_struct *fsp, const struct timespec mtime, - bool overwrite) +/****************************************************************** + Force a "sticky" write time on an fsp. This will always be + returned on all future write time queries and set on close. +******************************************************************/ + +bool set_sticky_write_time_fsp(struct files_struct *fsp, const struct timespec mtime) { - if (overwrite) { - fsp->write_time_forced = true; - TALLOC_FREE(fsp->update_write_time_event); + fsp->write_time_forced = true; + TALLOC_FREE(fsp->update_write_time_event); + + return set_sticky_write_time_path(fsp->conn, fsp->fsp_name, + fsp->file_id, mtime); +} + +/****************************************************************** + Update a write time immediately, without the 2 second delay. +******************************************************************/ + +bool update_write_time(struct files_struct *fsp) +{ + if (!set_write_time(fsp->file_id, timespec_current())) { + return false; } - return set_write_time_path(fsp->conn, fsp->fsp_name, fsp->file_id, - mtime, overwrite); + notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name); + + return true; } -- cgit