files_struct *fsp,
const SMB_STRUCT_STAT *psbuf);
+/****************************************************************************
+ Check if an open file handle or pathname is a symlink.
+****************************************************************************/
+
+static NTSTATUS refuse_symlink(connection_struct *conn,
+ const files_struct *fsp,
+ const struct smb_filename *smb_fname)
+{
+ SMB_STRUCT_STAT sbuf;
+ const SMB_STRUCT_STAT *pst = NULL;
+
+ if (fsp) {
+ pst = &fsp->fsp_name->st;
+ } else {
+ int ret = vfs_stat_smb_basename(conn,
+ smb_fname,
+ &sbuf);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ pst = &sbuf;
+ }
+ if (S_ISLNK(pst->st_ex_mode)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return NT_STATUS_OK;
+}
+
NTSTATUS check_access_fsp(const struct files_struct *fsp,
uint32_t access_mask)
{
const struct smb_filename *smb_fname,
uint32_t access_mask)
{
+ NTSTATUS status;
+
if (fsp) {
- NTSTATUS status = check_access_fsp(fsp, access_mask);
- return status;
+ status = check_access_fsp(fsp, access_mask);
} else {
- NTSTATUS status = smbd_check_access_rights(conn,
- smb_fname,
- false,
- access_mask);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- return NT_STATUS_OK;
+ status = smbd_check_access_rights(conn, smb_fname,
+ false, access_mask);
}
+
+ return status;
}
/********************************************************************
return NT_STATUS_OK;
}
-NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
- files_struct *fsp, const char *fname,
- char ***pnames, size_t *pnum_names)
+NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ char ***pnames,
+ size_t *pnum_names)
{
/* Get a list of all xattrs. Max namesize is 64k. */
size_t ea_namelist_size = 1024;
char **names, **tmp;
size_t num_names;
ssize_t sizeret = -1;
+ NTSTATUS status;
+
+ if (pnames) {
+ *pnames = NULL;
+ }
+ *pnum_names = 0;
if (!lp_ea_support(SNUM(conn))) {
- if (pnames) {
- *pnames = NULL;
- }
- *pnum_names = 0;
+ return NT_STATUS_OK;
+ }
+
+ status = refuse_symlink(conn, fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * Just return no EA's on a symlink.
+ */
return NT_STATUS_OK;
}
sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
ea_namelist_size);
} else {
- sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
- ea_namelist_size);
+ sizeret = SMB_VFS_LISTXATTR(conn,
+ smb_fname->base_name,
+ ea_namelist,
+ ea_namelist_size);
}
if ((sizeret == -1) && (errno == ERANGE)) {
if (sizeret == 0) {
TALLOC_FREE(names);
- if (pnames) {
- *pnames = NULL;
- }
- *pnum_names = 0;
return NT_STATUS_OK;
}
Return a linked list of the total EA's. Plus the total size
****************************************************************************/
-static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
- const char *fname, size_t *pea_total_len, struct ea_list **ea_list)
+static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ size_t *pea_total_len,
+ struct ea_list **ea_list)
{
/* Get a list of all xattrs. Max namesize is 64k. */
size_t i, num_names;
char **names;
struct ea_list *ea_list_head = NULL;
+ bool posix_pathnames = false;
NTSTATUS status;
*pea_total_len = 0;
*ea_list = NULL;
- status = get_ea_names_from_file(talloc_tos(), conn, fsp, fname,
- &names, &num_names);
+ if (fsp) {
+ posix_pathnames =
+ (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
+ } else {
+ posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
+ }
+
+ status = get_ea_names_from_file(talloc_tos(),
+ conn,
+ fsp,
+ smb_fname,
+ &names,
+ &num_names);
if (!NT_STATUS_IS_OK(status)) {
return status;
* Filter out any underlying POSIX EA names
* that a Windows client can't handle.
*/
- if (!lp_posix_pathnames() &&
+ if (!posix_pathnames &&
is_invalid_windows_ea_name(names[i])) {
continue;
}
return NT_STATUS_NO_MEMORY;
}
- status = get_ea_value(listp, conn, fsp,
- fname, names[i],
- &listp->ea);
+ status = get_ea_value(listp,
+ conn,
+ fsp,
+ smb_fname->base_name,
+ names[i],
+ &listp->ea);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(listp);
"= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
(unsigned int)listp->ea.value.length));
- DLIST_ADD_END(ea_list_head, listp, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, listp);
}
return NT_STATUS_INVALID_PARAMETER;
}
- return get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, pea_total_len, ea_list);
+ return get_ea_list_from_file_path(mem_ctx,
+ conn,
+ fsp,
+ smb_fname,
+ pea_total_len,
+ ea_list);
}
/****************************************************************************
if (is_ntfs_stream_smb_fname(smb_fname)) {
fsp = NULL;
}
- (void)get_ea_list_from_file_path(mem_ctx, conn, fsp, smb_fname->base_name, &total_ea_len, &ea_list);
+ (void)get_ea_list_from_file_path(mem_ctx,
+ conn,
+ fsp,
+ smb_fname,
+ &total_ea_len,
+ &ea_list);
if(conn->sconn->using_smb2) {
NTSTATUS status;
unsigned int ret_data_size;
Ensure the EA name is case insensitive by matching any existing EA name.
****************************************************************************/
-static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, const char *fname, fstring unix_ea_name)
+static void canonicalize_ea_name(connection_struct *conn,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ fstring unix_ea_name)
{
size_t total_ea_len;
TALLOC_CTX *mem_ctx = talloc_tos();
struct ea_list *ea_list;
- NTSTATUS status = get_ea_list_from_file_path(mem_ctx, conn, fsp, fname, &total_ea_len, &ea_list);
+ NTSTATUS status = get_ea_list_from_file_path(mem_ctx,
+ conn,
+ fsp,
+ smb_fname,
+ &total_ea_len,
+ &ea_list);
if (!NT_STATUS_IS_OK(status)) {
return;
}
const struct smb_filename *smb_fname, struct ea_list *ea_list)
{
NTSTATUS status;
- char *fname = NULL;
+ bool posix_pathnames = false;
if (!lp_ea_support(SNUM(conn))) {
return NT_STATUS_EAS_NOT_SUPPORTED;
}
+ if (fsp) {
+ posix_pathnames =
+ (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
+ } else {
+ posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
+ }
+
+ status = refuse_symlink(conn, fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
if (!NT_STATUS_IS_OK(status)) {
return status;
* we set *any* of them.
*/
- if (ea_list_has_invalid_name(ea_list)) {
+ if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
return STATUS_INVALID_EA_NAME;
}
- fname = smb_fname->base_name;
-
for (;ea_list; ea_list = ea_list->next) {
int ret;
fstring unix_ea_name;
fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
fstrcat(unix_ea_name, ea_list->ea.name);
- canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
+ canonicalize_ea_name(conn,
+ fsp,
+ smb_fname,
+ unix_ea_name);
DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
} else {
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
+ unix_ea_name, smb_fname->base_name));
+ ret = SMB_VFS_REMOVEXATTR(conn,
+ smb_fname->base_name,
+ unix_ea_name);
}
#ifdef ENOATTR
/* Removing a non existent attribute always succeeds. */
ea_list->ea.value.data, ea_list->ea.value.length, 0);
} else {
DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
- ea_list->ea.value.data, ea_list->ea.value.length, 0);
+ unix_ea_name, smb_fname->base_name));
+ ret = SMB_VFS_SETXATTR(conn,
+ smb_fname->base_name,
+ unix_ea_name,
+ ea_list->ea.value.data,
+ ea_list->ea.value.length,
+ 0);
}
}
}
offset += (namelen + 1); /* Go past the name + terminating zero. */
- DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, eal);
DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
}
return NULL;
}
- DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
+ DLIST_ADD_END(ea_list_head, eal);
offset += bytes_used;
}
uint32_t create_disposition;
uint32_t create_options = 0;
uint32_t private_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
/*
goto out;
}
- srvstr_get_path(ctx, params, req->flags2, &fname, pname,
- total_params - 28, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ params,
+ req->flags2,
+ &fname,
+ pname,
+ total_params - 28,
+ STR_TERMINATE,
&status);
+ } else {
+ srvstr_get_path(ctx,
+ params,
+ req->flags2,
+ &fname,
+ pname,
+ total_params - 28,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
goto out;
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- 0,
+ ucf_flags,
NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- if (ea_list_has_invalid_name(ea_list)) {
+ if (!req->posix_pathnames &&
+ ea_list_has_invalid_name(ea_list)) {
int param_len = 30;
*pparams = (char *)SMB_REALLOC(*pparams, param_len);
if(*pparams == NULL ) {
struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
- TALLOC_CTX *ctx = talloc_tos();
struct dptr_struct *dirptr = NULL;
struct smbd_server_connection *sconn = req->sconn;
- uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP);
+ uint32_t ucf_flags = UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
bool backup_priv = false;
bool as_root = false;
goto out;
}
- srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
- params+12, total_params - 12,
- STR_TERMINATE, &ntstatus, &mask_contains_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(talloc_tos(),
+ params,
+ req->flags2,
+ &directory,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ } else {
+ srvstr_get_path_wcard(talloc_tos(),
+ params,
+ req->flags2,
+ &directory,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ }
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
goto out;
if (backup_priv) {
become_root();
as_root = true;
- ntstatus = filename_convert_with_privilege(ctx,
+ ntstatus = filename_convert_with_privilege(talloc_tos(),
conn,
req,
directory,
&mask_contains_wcard,
&smb_dname);
} else {
- ntstatus = filename_convert(ctx, conn,
+ ntstatus = filename_convert(talloc_tos(), conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
ucf_flags,
if(p == NULL) {
/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
if((directory[0] == '.') && (directory[1] == '\0')) {
- mask = talloc_strdup(ctx,"*");
+ mask = talloc_strdup(talloc_tos(),"*");
if (!mask) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
reply_nterror(req, NT_STATUS_NO_MEMORY);
goto out;
}
+ /* Ensure smb_dname->base_name matches. */
+ smb_dname->base_name = directory;
}
DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
}
/* Pull out the list of names. */
- ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
+ ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
if (!ea_list) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
goto out;
ntstatus = dptr_create(conn,
req,
NULL, /* fsp */
- directory,
+ smb_dname,
False,
True,
req->smbpid,
a different TRANS2 call. */
DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- directory,lp_dont_descend(ctx, SNUM(conn))));
- if (in_list(directory,lp_dont_descend(ctx, SNUM(conn)),conn->case_sensitive))
+ directory,lp_dont_descend(talloc_tos(), SNUM(conn))));
+ if (in_list(directory,
+ lp_dont_descend(talloc_tos(), SNUM(conn)),
+ conn->case_sensitive)) {
dont_descend = True;
+ }
p = pdata;
space_remaining = max_data_bytes;
out_of_space = True;
finished = False;
} else {
- ntstatus = get_lanman2_dir_entry(ctx,
+ ntstatus = get_lanman2_dir_entry(talloc_tos(),
conn,
dirptr,
req->flags2,
if (!continue_bit) {
/* We only need resume_name if continue_bit is zero. */
- srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
- params+12,
- total_params - 12, STR_TERMINATE, &ntstatus,
- &mask_contains_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(ctx,
+ params,
+ req->flags2,
+ &resume_name,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ } else {
+ srvstr_get_path_wcard(ctx,
+ params,
+ req->flags2,
+ &resume_name,
+ params+12,
+ total_params - 12,
+ STR_TERMINATE,
+ &ntstatus,
+ &mask_contains_wcard);
+ }
if (!NT_STATUS_IS_OK(ntstatus)) {
/* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
complain (it thinks we're asking for the directory above the shared
return NT_STATUS_ACCESS_DENIED;
}
- if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) {
+ status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
+ NULL, "as);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
- return map_nt_error_from_unix(errno);
+ return status;
}
data_len = 48;
return NT_STATUS_INVALID_PARAMETER;
}
- status = vfs_streaminfo(conn, fsp, smb_fname->base_name,
- talloc_tos(), &num_streams, &streams);
+ status = vfs_streaminfo(conn,
+ fsp,
+ smb_fname,
+ talloc_tos(),
+ &num_streams,
+ &streams);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not get stream info: %s\n",
uint16_t num_file_acls = 0;
uint16_t num_def_acls = 0;
+ status = refuse_symlink(conn,
+ fsp,
+ smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
if (fsp && fsp->fh->fd != -1) {
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
talloc_tos());
} else {
uint32_t name_hash;
char *fname = NULL;
- uint32_t ucf_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ?
+ UCF_POSIX_PATHNAMES : 0);
/* qpathinfo */
if (total_params < 7) {
}
}
- srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
total_params - 6,
- STR_TERMINATE, &status);
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
/* Create an smb_filename with stream_name == NULL. */
smb_fname_base = synthetic_smb_fname(
- talloc_tos(), smb_fname->base_name,
- NULL, NULL);
+ talloc_tos(),
+ smb_fname->base_name,
+ NULL,
+ NULL,
+ smb_fname->flags);
if (smb_fname_base == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
/* Always operate on the base_name, even if a stream was passed in. */
- smb_fname_base = synthetic_smb_fname(
- talloc_tos(), smb_fname->base_name, NULL, &smb_fname->st);
+ smb_fname_base = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ NULL,
+ &smb_fname->st,
+ smb_fname->flags);
if (smb_fname_base == NULL) {
return NT_STATUS_NO_MEMORY;
}
{
char *oldname = NULL;
struct smb_filename *smb_fname_old = NULL;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status = NT_STATUS_OK;
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &oldname, pdata,
- total_data, STR_TERMINATE, &status);
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &oldname,
+ pdata,
+ total_data,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &oldname,
+ pdata,
+ total_data,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname,
- 0,
+ ucf_flags,
NULL,
&smb_fname_old);
if (!NT_STATUS_IS_OK(status)) {
uint32_t len;
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
+ uint32_t ucf_flags = UCF_SAVE_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &newname,
- &pdata[20], len, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
&status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
- UCF_SAVE_LCOMP,
+ ucf_flags,
NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
}
/* Create an smb_fname to call rename_internals_fsp() with. */
- smb_fname_dst = synthetic_smb_fname(
- talloc_tos(), fsp->base_fsp->fsp_name->base_name,
- newname, NULL);
+ smb_fname_dst = synthetic_smb_fname(talloc_tos(),
+ fsp->base_fsp->fsp_name->base_name,
+ newname,
+ NULL,
+ fsp->base_fsp->fsp_name->flags);
if (smb_fname_dst == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
char *newname = NULL;
struct smb_filename *smb_fname_dst = NULL;
NTSTATUS status = NT_STATUS_OK;
+ uint32_t ucf_flags = UCF_SAVE_LCOMP |
+ (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
if (!fsp) {
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path(ctx, pdata, req->flags2, &newname,
- &pdata[20], len, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
&status);
+ } else {
+ srvstr_get_path(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[20],
+ len,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
- UCF_SAVE_LCOMP,
+ ucf_flags,
NULL,
&smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
return NT_STATUS_INVALID_PARAMETER;
}
- srvstr_get_path_wcard(ctx, pdata, req->flags2, &newname, &pdata[12],
- len, 0, &status,
- &dest_has_wcard);
+ if (req->posix_pathnames) {
+ srvstr_get_path_wcard_posix(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[12],
+ len,
+ 0,
+ &status,
+ &dest_has_wcard);
+ } else {
+ srvstr_get_path_wcard(ctx,
+ pdata,
+ req->flags2,
+ &newname,
+ &pdata[12],
+ len,
+ 0,
+ &status,
+ &dest_has_wcard);
+ }
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
newname,
- true,
+ UCF_COND_ALLOW_WCARD_LCOMP,
!conn->sconn->using_smb2,
&newname,
&dest_has_wcard);
}
/* Create an smb_fname to call rename_internals_fsp() with. */
- smb_fname_dst = synthetic_smb_fname(
- talloc_tos(), fsp->base_fsp->fsp_name->base_name,
- newname, NULL);
+ smb_fname_dst = synthetic_smb_fname(talloc_tos(),
+ fsp->base_fsp->fsp_name->base_name,
+ newname,
+ NULL,
+ fsp->base_fsp->fsp_name->flags);
if (smb_fname_dst == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
goto out;
}
/* Create an smb_fname to call rename_internals_fsp() */
- smb_fname_dst = synthetic_smb_fname(
- ctx, base_name, NULL, NULL);
+ smb_fname_dst = synthetic_smb_fname(ctx,
+ base_name,
+ NULL,
+ NULL,
+ smb_fname_src->flags);
if (smb_fname_dst == NULL) {
status = NT_STATUS_NO_MEMORY;
goto out;
uint16_t num_def_acls;
bool valid_file_acls = True;
bool valid_def_acls = True;
+ NTSTATUS status;
if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
return NT_STATUS_INVALID_PARAMETER;
return NT_STATUS_INVALID_PARAMETER;
}
+ status = refuse_symlink(conn, fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
(unsigned int)num_file_acls,
if (fsp && fsp->fh->fd != -1) {
ret = SMB_VFS_FCHMOD(fsp, unixmode);
} else {
- ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
+ ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
}
if (ret != 0) {
return map_nt_error_from_unix(errno);
* UNIX extensions calls must always operate
* on symlinks.
*/
- ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
+ ret = SMB_VFS_LCHOWN(conn, smb_fname,
set_owner, (gid_t)-1);
}
* UNIX extensions calls must always operate
* on symlinks.
*/
- ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, (uid_t)-1,
+ ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
set_grp);
}
if (ret != 0) {
}
} else {
char *fname = NULL;
- uint32_t ucf_flags = 0;
+ uint32_t ucf_flags = (req->posix_pathnames ?
+ UCF_POSIX_PATHNAMES : 0);
/* set path info */
if (total_params < 7) {
}
info_level = SVAL(params,0);
- srvstr_get_path(req, params, req->flags2, &fname, ¶ms[6],
- total_params - 6, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
&status);
+ } else {
+ srvstr_get_path(req,
+ params,
+ req->flags2,
+ &fname,
+ ¶ms[6],
+ total_params - 6,
+ STR_TERMINATE,
+ &status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
char *directory = NULL;
NTSTATUS status = NT_STATUS_OK;
struct ea_list *ea_list = NULL;
+ uint32_t ucf_flags = (req->posix_pathnames ? UCF_POSIX_PATHNAMES : 0);
TALLOC_CTX *ctx = talloc_tos();
if (!CAN_WRITE(conn)) {
return;
}
- srvstr_get_path(ctx, params, req->flags2, &directory, ¶ms[4],
- total_params - 4, STR_TERMINATE,
+ if (req->posix_pathnames) {
+ srvstr_get_path_posix(ctx,
+ params,
+ req->flags2,
+ &directory,
+ ¶ms[4],
+ total_params - 4,
+ STR_TERMINATE,
+ &status);
+ } else {
+ srvstr_get_path(ctx,
+ params,
+ req->flags2,
+ &directory,
+ ¶ms[4],
+ total_params - 4,
+ STR_TERMINATE,
&status);
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- 0,
+ ucf_flags,
NULL,
&smb_dname);