bool can_access_file_data(connection_struct *conn,
const struct smb_filename *smb_fname,
uint32 access_mask);
-bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf);
+bool can_write_to_file(connection_struct *conn,
+ const struct smb_filename *smb_fname);
bool directory_has_default_acl(connection_struct *conn, const char *fname);
/* The following definitions come from smbd/fileio.c */
use it for anything security sensitive.
********************************************************************/
-static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
+static bool user_can_write_file(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
/*
* If user is a member of the Admin group
return True;
}
- SMB_ASSERT(VALID_STAT(*pst));
+ SMB_ASSERT(VALID_STAT(smb_fname->st));
/* Pseudo-open the file */
- if(S_ISDIR(pst->st_ex_mode)) {
+ if(S_ISDIR(smb_fname->st.st_ex_mode)) {
return True;
}
- return can_write_to_file(conn, name, pst);
+ return can_write_to_file(conn, smb_fname);
}
/*******************************************************************
Is a file a "special" type ?
********************************************************************/
-static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
+static bool file_is_special(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
/*
* If user is a member of the Admin group
if (conn->admin_user)
return False;
- SMB_ASSERT(VALID_STAT(*pst));
+ SMB_ASSERT(VALID_STAT(smb_fname->st));
- if (S_ISREG(pst->st_ex_mode) || S_ISDIR(pst->st_ex_mode) || S_ISLNK(pst->st_ex_mode))
+ if (S_ISREG(smb_fname->st.st_ex_mode) ||
+ S_ISDIR(smb_fname->st.st_ex_mode) ||
+ S_ISLNK(smb_fname->st.st_ex_mode))
return False;
return True;
/* Create an smb_filename with stream_name == NULL. */
status = create_synthetic_smb_fname(talloc_tos(), entry, NULL,
- NULL, &smb_fname_base);
+ pst, &smb_fname_base);
if (!NT_STATUS_IS_OK(status)) {
ret = false;
goto out;
* the configuration options. We succeed, on the basis that the
* checks *might* have passed if the file was present.
*/
- if (!VALID_STAT(*pst) &&
- (SMB_VFS_STAT(conn, smb_fname_base) != 0))
- {
- ret = true;
- goto out;
+ if (!VALID_STAT(*pst)) {
+ if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
+ ret = true;
+ goto out;
+ } else {
+ *pst = smb_fname_base->st;
+ }
}
- *pst = smb_fname_base->st;
-
/* Honour _hide unreadable_ option */
if (hide_unreadable &&
!user_can_read_file(conn, smb_fname_base)) {
goto out;
}
/* Honour _hide unwriteable_ option */
- if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) {
+ if (hide_unwriteable && !user_can_write_file(conn,
+ smb_fname_base)) {
DEBUG(10,("is_visible_file: file %s is unwritable.\n",
entry ));
ret = false;
goto out;
}
/* Honour _hide_special_ option */
- if (hide_special && file_is_special(conn, entry, pst)) {
+ if (hide_special && file_is_special(conn, smb_fname_base)) {
DEBUG(10,("is_visible_file: file %s is special.\n",
entry ));
ret = false;
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;
+ 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;
+ }
}
+ TALLOC_FREE(smb_fname);
} /* Else never set the readonly bit. */
if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0))
int file_ntimes(connection_struct *conn, const char *fname,
struct smb_file_time *ft)
{
- SMB_STRUCT_STAT sbuf;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
int ret = -1;
errno = 0;
- ZERO_STRUCT(sbuf);
DEBUG(6, ("file_ntime: actime: %s",
time_to_asc(convert_timespec_to_time_t(ft->atime))));
(as DOS does).
*/
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+ &smb_fname);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return -1;
+ }
+
/* Check if we have write access. */
- if (can_write_to_file(conn, fname, &sbuf)) {
+ if (can_write_to_file(conn, smb_fname)) {
/* We are allowed to become root and change the filetime. */
become_root();
ret = SMB_VFS_NTIMES(conn, fname, ft);
unbecome_root();
}
+ TALLOC_FREE(smb_fname);
return ret;
}
Note this doesn't take into account share write permissions.
****************************************************************************/
-bool can_write_to_file(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf)
+bool can_write_to_file(connection_struct *conn,
+ const struct smb_filename *smb_fname)
{
- struct smb_filename *smb_fname;
- NTSTATUS status;
- bool ret;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
-
- ret = can_access_file_data(conn, smb_fname, FILE_WRITE_DATA);
-
- TALLOC_FREE(smb_fname);
-
- return ret;
+ return can_access_file_data(conn, smb_fname, FILE_WRITE_DATA);
}
/****************************************************************************
uint32 perms = 0;
p += 25;
if (fsp->is_directory ||
- can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
+ can_write_to_file(conn, smb_fname)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
uint32 perms = 0;
p += 25;
if (fsp->is_directory ||
- can_write_to_file(conn, fsp->fsp_name, &smb_fname->st)) {
+ can_write_to_file(conn, smb_fname)) {
perms = FILE_GENERIC_ALL;
} else {
perms = FILE_GENERIC_READ|FILE_EXECUTE;
const SMB_STRUCT_STAT *psbuf,
const char *fname)
{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+
if ((errno != EPERM) && (errno != EACCES)) {
return false;
}
return true;
}
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
+ &smb_fname);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
/* user has writeable permission */
if (lp_dos_filemode(SNUM(conn)) &&
- can_write_to_file(conn, fname, psbuf)) {
+ can_write_to_file(conn, smb_fname)) {
+ TALLOC_FREE(smb_fname);
return true;
}
+ TALLOC_FREE(smb_fname);
return false;
}