mode_t unix_mode(connection_struct *conn, int dosmode,
const struct smb_filename *smb_fname,
- const char *inherit_from_dir)
+ struct smb_filename *smb_fname_parent)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
mode_t dir_mode = 0; /* Mode of the inherit_from directory if
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
- if ((inherit_from_dir != NULL) && lp_inherit_permissions(SNUM(conn))) {
- struct smb_filename *smb_fname_parent;
-
- DEBUG(2, ("unix_mode(%s) inheriting from %s\n",
+ if ((smb_fname_parent != NULL) && lp_inherit_permissions(SNUM(conn))) {
+ DBG_DEBUG("[%s] inheriting from [%s]\n",
smb_fname_str_dbg(smb_fname),
- inherit_from_dir));
-
- smb_fname_parent = synthetic_smb_fname(talloc_tos(),
- inherit_from_dir,
- NULL,
- NULL,
- smb_fname->flags);
- if (smb_fname_parent == NULL) {
- DEBUG(1,("unix_mode(%s) failed, [dir %s]: No memory\n",
- smb_fname_str_dbg(smb_fname),
- inherit_from_dir));
- return(0);
- }
+ smb_fname_str_dbg(smb_fname_parent));
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)));
+ DBG_ERR("stat failed [%s]: %s\n",
+ smb_fname_str_dbg(smb_fname_parent),
+ strerror(errno));
TALLOC_FREE(smb_fname_parent);
return(0); /* *** shouldn't happen! *** */
}
}
} else if (ro_opts == MAP_READONLY_PERMISSIONS) {
/* Check actual permissions for read-only. */
- if (!can_write_to_file(conn, smb_fname)) {
+ if (!can_write_to_file(conn,
+ conn->cwd_fsp,
+ smb_fname))
+ {
result |= FILE_ATTRIBUTE_READONLY;
}
} /* Else never set the readonly bit. */
if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
!null_nttime(dosattrib.info.info3.create_time)) {
struct timespec create_time =
- nt_time_to_unix_timespec(
+ nt_time_to_full_timespec(
dosattrib.info.info3.create_time);
update_stat_ex_create_time(&smb_fname->st,
create_time)));
}
break;
+ case 4:
+ {
+ struct xattr_DosInfo4 *info = &dosattrib.info.info4;
+
+ dosattr = info->attrib;
+
+ if ((info->valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
+ !null_nttime(info->create_time))
+ {
+ struct timespec creat_time;
+
+ creat_time = nt_time_to_full_timespec(info->create_time);
+ update_stat_ex_create_time(&smb_fname->st, creat_time);
+
+ DBG_DEBUG("file [%s] creation time [%s]\n",
+ smb_fname_str_dbg(smb_fname),
+ nt_time_string(talloc_tos(), info->create_time));
+ }
+
+ if (info->valid_flags & XATTR_DOSINFO_ITIME) {
+ struct timespec itime;
+ uint64_t file_id;
+
+ itime = nt_time_to_unix_timespec(info->itime);
+ if (smb_fname->st.st_ex_iflags &
+ ST_EX_IFLAG_CALCULATED_ITIME)
+ {
+ update_stat_ex_itime(&smb_fname->st, itime);
+ }
+
+ file_id = make_file_id_from_itime(&smb_fname->st);
+ if (smb_fname->st.st_ex_iflags &
+ ST_EX_IFLAG_CALCULATED_FILE_ID)
+ {
+ update_stat_ex_file_id(&smb_fname->st, file_id);
+ }
+
+ DBG_DEBUG("file [%s] itime [%s] fileid [%"PRIx64"]\n",
+ smb_fname_str_dbg(smb_fname),
+ nt_time_string(talloc_tos(), info->itime),
+ file_id);
+ }
+ break;
+ }
default:
DBG_WARNING("Badly formed DOSATTRIB on file %s - %s\n",
smb_fname_str_dbg(smb_fname), blob.data);
ZERO_STRUCT(dosattrib);
ZERO_STRUCT(blob);
- dosattrib.version = 3;
- dosattrib.info.info3.valid_flags = XATTR_DOSINFO_ATTRIB|
+ dosattrib.version = 4;
+ dosattrib.info.info4.valid_flags = XATTR_DOSINFO_ATTRIB |
XATTR_DOSINFO_CREATE_TIME;
- dosattrib.info.info3.attrib = dosmode;
- dosattrib.info.info3.create_time = unix_timespec_to_nt_time(
- smb_fname->st.st_ex_btime);
+ dosattrib.info.info4.attrib = dosmode;
+ dosattrib.info.info4.create_time = full_timespec_to_nt_time(
+ &smb_fname->st.st_ex_btime);
+
+ if (!(smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) {
+ dosattrib.info.info4.valid_flags |= XATTR_DOSINFO_ITIME;
+ dosattrib.info.info4.itime = full_timespec_to_nt_time(
+ &smb_fname->st.st_ex_itime);
+ }
DEBUG(10,("set_ea_dos_attributes: set attribute 0x%x, btime = %s on file %s\n",
(unsigned int)dosmode,
return NT_STATUS_ACCESS_DENIED;
}
- status = smbd_check_access_rights(conn, smb_fname, false,
- FILE_WRITE_ATTRIBUTES);
+ status = smbd_check_access_rights(conn,
+ conn->cwd_fsp,
+ smb_fname,
+ false,
+ FILE_WRITE_ATTRIBUTES);
if (NT_STATUS_IS_OK(status)) {
set_dosmode_ok = true;
}
if (!set_dosmode_ok && lp_dos_filemode(SNUM(conn))) {
- set_dosmode_ok = can_write_to_file(conn, smb_fname);
+ set_dosmode_ok = can_write_to_file(conn,
+ conn->cwd_fsp,
+ smb_fname);
}
if (!set_dosmode_ok) {
* BUG: https://bugzilla.samba.org/show_bug.cgi?id=13380
*/
- if (is_ntfs_stream_smb_fname(smb_fname)) {
+ if (is_named_stream(smb_fname)) {
/* is_ntfs_stream_smb_fname() returns false for a POSIX path. */
- if (!is_ntfs_default_stream_smb_fname(smb_fname)) {
- /*
- * Non-default stream name, not a posix path.
- */
- dosmode &= ~(FILE_ATTRIBUTE_DIRECTORY);
- }
+ dosmode &= ~(FILE_ATTRIBUTE_DIRECTORY);
}
if (conn->fs_capabilities & FILE_FILE_COMPRESSION) {
struct smb_filename *smb_path = NULL;
struct vfs_aio_state aio_state;
NTSTATUS status;
+ bool ok;
+
+ /*
+ * Make sure we run as the user again
+ */
+ ok = change_to_user_and_service_by_fsp(state->dir_fsp);
+ SMB_ASSERT(ok);
status = SMB_VFS_GET_DOS_ATTRIBUTES_RECV(subreq,
&aio_state,
return;
}
- smb_path = synthetic_smb_fname(state, path, NULL, NULL, 0);
- if (tevent_req_nomem(path, req)) {
+ smb_path = synthetic_smb_fname(state,
+ path,
+ NULL,
+ &state->smb_fname->st,
+ state->smb_fname->twrp,
+ 0);
+ if (tevent_req_nomem(smb_path, req)) {
return;
}
attribute also.
********************************************************************/
-int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
- uint32_t dosmode, const char *parent_dir, bool newfile)
+int file_set_dosmode(connection_struct *conn,
+ struct smb_filename *smb_fname,
+ uint32_t dosmode,
+ struct smb_filename *parent_dir,
+ bool newfile)
{
int mask=0;
mode_t tmp;
bits on a file. Just like file_ntimes below.
*/
- if (!can_write_to_file(conn, smb_fname)) {
+ if (!can_write_to_file(conn,
+ conn->cwd_fsp,
+ smb_fname))
+ {
errno = EACCES;
return -1;
}
files_struct *fsp,
bool sparse)
{
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
uint32_t old_dosmode;
uint32_t new_dosmode;
NTSTATUS status;
"on readonly share[%s]\n",
smb_fname_str_dbg(fsp->fsp_name),
sparse,
- lp_servicename(talloc_tos(), SNUM(conn))));
+ lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
return NT_STATUS_ACCESS_DENIED;
}
- if (fsp->is_directory) {
+ if (fsp->fsp_flags.is_directory) {
DEBUG(9, ("invalid attempt to %s sparse flag on dir %s\n",
(sparse ? "set" : "clear"),
smb_fname_str_dbg(fsp->fsp_name)));
FILE_NOTIFY_CHANGE_ATTRIBUTES,
fsp->fsp_name->base_name);
- fsp->is_sparse = sparse;
+ fsp->fsp_flags.is_sparse = sparse;
return NT_STATUS_OK;
}
*/
/* Check if we have write access. */
- if (can_write_to_file(conn, smb_fname)) {
+ if (can_write_to_file(conn,
+ conn->cwd_fsp,
+ smb_fname))
+ {
/* We are allowed to become root and change the filetime. */
become_root();
ret = SMB_VFS_NTIMES(conn, smb_fname, ft);
bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime)
{
- if (null_timespec(mtime)) {
+ if (is_omit_timespec(&mtime)) {
return true;
}
bool set_sticky_write_time_fsp(struct files_struct *fsp, struct timespec mtime)
{
- if (null_timespec(mtime)) {
+ if (is_omit_timespec(&mtime)) {
return true;
}
- fsp->write_time_forced = true;
+ fsp->fsp_flags.write_time_forced = true;
TALLOC_FREE(fsp->update_write_time_event);
return set_sticky_write_time_path(fsp->file_id, mtime);
psmb_fname->base_name,
NULL,
&psmb_fname->st,
+ psmb_fname->twrp,
psmb_fname->flags);
if (smb_fname == NULL) {