}
****************************************************************************/
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname,
+mode_t unix_mode(connection_struct *conn, int dosmode,
+ const struct smb_filename *smb_fname,
const char *inherit_from_dir)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
- if (fname && (inherit_from_dir != NULL)
- && lp_inherit_perms(SNUM(conn))) {
- SMB_STRUCT_STAT sbuf;
+ if ((inherit_from_dir != NULL) && lp_inherit_perms(SNUM(conn))) {
+ struct smb_filename *smb_fname_parent = NULL;
+ NTSTATUS status;
- DEBUG(2, ("unix_mode(%s) inheriting from %s\n", fname,
+ DEBUG(2, ("unix_mode(%s) inheriting from %s\n",
+ smb_fname_str_dbg(smb_fname),
inherit_from_dir));
- if (vfs_stat_smb_fname(conn, inherit_from_dir, &sbuf) != 0) {
- DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", fname,
+
+ status = create_synthetic_smb_fname(talloc_tos(),
+ inherit_from_dir, NULL,
+ NULL, &smb_fname_parent);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("unix_mode(%s) failed, [dir %s]: %s\n",
+ smb_fname_str_dbg(smb_fname),
+ inherit_from_dir, nt_errstr(status)));
+ return(0);
+ }
+
+ if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) {
+ DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",
+ smb_fname_str_dbg(smb_fname),
inherit_from_dir, strerror(errno)));
+ TALLOC_FREE(smb_fname_parent);
return(0); /* *** shouldn't happen! *** */
}
/* Save for later - but explicitly remove setuid bit for safety. */
- dir_mode = sbuf.st_ex_mode & ~S_ISUID;
- DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
+ dir_mode = smb_fname_parent->st.st_ex_mode & ~S_ISUID;
+ DEBUG(2,("unix_mode(%s) inherit mode %o\n",
+ smb_fname_str_dbg(smb_fname), (int)dir_mode));
/* Clear "result" */
result = 0;
+ TALLOC_FREE(smb_fname_parent);
}
if (IS_DOS_DIR(dosmode)) {
}
}
- DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result ));
+ DEBUG(3,("unix_mode(%s) returning 0%o\n", smb_fname_str_dbg(smb_fname),
+ (int)result));
return(result);
}
Change a unix mode to a dos mode.
****************************************************************************/
-static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf)
+static uint32 dos_mode_from_sbuf(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
int result = 0;
enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn));
if (ro_opts == MAP_READONLY_YES) {
/* Original Samba method - map inverse of user "w" bit. */
- if ((sbuf->st_ex_mode & S_IWUSR) == 0) {
+ if ((smb_fname->st.st_ex_mode & S_IWUSR) == 0) {
result |= aRONLY;
}
} else if (ro_opts == MAP_READONLY_PERMISSIONS) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), path,
- sbuf, &smb_fname);
- if (NT_STATUS_IS_OK(status)) {
- /* Check actual permissions for read-only. */
- if (!can_write_to_file(conn, smb_fname)) {
- result |= aRONLY;
- }
+ /* Check actual permissions for read-only. */
+ if (!can_write_to_file(conn, smb_fname)) {
+ result |= aRONLY;
}
- TALLOC_FREE(smb_fname);
} /* Else never set the readonly bit. */
- if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0))
+ if (MAP_ARCHIVE(conn) && ((smb_fname->st.st_ex_mode & S_IXUSR) != 0))
result |= aARCH;
- if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0))
+ if (MAP_SYSTEM(conn) && ((smb_fname->st.st_ex_mode & S_IXGRP) != 0))
result |= aSYSTEM;
- if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0))
+ if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
result |= aHIDDEN;
- if (S_ISDIR(sbuf->st_ex_mode))
+ if (S_ISDIR(smb_fname->st.st_ex_mode))
result = aDIR | (result & aRONLY);
- result |= set_sparse_flag(sbuf);
- result |= set_link_read_only_flag(sbuf);
+ result |= set_sparse_flag(&smb_fname->st);
+ result |= set_link_read_only_flag(&smb_fname->st);
DEBUG(8,("dos_mode_from_sbuf returning "));
Get DOS attributes from an EA.
****************************************************************************/
-static bool get_ea_dos_attribute(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *sbuf, uint32 *pattr)
+static bool get_ea_dos_attribute(connection_struct *conn,
+ const struct smb_filename *smb_fname,
+ uint32 *pattr)
{
ssize_t sizeret;
fstring attrstr;
/* 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));
+ sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name,
+ SAMBA_XATTR_DOS_ATTRIB, attrstr,
+ sizeof(attrstr));
if (sizeret == -1) {
if (errno == ENOSYS
#if defined(ENOTSUP)
#else
) {
#endif
- DEBUG(1,("get_ea_dos_attributes: Cannot get attribute from EA on file %s: Error = %s\n",
- path, strerror(errno) ));
+ DEBUG(1,("get_ea_dos_attributes: Cannot get attribute "
+ "from EA on file %s: Error = %s\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
set_store_dos_attributes(SNUM(conn), False);
}
return False;
}
/* Null terminate string. */
attrstr[sizeret] = 0;
- DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n", path, attrstr));
+ DEBUG(10,("get_ea_dos_attribute: %s attrstr = %s\n",
+ smb_fname_str_dbg(smb_fname), 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));
+ DEBUG(1,("get_ea_dos_attributes: Badly formed DOSATTRIB on "
+ "file %s - %s\n", smb_fname_str_dbg(smb_fname),
+ attrstr));
return False;
}
- if (S_ISDIR(sbuf->st_ex_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
dosattr |= aDIR;
}
*pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK);
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,
+ struct smb_filename *smb_fname,
+ uint32 dosmode)
{
fstring attrstr;
files_struct *fsp = NULL;
}
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 (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+ SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr),
+ 0) == -1) {
if((errno != EPERM) && (errno != EACCES)) {
if (errno == ENOSYS
#if defined(ENOTSUP)
#else
) {
#endif
- DEBUG(1,("set_ea_dos_attributes: Cannot set attribute EA on file %s: Error = %s\n",
- path, strerror(errno) ));
+ DEBUG(1,("set_ea_dos_attributes: Cannot set "
+ "attribute EA on file %s: Error = %s\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno) ));
set_store_dos_attributes(SNUM(conn), False);
}
return False;
* are not violating security in doing the setxattr.
*/
- if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, path, sbuf,
+ if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, smb_fname,
&fsp)))
return ret;
become_root();
- if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) {
+ if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+ SAMBA_XATTR_DOS_ATTRIB, attrstr,
+ strlen(attrstr), 0) == 0) {
ret = True;
}
unbecome_root();
close_file_fchmod(NULL, fsp);
return ret;
}
- DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path));
+ DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr,
+ smb_fname_str_dbg(smb_fname)));
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, const SMB_STRUCT_STAT *psbuf)
+uint32 dos_mode_msdfs(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
- SMB_STRUCT_STAT sbuf = *psbuf;
uint32 result = 0;
- DEBUG(8,("dos_mode_msdfs: %s\n", path));
+ DEBUG(8,("dos_mode_msdfs: %s\n", smb_fname_str_dbg(smb_fname)));
- if (!VALID_STAT(sbuf)) {
+ if (!VALID_STAT(smb_fname->st)) {
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,'/');
+ const char *p = strrchr_m(smb_fname->base_name, '/');
if (p) {
p++;
} else {
- p = path;
+ p = smb_fname->base_name;
}
/* Only . and .. are not hidden. */
}
}
- result |= dos_mode_from_sbuf(conn, path, &sbuf);
+ result |= dos_mode_from_sbuf(conn, smb_fname);
/* Optimization : Only call is_hidden_path if it's not already
hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
+ if (!(result & aHIDDEN) &&
+ IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
result |= aHIDDEN;
}
****************************************************************************/
static bool get_stat_dos_flags(connection_struct *conn,
- const char *fname,
- const SMB_STRUCT_STAT *sbuf,
+ const struct smb_filename *smb_fname,
uint32_t *dosmode)
{
- SMB_ASSERT(sbuf && VALID_STAT(*sbuf));
+ SMB_ASSERT(VALID_STAT(smb_fname->st));
SMB_ASSERT(dosmode);
if (!lp_store_dos_attributes(SNUM(conn))) {
return false;
}
- DEBUG(5, ("Getting stat dos attributes for %s.\n", fname));
+ DEBUG(5, ("Getting stat dos attributes for %s.\n",
+ smb_fname_str_dbg(smb_fname)));
- if (sbuf->st_ex_flags & UF_DOS_ARCHIVE)
+ if (smb_fname->st.st_ex_flags & UF_DOS_ARCHIVE)
*dosmode |= aARCH;
- if (sbuf->st_ex_flags & UF_DOS_HIDDEN)
+ if (smb_fname->st.st_ex_flags & UF_DOS_HIDDEN)
*dosmode |= aHIDDEN;
- if (sbuf->st_ex_flags & UF_DOS_RO)
+ if (smb_fname->st.st_ex_flags & UF_DOS_RO)
*dosmode |= aRONLY;
- if (sbuf->st_ex_flags & UF_DOS_SYSTEM)
+ if (smb_fname->st.st_ex_flags & UF_DOS_SYSTEM)
*dosmode |= aSYSTEM;
- if (sbuf->st_ex_flags & UF_DOS_NOINDEX)
+ if (smb_fname->st.st_ex_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
- if (S_ISDIR(sbuf->st_ex_mode))
+ if (S_ISDIR(smb_fname->st.st_ex_mode))
*dosmode |= aDIR;
- *dosmode |= set_sparse_flag(sbuf);
- *dosmode |= set_link_read_only_flag(sbuf);
+ *dosmode |= set_sparse_flag(&smb_fname->st);
+ *dosmode |= set_link_read_only_flag(&smb_fname->st);
return true;
}
Change a unix mode to a dos mode.
****************************************************************************/
-uint32 dos_mode(connection_struct *conn, const char *path, const SMB_STRUCT_STAT *psbuf)
+uint32 dos_mode(connection_struct *conn, const struct smb_filename *smb_fname)
{
- SMB_STRUCT_STAT sbuf = *psbuf;
+ SMB_STRUCT_STAT sbuf;
uint32 result = 0;
bool offline, used_stat_dos_flags = false;
- DEBUG(8,("dos_mode: %s\n", path));
+ DEBUG(8,("dos_mode: %s\n", smb_fname_str_dbg(smb_fname)));
- if (!VALID_STAT(sbuf)) {
+ if (!VALID_STAT(smb_fname->st)) {
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,'/');
+ const char *p = strrchr_m(smb_fname->base_name,'/');
if (p) {
p++;
} else {
- p = path;
+ p = smb_fname->base_name;
}
/* Only . and .. are not hidden. */
}
#ifdef HAVE_STAT_DOS_FLAGS
- used_stat_dos_flags = get_stat_dos_flags(conn, path, &sbuf, &result);
+ used_stat_dos_flags = get_stat_dos_flags(conn, smb_fname, &result);
#endif
if (!used_stat_dos_flags) {
/* Get the DOS attributes from an EA by preference. */
- if (get_ea_dos_attribute(conn, path, &sbuf, &result)) {
- result |= set_sparse_flag(&sbuf);
+ if (get_ea_dos_attribute(conn, smb_fname, &result)) {
+ result |= set_sparse_flag(&smb_fname->st);
} else {
- result |= dos_mode_from_sbuf(conn, path, &sbuf);
+ result |= dos_mode_from_sbuf(conn, smb_fname);
}
}
- offline = SMB_VFS_IS_OFFLINE(conn, path, &sbuf);
+ sbuf = smb_fname->st;
+ offline = SMB_VFS_IS_OFFLINE(conn, smb_fname->base_name, &sbuf);
if (S_ISREG(sbuf.st_ex_mode) && offline) {
result |= FILE_ATTRIBUTE_OFFLINE;
}
/* Optimization : Only call is_hidden_path if it's not already
hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
+ if (!(result & aHIDDEN) &&
+ IS_HIDDEN_PATH(conn, smb_fname->base_name)) {
result |= aHIDDEN;
}
mode_t unixmode;
int ret = -1, lret = -1;
uint32_t old_mode;
- char *fname = NULL;
- NTSTATUS status;
/* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE);
else
dosmode &= ~aDIR;
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- old_mode = dos_mode(conn, fname, &smb_fname->st);
+ old_mode = dos_mode(conn, smb_fname);
if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) {
- lret = SMB_VFS_SET_OFFLINE(conn, fname);
+ lret = SMB_VFS_SET_OFFLINE(conn, smb_fname->base_name);
if (lret == -1) {
DEBUG(0, ("set_dos_mode: client has asked to "
"set FILE_ATTRIBUTE_OFFLINE to "
{
if (!newfile && attributes_changed) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ smb_fname->base_name);
}
smb_fname->st.st_ex_mode = unixmode;
return 0;
}
}
#endif
-
/* Store the DOS attributes in an EA by preference. */
- if (set_ea_dos_attribute(conn, fname, &smb_fname->st, dosmode)) {
+ if (set_ea_dos_attribute(conn, smb_fname, dosmode)) {
if (!newfile) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ smb_fname->base_name);
}
smb_fname->st.st_ex_mode = unixmode;
return 0;
}
- unixmode = unix_mode(conn,dosmode,fname, parent_dir);
+ unixmode = unix_mode(conn, dosmode, smb_fname, parent_dir);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
unixmode |= (smb_fname->st.st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
- ret = SMB_VFS_CHMOD(conn, fname, unixmode);
+ ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
if (ret == 0) {
if(!newfile || (lret != -1)) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ smb_fname->base_name);
}
smb_fname->st.st_ex_mode = unixmode;
return 0;
* break batch oplocks open by others. JRA.
*/
files_struct *fsp;
- if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname,
- &smb_fname->st, &fsp)))
+ if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, smb_fname,
+ &fsp)))
return -1;
become_root();
ret = SMB_VFS_FCHMOD(fsp, unixmode);
close_file_fchmod(NULL, fsp);
if (!newfile) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ FILE_NOTIFY_CHANGE_ATTRIBUTES,
+ smb_fname->base_name);
}
if (ret == 0) {
smb_fname->st.st_ex_mode = unixmode;
time_to_asc(convert_timespec_to_time_t(ft->atime))));
DEBUG(6, ("file_ntime: modtime: %s",
time_to_asc(convert_timespec_to_time_t(ft->mtime))));
+ DEBUG(6, ("file_ntime: ctime: %s",
+ time_to_asc(convert_timespec_to_time_t(ft->ctime))));
DEBUG(6, ("file_ntime: createtime: %s",
time_to_asc(convert_timespec_to_time_t(ft->create_time))));
}
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name);
+ FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
return true;
}