-#define OLD_NTDOMAIN 1
-
/*
- Unix SMB/Netbios implementation.
- Version 1.9.
+ Unix SMB/CIFS implementation.
dos mode handling functions
Copyright (C) Andrew Tridgell 1992-1998
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
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
****************************************************************************/
-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;
-
- DEBUG(8,("dos_mode: %s\n", path));
+ int result = 0;
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
+ DEBUG(8,("dos_mode: %s\n", path));
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
+ 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 (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(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);
}
/*******************************************************************
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)
{
- extern struct current_user current_user;
SMB_STRUCT_STAT st1;
int mask=0;
mode_t tmp;
if (S_ISDIR(st->st_mode))
dosmode |= aDIR;
+ else
+ dosmode &= ~aDIR;
if (dos_mode(conn,fname,st) == dosmode)
return(0);
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((errno != EPERM) && (errno != EACCES))
return -1;
/* 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 );
errno = 0;
- if(conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times) == 0)
+ if(conn->vfs_ops.utime(conn,fname, times) == 0)
return 0;
if((errno != EPERM) && (errno != EACCES))
current_user.ngroups,current_user.groups)))) {
/* We are allowed to become root and change the filetime. */
become_root();
- ret = conn->vfs_ops.utime(conn,dos_to_unix(fname, False), times);
+ ret = conn->vfs_ops.utime(conn,fname, times);
unbecome_root();
}
}
return(True);
}
-
-#undef OLD_NTDOMAIN